Some checks failed
Deploy analytics worker / Deploy analytics worker to ${{ (github.ref == 'refs/heads/production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} (push) Failing after 1s
i18n upload strings / Upload latest strings (push) Failing after 1s
Deploy bemo / Deploy bemo to ${{ (github.ref == 'refs/heads/bemo-production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} (push) Failing after 1s
Deploy grafana resources / ${{ github.event_name == 'push' && 'Deploy grafana resources' || 'Validate grafana resources (dry run)' }} (push) Failing after 0s
End to end tests (dotcom) / Check for relevant changes (push) Failing after 0s
End to end tests (examples) / Check for relevant changes (push) Failing after 0s
End to end tests (mermaid readability) / Check for relevant changes (push) Failing after 1s
End to end tests (perf) / Check for relevant changes (push) Failing after 0s
Publish editor extensions / Publish editor extensions (push) Failing after 1s
Publish SDK packages / Remove the publish-packages label (push) Has been skipped
Checks / Tests & checks (push) Has been cancelled
Checks / Build all projects (push) Has been cancelled
Deploy templates / Deploy templates (push) Has been cancelled
End to end tests (dotcom) / End to end tests (dotcom) (push) Has been cancelled
End to end tests (mermaid readability) / End to end tests (mermaid readability) (push) Has been cancelled
End to end tests (perf) / End to end tests (perf) (push) Has been cancelled
Deploy .com / Deploy dotcom to ${{ (github.ref == 'refs/heads/production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} (push) Has been cancelled
End to end tests (examples) / End to end tests (examples) (push) Has been cancelled
Publish SDK packages / Publish SDK packages (push) Has been cancelled
Publish SDK packages / Tell user released version (push) Has been cancelled
Publish SDK packages / Publishes code templates to separate repositories (push) Has been cancelled
Publish SDK packages / Deploys the template demos with the new SDK version (push) Has been cancelled
161 lines
5.8 KiB
YAML
161 lines
5.8 KiB
YAML
name: Update release notes
|
|
|
|
on:
|
|
# Update release notes whenever production is updated, keeping next.mdx (and the
|
|
# draft GitHub release synced by the skill) in step with each dotcom release —
|
|
# the same production push that deploys dotcom and publishes the `next` package.
|
|
# Production only: a push to main must not trigger a notes run on every merge.
|
|
# Release-notes PR titles carry `[skip ci]` so their squash-merge commits skip main
|
|
# push workflows. Branch commits omit the marker so required PR checks run.
|
|
push:
|
|
branches:
|
|
- production
|
|
workflow_dispatch:
|
|
|
|
concurrency:
|
|
group: update-release-notes
|
|
|
|
defaults:
|
|
run:
|
|
shell: bash
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
jobs:
|
|
update-release-notes:
|
|
name: 'Update release notes with Claude Code'
|
|
timeout-minutes: 30
|
|
runs-on: ubuntu-latest
|
|
|
|
steps:
|
|
- name: Generate GH token
|
|
id: generate_token
|
|
uses: tibdex/github-app-token@b62528385c34dbc9f38e5f4225ac829252d1ea92
|
|
with:
|
|
app_id: ${{ secrets.HUPPY_APP_ID }}
|
|
private_key: ${{ secrets.HUPPY_PRIVATE_KEY }}
|
|
|
|
- name: Check out code
|
|
uses: actions/checkout@v6
|
|
with:
|
|
persist-credentials: false
|
|
fetch-depth: 0
|
|
token: ${{ steps.generate_token.outputs.token }}
|
|
|
|
- name: Configure git credentials
|
|
run: git config --global url."https://x-access-token:${{ steps.generate_token.outputs.token }}@github.com/".insteadOf "https://github.com/"
|
|
|
|
- name: Run our setup
|
|
uses: ./.github/actions/setup
|
|
|
|
- name: Configure git
|
|
run: |
|
|
git config --global user.name 'huppy-bot[bot]'
|
|
git config --global user.email '128400622+huppy-bot[bot]@users.noreply.github.com'
|
|
|
|
- name: Create branch
|
|
id: branch
|
|
run: |
|
|
BRANCH_NAME="release-notes/update-$(date +%Y%m%d-%H%M%S)"
|
|
git checkout -b "$BRANCH_NAME"
|
|
echo "branch_name=$BRANCH_NAME" >> "$GITHUB_OUTPUT"
|
|
|
|
# Recorded before the skill runs so the close step below can tell an
|
|
# already-open PR from an earlier run apart from the one this run opens.
|
|
- name: Find open release notes PRs
|
|
id: existing_prs
|
|
run: |
|
|
{
|
|
echo 'numbers<<PR_LIST_EOF'
|
|
gh pr list --state open --base main --limit 100 --json number,headRefName \
|
|
--jq '.[] | select(.headRefName | test("^(release-notes/update-|update-release-notes-)")) | .number'
|
|
echo 'PR_LIST_EOF'
|
|
} >> "$GITHUB_OUTPUT"
|
|
env:
|
|
GH_TOKEN: ${{ steps.generate_token.outputs.token }}
|
|
|
|
- name: Install Claude Code
|
|
run: npm install -g @anthropic-ai/claude-code
|
|
|
|
- name: Run update-release-notes skill
|
|
run: |
|
|
claude --dangerously-skip-permissions --print "/update-release-notes"
|
|
env:
|
|
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
|
|
GH_TOKEN: ${{ steps.generate_token.outputs.token }}
|
|
|
|
- name: Check for changes
|
|
id: changes
|
|
run: |
|
|
if [ -z "$(git status --porcelain)" ]; then
|
|
echo "has_changes=false" >> "$GITHUB_OUTPUT"
|
|
else
|
|
echo "has_changes=true" >> "$GITHUB_OUTPUT"
|
|
fi
|
|
|
|
- name: Commit and push
|
|
if: steps.changes.outputs.has_changes == 'true'
|
|
run: |
|
|
git add -A
|
|
git commit -m "Update release notes"
|
|
git push -u origin "${{ steps.branch.outputs.branch_name }}"
|
|
|
|
- name: Create PR
|
|
if: steps.changes.outputs.has_changes == 'true'
|
|
run: |
|
|
gh pr create \
|
|
--title "docs(releases): update release notes [skip ci]" \
|
|
--body "$(cat <<'EOF'
|
|
In order to keep the release notes up to date, this PR adds entries for PRs merged since the last update.
|
|
|
|
### Change type
|
|
|
|
- [x] `other`
|
|
|
|
### Test plan
|
|
|
|
- [ ] Unit tests
|
|
- [ ] End to end tests
|
|
EOF
|
|
)" \
|
|
--base main \
|
|
--head "${{ steps.branch.outputs.branch_name }}" \
|
|
--label "docs-hotfix-please"
|
|
env:
|
|
GH_TOKEN: ${{ steps.generate_token.outputs.token }}
|
|
|
|
# Each run regenerates the notes from scratch, so a PR opened by this run
|
|
# supersedes any release notes PR left open by an earlier run. The PR may come
|
|
# from the step above or from the skill itself, so this compares the currently
|
|
# open PRs against the ones recorded before the skill ran rather than relying on
|
|
# a single known PR number. When this run opened nothing, the older PR is still
|
|
# the pending update and is left alone.
|
|
- name: Close superseded PRs
|
|
run: |
|
|
EXISTING="${{ steps.existing_prs.outputs.numbers }}"
|
|
CURRENT=$(gh pr list --state open --base main --limit 100 --json number,headRefName \
|
|
--jq '.[] | select(.headRefName | test("^(release-notes/update-|update-release-notes-)")) | .number')
|
|
|
|
NEW_PRS=$(comm -13 <(echo "$EXISTING" | sort) <(echo "$CURRENT" | sort))
|
|
if [ -z "$NEW_PRS" ]; then
|
|
echo "This run did not open a release notes PR, nothing to supersede"
|
|
exit 0
|
|
fi
|
|
|
|
# The new PR is already open at this point, so a failure to tidy up an old
|
|
# one is a warning, not a reason to fail the run.
|
|
NEWEST=$(echo "$NEW_PRS" | sort -n | tail -n 1)
|
|
echo "$EXISTING" | while read -r PR; do
|
|
[ -n "$PR" ] || continue
|
|
echo "Closing superseded release notes PR #$PR"
|
|
gh pr close "$PR" --delete-branch --comment "Superseded by #$NEWEST." \
|
|
|| echo "Warning: could not close #$PR"
|
|
done
|
|
env:
|
|
GH_TOKEN: ${{ steps.generate_token.outputs.token }}
|
|
|
|
- name: No changes
|
|
if: steps.changes.outputs.has_changes == 'false'
|
|
run: echo "No release notes updates needed"
|