Release #28
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: | |
| workflow_run: | |
| workflows: [CI] | |
| branches: [main] | |
| types: | |
| - completed | |
| concurrency: | |
| group: release-${{ github.ref }} | |
| cancel-in-progress: false | |
| defaults: | |
| run: | |
| shell: bash | |
| env: | |
| # go-semantic-release/action (SHA-pinned below) is a thin wrapper: at | |
| # runtime it downloads a `semantic-release` executable and runs it with | |
| # this job's `contents: write` permission. Pinning the action's SHA does | |
| # NOT pin that executable — by default the action fetches whatever is | |
| # currently "latest" from registry.go-semantic-release.xyz. We instead | |
| # download a specific, checksummed release ourselves and hand the action | |
| # that binary via its `bin` input, so nothing here floats. | |
| # | |
| # To bump: pick the new tag from | |
| # https://github.com/go-semantic-release/semantic-release/releases, then | |
| # copy the `linux_amd64` line out of that release's own | |
| # `semantic-release_<version>_checksums.txt` asset. | |
| SEMREL_VERSION: v2.31.0 | |
| SEMREL_SHA256: b8f518b1aeb1d1742f4e6e91a179b707cea4309a64fe3854f465bf724f04f6d3 | |
| jobs: | |
| release: | |
| name: Create Release | |
| if: github.event.workflow_run.conclusion == 'success' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| permissions: | |
| contents: write | |
| # The changelog promote opens a PR instead of pushing to main, which the | |
| # branch ruleset forbids. | |
| pull-requests: write | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| fetch-depth: 0 | |
| - uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 | |
| with: | |
| go-version-file: go.mod | |
| cache: true | |
| - name: Fetch and verify semantic-release binary | |
| id: semrel-bin | |
| run: | | |
| set -euo pipefail | |
| asset="semantic-release_${SEMREL_VERSION}_linux_amd64" | |
| url="https://github.com/go-semantic-release/semantic-release/releases/download/${SEMREL_VERSION}/${asset}" | |
| dest="${RUNNER_TEMP}/${asset}" | |
| curl --fail --silent --show-error --location -o "$dest" "$url" | |
| echo "${SEMREL_SHA256} ${dest}" | sha256sum -c - | |
| chmod +x "$dest" | |
| echo "path=${dest}" >> "$GITHUB_OUTPUT" | |
| - name: Create Release | |
| id: release | |
| uses: go-semantic-release/action@2e9dc4247a6004f8377781bef4cb9dad273a741f # v1.24.1 | |
| with: | |
| hooks: goreleaser | |
| # Throwaway path for the goreleaser hook — never committed. The | |
| # real CHANGELOG.md is promoted by hand below, since `prepend` | |
| # writes above the file's H1 and intro prose, and this action | |
| # never commits the file back to the repo regardless. | |
| changelog-file: .release-notes.md | |
| allow-initial-development-versions: true | |
| prepend: true | |
| bin: ${{ steps.semrel-bin.outputs.path }} | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Promote Unreleased changelog section | |
| # steps.release.outputs.version is only set when a new version was | |
| # actually released (go-semantic-release/action returns early, | |
| # without calling setOutput, when there's nothing to release). | |
| # | |
| # This opens a PR rather than pushing to main. The main ruleset requires | |
| # a pull request and 5 status checks with no bypass actors, so the direct | |
| # push this used to do was rejected outright (GH013) — the tag and the | |
| # GitHub Release were created and only the changelog commit was lost, so | |
| # the job failed AFTER releasing and the drift was silent. Granting the | |
| # bot a bypass would have fixed it by letting every workflow in the repo | |
| # push to main unreviewed, which is a poor trade for a docs commit. | |
| if: steps.release.outputs.version != '' | |
| env: | |
| RELEASE_VERSION: ${{ steps.release.outputs.version }} | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| date="$(date -u +%Y-%m-%d)" | |
| .github/scripts/promote-changelog.sh "$RELEASE_VERSION" "$date" | |
| if git diff --quiet -- CHANGELOG.md; then | |
| echo "CHANGELOG.md unchanged — nothing to promote." | |
| exit 0 | |
| fi | |
| branch="chore/changelog-v${RELEASE_VERSION}" | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| git checkout -b "$branch" | |
| git add CHANGELOG.md | |
| git commit -m "docs: promote Unreleased to v${RELEASE_VERSION} in CHANGELOG.md" | |
| git push origin "$branch" | |
| # --fill would reuse the commit message; the body is worth spelling | |
| # out because whoever sees this PR did not run the release. Built with | |
| # printf so the text is not indented by this block's YAML indentation. | |
| body="$(printf '%s\n' \ | |
| "Automated by the Release workflow after cutting v${RELEASE_VERSION}." \ | |
| "" \ | |
| "Moves the \`## Unreleased\` section under a \`## v${RELEASE_VERSION}\` heading." \ | |
| "The tag and GitHub Release already exist; this only records them in" \ | |
| "the changelog, so merging is safe whenever convenient.")" | |
| gh pr create \ | |
| --base main \ | |
| --head "$branch" \ | |
| --title "docs: promote Unreleased to v${RELEASE_VERSION} in CHANGELOG.md" \ | |
| --body "$body" | |
| # Auto-merge so the changelog does not drift while PRs queue up. It | |
| # merges once the required checks pass; if auto-merge is disabled on | |
| # the repo, say so and leave the PR open rather than failing a release | |
| # that has already succeeded. | |
| gh pr merge "$branch" --squash --auto \ | |
| || echo "::warning::Could not enable auto-merge; merge the changelog PR by hand." |