Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ Push the release tag to trigger the release:
git fetch && git tag v{{VERSION}} origin/release/{{VERSION}}
git push origin v{{VERSION}}
```
This PR will auto-merge once the tag is pushed.
The tag push will trigger the release build. This PR will be automatically closed.

## Cherry-Picks

If you need to include additional fixes, cherry-pick them into the `release/{{VERSION}}` branch before tagging.

## Important Notes

Expand Down
32 changes: 19 additions & 13 deletions .github/workflows/check-release-pr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
ref: ${{ github.head_ref }}
fetch-depth: 0

- name: Check all PR commits exist in main
- name: Check all PR commits are empty or cherry-picked from main
run: |
git fetch origin main

Expand All @@ -39,19 +39,25 @@ jobs:
exit 0
fi

COMMIT_COUNT=$(echo "$MISSING_COMMITS" | wc -l)
FIRST_COMMIT=$(git rev-list --reverse HEAD ^origin/main | head -1)
ALL_EMPTY=true
for commit in $MISSING_COMMITS; do
if [ -n "$(git diff-tree --no-commit-id --name-only -r "$commit")" ]; then
ALL_EMPTY=false
break
fi
done

if [ "$COMMIT_COUNT" -eq 1 ] && echo "$MISSING_COMMITS" | grep -q "$FIRST_COMMIT"; then
echo "✅ Only version bump commit is unique"
git log --oneline -1 "$FIRST_COMMIT"
else
echo "❌ Found commits that should exist in main:"
if [ "$ALL_EMPTY" = true ]; then
echo "✅ Only empty commits (release branch markers) are unique"
for commit in $MISSING_COMMITS; do
if [ "$commit" != "$FIRST_COMMIT" ]; then
git log --oneline -1 "$commit"
fi
git log --oneline -1 "$commit"
done
echo "Make sure commits have equivalents in main. If you've since updated main, re-run this job"
exit 1
exit 0
fi

echo "❌ Found commits with changes that don't exist in main:"
for commit in $MISSING_COMMITS; do
git log --oneline -1 "$commit"
done
echo "Cherry-pick these commits into main first, or re-run this job after updating main."
exit 1
59 changes: 59 additions & 0 deletions .github/workflows/close-release-pr-on-tag.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
name: Close release PR on tag push

on:
push:
tags:
- 'v[0-9]+.[0-9]+.[0-9]+'

permissions:
actions: write
contents: write
pull-requests: write

jobs:
close-release-pr:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1

- name: Extract version from tag
id: version
env:
TAG: ${{ github.ref_name }}
run: |
VERSION=${TAG#v}
BRANCH="release/${VERSION}"

echo "tag=${TAG}" >> $GITHUB_OUTPUT
echo "version=${VERSION}" >> $GITHUB_OUTPUT
echo "branch=${BRANCH}" >> $GITHUB_OUTPUT

echo "Tag: ${TAG}"
echo "Version: ${VERSION}"
echo "Expected branch: ${BRANCH}"

- name: Find and close matching PR
env:
GH_TOKEN: ${{ github.token }}
BRANCH: ${{ steps.version.outputs.branch }}
TAG: ${{ steps.version.outputs.tag }}
VERSION: ${{ steps.version.outputs.version }}
run: |
PR_NUMBER=$(gh pr list --head "$BRANCH" --state open --json number --jq '.[0].number // empty')

if [ -z "$PR_NUMBER" ]; then
echo "ℹ️ No open PR found for branch: $BRANCH (may already be closed)"
else
echo "✅ Found PR #$PR_NUMBER for branch: $BRANCH"
gh pr close "$PR_NUMBER" --comment "Release $TAG has been tagged and pushed. Closing this PR (version bump was already merged to main)."
echo "✅ Closed PR #$PR_NUMBER"
fi

- name: Trigger patch release
env:
BRANCH: ${{ steps.version.outputs.branch }}
GH_TOKEN: ${{ github.token }}
run: |
gh workflow run patch-release.yaml \
--field target_branch=$BRANCH
88 changes: 88 additions & 0 deletions .github/workflows/create-release-branch.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
name: Create Release Branch

on:
pull_request:
types:
- closed
branches:
- main

permissions:
contents: write
pull-requests: write

jobs:
create-release-branch:
runs-on: ubuntu-latest
if: >
github.event.pull_request.merged == true &&
startsWith(github.event.pull_request.head.ref, 'version-bump/')
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
ref: ${{ github.event.pull_request.merge_commit_sha }}
fetch-depth: 0
Comment on lines +21 to +24

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Checkout the merged PR SHA instead of the live base branch

This release branch is cut from github.event.pull_request.base.ref, which is the moving branch name, not the merge commit that just closed the PR. If another PR lands on main (or on the patch line) before this job starts, actions/checkout will pull the newer tip and just get-tag-version will read that newer state, so the workflow can create release/<version> from unrelated commits or even derive the wrong version. Using the merged PR SHA here avoids releasing code that was never part of the version-bump PR that triggered the job.

Useful? React with 👍 / 👎.


- uses: cashapp/activate-hermit@e49f5cb4dd64ff0b0b659d1d8df499595451155a # v1
- uses: astral-sh/setup-uv@61cb8a9741eeb8a550a1b8544337180c0fc8476b # v7.2.0

- name: Extract version and base branch
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
VERSION=$(just get-tag-version)
BASE_BRANCH="${{ github.event.pull_request.base.ref }}"
echo "version=$VERSION" >> $GITHUB_ENV
echo "base_branch=$BASE_BRANCH" >> $GITHUB_ENV
echo "Version: $VERSION"
echo "Base branch: $BASE_BRANCH"

PRIOR_TAG=$(just get-prior-version "$VERSION")
if [[ -z "$PRIOR_TAG" ]]; then
echo "No prior version (first release), using first commit"
PRIOR_TAG=$(git rev-list --max-parents=0 HEAD)
Comment on lines +41 to +43

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Fail when the previous release lookup comes back empty

For minor releases, just get-prior-version now depends on gh release list, so it can legitimately return nothing when the previous tag exists but the GitHub Release was never published yet (for example after a failed release.yml) or the API call transiently fails. Falling back to git rev-list --max-parents=0 HEAD here then opens a release PR whose notes compare against the entire repository history, which is much harder to notice than a hard failure; update-release-pr.yaml has the same fallback.

Useful? React with 👍 / 👎.

fi
echo "prior_ref=$PRIOR_TAG" >> $GITHUB_ENV
echo "Prior ref: $PRIOR_TAG"

- name: Create release branch
run: |
git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com"
git config --local user.name "github-actions[bot]"

BRANCH_NAME="release/${{ env.version }}"
git switch -c "$BRANCH_NAME"

# Add an empty commit so GitHub can represent this as a PR
git commit --allow-empty --message "chore(release): open release branch for ${{ env.version }}"

git push origin "$BRANCH_NAME"

HEAD_REF=$(git rev-parse HEAD)
echo "branch_name=$BRANCH_NAME" >> $GITHUB_ENV
echo "head_ref=$HEAD_REF" >> $GITHUB_ENV

- name: Generate release notes
uses: ./.github/actions/generate-release-pr-body
with:
version: ${{ env.version }}
head_ref: ${{ env.head_ref }}
prior_ref: ${{ env.prior_ref }}

- name: Create Release PR
run: |
PR_URL=$(gh pr create \
-B "${{ env.base_branch }}" \
-H "${{ env.branch_name }}" \
--title "chore(release): release version ${{ env.version }}" \
--body-file pr_body.txt)
echo "pr_url=$PR_URL" >> $GITHUB_ENV
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Post release checklist comment
run: |
sed 's/{{VERSION}}/${{ env.version }}/g' RELEASE_CHECKLIST.md > checklist_comment.md
gh pr comment "${{ env.pr_url }}" --body-file checklist_comment.md
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
118 changes: 0 additions & 118 deletions .github/workflows/create-release-pr.yaml

This file was deleted.

Loading
Loading