Update Spec: feat(seo): enhance og:image with branding and spec overview collage #1456
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: "Spec: Update" | |
| run-name: "Update Spec: ${{ github.event.issue.title }}" | |
| # Updates existing specification | |
| # Flow: | |
| # 1. User adds `spec-update` label → analyzes and creates PR with updates | |
| # 2. Maintainer adds `approved` label → merges PR to main | |
| # | |
| # Issue title format: [specification-id] Update: description | |
| on: | |
| issues: | |
| types: [labeled] | |
| concurrency: | |
| group: spec-update-${{ github.event.issue.number }} | |
| cancel-in-progress: false | |
| jobs: | |
| # ============================================================================ | |
| # Job 1: Analyze and update specification | |
| # ============================================================================ | |
| update: | |
| if: github.event.label.name == 'spec-update' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| issues: write | |
| id-token: write | |
| steps: | |
| - name: Extract specification ID | |
| id: extract | |
| env: | |
| ISSUE_TITLE: ${{ github.event.issue.title }} | |
| run: | | |
| # Title format: [specification-id] ... | |
| SPEC_ID=$(echo "$ISSUE_TITLE" | sed -n 's/^\[\([a-z0-9-]*\)\].*/\1/p') | |
| if [[ -z "$SPEC_ID" ]]; then | |
| echo "::error::Could not extract specification ID from title. Expected format: [specification-id] ..." | |
| exit 1 | |
| fi | |
| echo "specification_id=$SPEC_ID" >> $GITHUB_OUTPUT | |
| - name: Checkout repository | |
| uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| - name: Verify specification exists | |
| id: verify | |
| env: | |
| SPEC_ID: ${{ steps.extract.outputs.specification_id }} | |
| run: | | |
| if [[ ! -f "plots/${SPEC_ID}/specification.md" ]]; then | |
| echo "::error::Specification not found: plots/${SPEC_ID}/specification.md" | |
| exit 1 | |
| fi | |
| echo "exists=true" >> $GITHUB_OUTPUT | |
| - name: React with eyes emoji | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| gh api repos/${{ github.repository }}/issues/${{ github.event.issue.number }}/reactions \ | |
| -f content=eyes | |
| - name: Process update with Claude | |
| id: process | |
| continue-on-error: true | |
| timeout-minutes: 30 | |
| uses: anthropics/claude-code-action@v1 | |
| with: | |
| claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} | |
| claude_args: "--model opus" | |
| prompt: | | |
| ## Task: Update Existing Specification | |
| You are updating an existing plot specification. | |
| ### Issue Details | |
| - **Title:** ${{ github.event.issue.title }} | |
| - **Number:** #${{ github.event.issue.number }} | |
| - **Specification ID:** ${{ steps.extract.outputs.specification_id }} | |
| - **Body:** | |
| ``` | |
| ${{ github.event.issue.body }} | |
| ``` | |
| --- | |
| ## Instructions | |
| 1. **Read current specification:** | |
| - `plots/${{ steps.extract.outputs.specification_id }}/specification.md` | |
| - `plots/${{ steps.extract.outputs.specification_id }}/specification.yaml` | |
| 2. **Post analysis comment:** | |
| Post a SHORT comment (max 3-4 sentences) to the issue using `gh issue comment`: | |
| - Is this a valid/useful change? | |
| - What will be modified? | |
| - Any concerns? | |
| 3. **Create update branch:** | |
| ```bash | |
| git checkout -b "specification/${{ steps.extract.outputs.specification_id }}-update" | |
| ``` | |
| 4. **Apply updates:** | |
| - Modify `plots/${{ steps.extract.outputs.specification_id }}/specification.md` as needed | |
| - Update `plots/${{ steps.extract.outputs.specification_id }}/specification.yaml`: | |
| - Set `updated`: current timestamp (ISO 8601 format, e.g., 2025-12-21T10:30:00Z) | |
| 5. **Commit and push:** | |
| ```bash | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| git add plots/${{ steps.extract.outputs.specification_id }}/ | |
| git commit -m "spec: update ${{ steps.extract.outputs.specification_id }} | |
| Updated from issue #${{ github.event.issue.number }}" | |
| git push -u origin "specification/${{ steps.extract.outputs.specification_id }}-update" | |
| ``` | |
| --- | |
| ## Important Rules | |
| - Do NOT create a PR (the workflow does that) | |
| - Do NOT add labels | |
| - STOP after pushing the branch | |
| - name: Retry Claude (on failure) | |
| if: steps.process.outcome == 'failure' | |
| id: process_retry | |
| timeout-minutes: 30 | |
| uses: anthropics/claude-code-action@v1 | |
| with: | |
| claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} | |
| claude_args: "--model opus" | |
| prompt: | | |
| ## Task: Update Existing Specification | |
| You are updating an existing plot specification. | |
| ### Issue Details | |
| - **Title:** ${{ github.event.issue.title }} | |
| - **Number:** #${{ github.event.issue.number }} | |
| - **Specification ID:** ${{ steps.extract.outputs.specification_id }} | |
| - **Body:** | |
| ``` | |
| ${{ github.event.issue.body }} | |
| ``` | |
| --- | |
| ## Instructions | |
| 1. **Read current specification:** | |
| - `plots/${{ steps.extract.outputs.specification_id }}/specification.md` | |
| - `plots/${{ steps.extract.outputs.specification_id }}/specification.yaml` | |
| 2. **Post analysis comment:** | |
| Post a SHORT comment (max 3-4 sentences) to the issue using `gh issue comment`: | |
| - Is this a valid/useful change? | |
| - What will be modified? | |
| - Any concerns? | |
| 3. **Create update branch:** | |
| ```bash | |
| git checkout -b "specification/${{ steps.extract.outputs.specification_id }}-update" | |
| ``` | |
| 4. **Apply updates:** | |
| - Modify `plots/${{ steps.extract.outputs.specification_id }}/specification.md` as needed | |
| - Update `plots/${{ steps.extract.outputs.specification_id }}/specification.yaml`: | |
| - Set `updated`: current timestamp (ISO 8601 format, e.g., 2025-12-21T10:30:00Z) | |
| 5. **Commit and push:** | |
| ```bash | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| git add plots/${{ steps.extract.outputs.specification_id }}/ | |
| git commit -m "spec: update ${{ steps.extract.outputs.specification_id }} | |
| Updated from issue #${{ github.event.issue.number }}" | |
| git push -u origin "specification/${{ steps.extract.outputs.specification_id }}-update" | |
| ``` | |
| --- | |
| ## Important Rules | |
| - Do NOT create a PR (the workflow does that) | |
| - Do NOT add labels | |
| - STOP after pushing the branch | |
| - name: Create Pull Request | |
| id: pr | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| SPEC_ID: ${{ steps.extract.outputs.specification_id }} | |
| run: | | |
| SPEC_CONTENT=$(cat "plots/${SPEC_ID}/specification.md") | |
| PR_URL=$(gh pr create \ | |
| --base main \ | |
| --head "specification/${SPEC_ID}-update" \ | |
| --title "spec: update ${SPEC_ID}" \ | |
| --body "$(cat <<EOF | |
| ## Update Specification: \`${SPEC_ID}\` | |
| Closes #${{ github.event.issue.number }} | |
| --- | |
| ### Updated specification.md | |
| ${SPEC_CONTENT} | |
| --- | |
| **Next:** Add \`approved\` label to the issue to merge this update. | |
| --- | |
| :robot: *[spec-update workflow](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})* | |
| EOF | |
| )") | |
| PR_NUMBER=$(echo "$PR_URL" | grep -oE '[0-9]+$') | |
| echo "pr_number=$PR_NUMBER" >> $GITHUB_OUTPUT | |
| - name: Comment on issue | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| SPEC_ID: ${{ steps.extract.outputs.specification_id }} | |
| PR_NUMBER: ${{ steps.pr.outputs.pr_number }} | |
| run: | | |
| SPEC_CONTENT=$(cat "plots/${SPEC_ID}/specification.md") | |
| gh issue comment ${{ github.event.issue.number }} --body "$(cat <<EOF | |
| ## :pencil2: Specification Update Ready | |
| **Specification:** \`${SPEC_ID}\` | |
| **PR:** #${PR_NUMBER} | |
| --- | |
| ### Updated specification.md | |
| ${SPEC_CONTENT} | |
| --- | |
| **Next:** Add \`approved\` label to merge this update. | |
| --- | |
| :robot: *[spec-update workflow](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})* | |
| EOF | |
| )" | |
| - name: Add rocket reaction on success | |
| if: success() | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| gh api repos/${{ github.repository }}/issues/${{ github.event.issue.number }}/reactions \ | |
| -f content=rocket | |
| # ============================================================================ | |
| # Job 2: Merge update (triggered by approved label) | |
| # ============================================================================ | |
| merge: | |
| if: > | |
| github.event.label.name == 'approved' && | |
| contains(github.event.issue.labels.*.name, 'spec-update') | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| issues: write | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v6 | |
| - name: Extract specification ID | |
| id: extract | |
| env: | |
| ISSUE_TITLE: ${{ github.event.issue.title }} | |
| run: | | |
| SPEC_ID=$(echo "$ISSUE_TITLE" | sed -n 's/^\[\([a-z0-9-]*\)\].*/\1/p') | |
| if [[ -z "$SPEC_ID" ]]; then | |
| echo "::error::Could not extract specification ID" | |
| exit 1 | |
| fi | |
| echo "specification_id=$SPEC_ID" >> $GITHUB_OUTPUT | |
| - name: Find and merge PR | |
| id: merge | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| SPEC_ID: ${{ steps.extract.outputs.specification_id }} | |
| run: | | |
| # Find PR for this update | |
| PR_NUMBER=$(gh pr list --head "specification/${SPEC_ID}-update" --json number -q '.[0].number') | |
| if [[ -z "$PR_NUMBER" ]]; then | |
| echo "::error::No PR found for update branch" | |
| exit 1 | |
| fi | |
| # Merge the PR | |
| gh pr merge "$PR_NUMBER" --squash --delete-branch | |
| echo "pr_number=$PR_NUMBER" >> $GITHUB_OUTPUT | |
| echo "::notice::Merged update PR #$PR_NUMBER" | |
| - name: Comment and close issue | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| SPEC_ID: ${{ steps.extract.outputs.specification_id }} | |
| PR_NUMBER: ${{ steps.merge.outputs.pr_number }} | |
| run: | | |
| gh issue comment ${{ github.event.issue.number }} --body "$(cat <<EOF | |
| ## :white_check_mark: Specification Updated! | |
| **Specification:** \`${SPEC_ID}\` | |
| **PR:** #${PR_NUMBER} (merged) | |
| The specification has been updated in \`main\`. | |
| --- | |
| :robot: *[spec-update workflow](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})* | |
| EOF | |
| )" | |
| # Close the issue | |
| gh issue close ${{ github.event.issue.number }} |