[Feat] Generate task-relevant kickoff strings from the router (#329) #166
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: Release | |
| on: | |
| push: | |
| branches: | |
| - develop | |
| # Every push re-checks the live develop version. Tagged versions are no-ops; | |
| # an untagged version means a maintainer merged a release PR and is ready for | |
| # the frozen promotion gate. | |
| concurrency: | |
| group: release-develop | |
| cancel-in-progress: true | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| jobs: | |
| promote: | |
| name: Open or refresh Promote PR | |
| runs-on: blacksmith-4vcpu-ubuntu-2404 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 | |
| with: | |
| token: ${{ secrets.RELEASE_BOT_TOKEN || secrets.GITHUB_TOKEN }} | |
| fetch-depth: 0 | |
| ref: develop | |
| - name: Cut frozen release branch and open promote PR | |
| env: | |
| GH_TOKEN: ${{ secrets.RELEASE_BOT_TOKEN || secrets.GITHUB_TOKEN }} | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| version="$(node -p "require('./package.json').version")" | |
| : "${version:?missing package.json version}" | |
| tag="v${version}" | |
| if git rev-parse "$tag" >/dev/null 2>&1 || git ls-remote --tags origin "refs/tags/$tag" | grep -q .; then | |
| echo "Tag $tag already exists; nothing to promote." | |
| exit 0 | |
| fi | |
| git fetch origin main --quiet | |
| if ! git show-ref --verify --quiet refs/remotes/origin/main; then | |
| echo "origin/main is missing; create main before promoting." | |
| exit 1 | |
| fi | |
| # Freeze the release at the commit that introduced this version (the | |
| # release PR merge), not at the moving develop tip. Commits merged to | |
| # develop afterward wait for the next release. | |
| bump_sha="$(node scripts/release/find-version-commit.mjs "$version" HEAD)" | |
| if git merge-base --is-ancestor "$bump_sha" origin/main; then | |
| echo "main already contains ${bump_sha}; nothing to promote." | |
| exit 0 | |
| fi | |
| release_branch="release/${tag}" | |
| if git ls-remote --exit-code --heads origin "$release_branch" >/dev/null 2>&1; then | |
| echo "Release branch ${release_branch} already exists; leaving it frozen." | |
| else | |
| git push origin "${bump_sha}:refs/heads/${release_branch}" | |
| echo "Cut ${release_branch} at ${bump_sha}" | |
| fi | |
| notes="$(node scripts/release/extract-changelog-section.mjs "$version" || true)" | |
| body_file="$(mktemp)" | |
| { | |
| echo "## Promote ${tag}" | |
| echo | |
| echo "Frozen at \`${bump_sha}\` — the commit where \`${version}\` was versioned. Commits merged to \`develop\` after that point ship in the next release." | |
| echo | |
| echo "- Merge this PR with a **merge commit** (do not squash or rebase)." | |
| echo "- If multiple promote PRs are open, merge them in version order (oldest first)." | |
| echo "- Merging publishes a GitHub Release for \`${tag}\` and triggers the existing GHCR \`v*\` image publish (\`latest\` channel)." | |
| echo "- The \`${release_branch}\` branch can be deleted after this PR merges." | |
| echo | |
| echo "### Changelog" | |
| echo | |
| if [ -n "$notes" ]; then | |
| echo "$notes" | |
| else | |
| echo "_No CHANGELOG section found for ${version}; see commits on develop._" | |
| fi | |
| } > "$body_file" | |
| existing="$(gh pr list --base main --head "$release_branch" --state open --json number,url --jq '.[0].url // empty')" | |
| if [ -n "$existing" ]; then | |
| echo "Promote PR already open: $existing" | |
| gh pr edit "$existing" --title "Promote ${tag} to production" --body-file "$body_file" | |
| rm -f "$body_file" | |
| exit 0 | |
| fi | |
| gh pr create \ | |
| --base main \ | |
| --head "$release_branch" \ | |
| --title "Promote ${tag} to production" \ | |
| --body-file "$body_file" | |
| rm -f "$body_file" |