ci: automate library release with Release and Promote workflows#77
ci: automate library release with Release and Promote workflows#77g-carre wants to merge 4 commits into
Conversation
Automate the library release flow, adapting the pattern from scality/nodeip-discovery#2 for a pure Go library (no container/binary artifact): - release.yaml: manual dispatch to compute the next semver (alpha/beta/GA x patch/minor/major) and push an annotated v* tag. - promote.yaml: on a v* tag push, create a GitHub Release with generated notes, marking prereleases when the tag has a hyphen. The reference build.yaml/post-merge.yaml and the promote build job are omitted since a library ships as a git tag consumed via `go get`, not a Docker image. Issue: ARTESCA-17773
|
Compute the base tag with `git tag --merged HEAD --sort=version:refname` instead of `--sort=taggerdate`: - version:refname orders by semantic version, so an older-line hotfix tagged after a newer release no longer becomes the base. - --merged HEAD scopes selection to the current branch's history, making it correct for future per-minor release branches (e.g. releasing v1.0.x from dev/1.0 while v2.0.0 lives on main). grep -v '-' is retained: version sort would otherwise rank a prerelease above its GA. Issue: ARTESCA-17773
| # NOTE: when release branches are added, also relax the `main`-only guard | ||
| # above and constrain non-`main` branches to patch-scope releases. | ||
| run: | | ||
| last_ga_tag=$(git tag --merged HEAD --sort=version:refname --list "v*" | grep -v '\-' | tail -n 1) |
There was a problem hiding this comment.
grep -v '\-' returns exit code 1 when no lines match. With GitHub Actions' default set -e -o pipefail, this kills the pipeline before the fallback on line 58 (last_ga_tag="0.0.0") can fire. This breaks the first-ever release and any release when only pre-release tags exist.
| last_ga_tag=$(git tag --merged HEAD --sort=version:refname --list "v*" | grep -v '\-' | tail -n 1) | |
| last_ga_tag=$(git tag --merged HEAD --sort=version:refname --list "v*" | { grep -v '\-' || true; } | tail -n 1) |
— Claude Code
| - "v*" | ||
|
|
||
| jobs: | ||
| create-release: |
There was a problem hiding this comment.
No permissions block is declared. If the repo (or org) restricts the default GITHUB_TOKEN to read-only (GitHub's recommended default), softprops/action-gh-release will fail with a 403 because it needs write access to create releases.
| create-release: | |
| permissions: | |
| contents: write | |
| runs-on: ubuntu-24.04 |
— Claude Code
|
- add a quality-gate job running the test suite against the exact commit being tagged (releases are cut from main without re-running pre-merge) - restrict the default GITHUB_TOKEN to contents: read; the tag is pushed with the App token - guard the GA-tag grep with || true so the 0.0.0 fallback fires on a repo with no GA tag, even if the step ever runs with pipefail - drop git fsck/gc, pointless on a fresh CI clone
Do not rely on the org-wide default GITHUB_TOKEN permissions to create the GitHub Release.
| token: ${{ steps.app-token.outputs.token }} | ||
| - name: Install semver tool | ||
| run: | | ||
| curl --fail -LO https://raw.githubusercontent.com/fsaintjacques/semver-tool/3.4.0/src/semver |
There was a problem hiding this comment.
Nit: the rest of the workflow pins actions to commit SHAs for supply chain integrity, but this semver script is fetched by tag without checksum verification. If the 3.4.0 tag in that repo is ever force-pushed, the content silently changes. Consider pinning to a commit SHA in the URL or adding a sha256sum --check step after download.
— Claude Code
|
Clean PR — version computation logic is correct, actions are SHA-pinned, the App token / GITHUB_TOKEN split is right (App token for the tag push so it triggers promote.yaml), and the main-only guard plus quality-gate tests are solid. |
What
Adds two GitHub Actions workflows to automate the release flow for this Go library, adapting the pattern from scality/nodeip-discovery#2:
release.yaml— manualworkflow_dispatchfrommain. Computes the next semver (alpha/beta/GA×patch/minor/major) off the last GA tag and pushes an annotatedv*tag.promote.yaml— triggers on av*tag push and creates a GitHub Release with generated notes, marking prereleases when the tag contains a hyphen.Flow: click Release → tag is created → Promote fires → GitHub Release published.
Why it differs from the reference
nodeip-discovery is a deployable service (builds a Docker image). raidmgmt is a pure library — no
Dockerfile, nocmd/, consumed viago get ...@vX.Y.Z, so the git tag is the artifact. The referencebuild.yaml/post-merge.yamland the promotebuildjob are therefore omitted.generate-sbomwas intentionally left out: it targets a Docker image and uploads to Dependency Track, which is redundant for a library whose deps are already captured in the consuming component's SBOM.Prerequisite
release.yamlusesvars.ACTIONS_APP_ID+secrets.ACTIONS_APP_PRIVATE_KEY(already configured in this repo — referenced byreview.yml).Issue: ARTESCA-17773
🤖 Generated with Claude Code