Skip to content

Update Spec: feat(seo): enhance og:image with branding and spec overview collage #1456

Update Spec: feat(seo): enhance og:image with branding and spec overview collage

Update Spec: feat(seo): enhance og:image with branding and spec overview collage #1456

Workflow file for this run

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 }}