ci(release): semantic-release + GoReleaser pipeline#32
Conversation
344c9ed to
c583be5
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d1a9353d2f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| concurrency: | ||
| group: verify-${{ github.workflow }}-${{ github.ref }} | ||
| cancel-in-progress: true |
There was a problem hiding this comment.
Remove workflow-level auto-cancel for release runs
The workflow-level concurrency block cancels any in-progress run on main when a newer push arrives, which can interrupt the release job after semantic-release has already created the tag/GitHub release but before GoReleaser uploads tarballs/checksums. In that case, the next run may not republish assets for that already-tagged version, leaving a published release without binaries. This is introduced by placing cancel-in-progress: true at the workflow scope in ci.yml instead of scoping cancellation to verify only.
Useful? React with 👍 / 👎.
c583be5 to
be4fcdb
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit be4fcdb. Configure here.
Replace the manual `scripts/release.sh` flow with a push-to-main, Conventional-Commits-driven pipeline: - Verify job runs on PR + push (`go run ./cmd/verify`). - Release job runs on push to main after verify, skipped on `[skip ci]`. - semantic-release decides the next version from commits and creates the tag + GitHub Release (tag-only mode — no source bump for Go). - GoReleaser builds darwin/arm64 + darwin/amd64 tarballs, uploads them to the release, and pushes the formula update to `uinaf/homebrew-tap`. - `actions/attest-build-provenance` signs the artifacts. - Bot identity matches the org pattern (`glitch418x`). Tarball naming and contents match the current artifacts byte-for-byte (`healthd_v<ver>_darwin_<arch>.tar.gz`, binary-only) so the existing `scripts/install.sh` and `uinaf/homebrew-tap/Formula/healthd.rb` keep working without changes. Side changes: - Add `--version` wiring in `cmd/root.go` so GoReleaser ldflags inject build metadata; falls back to `debug.ReadBuildInfo` for `go build`. - `go mod tidy` (now run as a release before-hook) reclassifies bubbletea/lipgloss as direct deps — they are imported directly. - Drop redundant `integration` + `e2e/cli` steps from CI; `cmd/verify` already covers them via `go list ./...`. - Add `.gitignore` for `dist/` and `bin/`. Requires `TAP_GITHUB_TOKEN` repo secret (fine-grained PAT with `contents: write` on `uinaf/homebrew-tap`) before the first release.
be4fcdb to
af421b4
Compare
|
Both review findings addressed in
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 56d4f27b03
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| run: git fetch --tags --force | ||
|
|
||
| - name: Run GoReleaser | ||
| if: steps.release.outputs.new_release_published == 'true' |
There was a problem hiding this comment.
Allow GoReleaser to run on release-job retries
Run GoReleaser is gated on steps.release.outputs.new_release_published == 'true', so if semantic-release succeeds (tag/release created) but a later step fails, rerunning the job on the same commit will skip artifact publishing because semantic-release now reports no new release. In that failure mode (for example transient GoReleaser/Homebrew token issues), the GitHub release stays published without binaries/checksums unless someone performs a manual recovery.
Useful? React with 👍 / 👎.
Codex P1: with the previous gate, a partial-failure rerun (e.g. brew token blip after semantic-release tagged) would skip GoReleaser because semantic-release reports no NEW release the second time. Result was a published GitHub Release without binaries. Now we always fetch tags after semantic-release, then detect via 'git describe --exact-match --tags HEAD'. Re-running the job recovers the GoReleaser publish step against the existing tag.
|
Updates on
|
|
To use Codex here, create an environment for this repo. |

Summary
scripts/release.shwith a push-to-main, Conventional Commits driven pipelinesemantic-releasedecides version + tags + drafts the GitHub Release; GoReleaser ships darwin tarballs and bumpsuinaf/homebrew-tap[skip ci])healthd_v<ver>_darwin_<arch>.tar.gz, binary-only) soscripts/install.shand the existing brew formula keep workingChanges
.github/workflows/ci.yml— verify (fmt + lint + test + coverage gate viago run ./cmd/verify) → release (semantic-release → GoReleaser → build provenance attestation).goreleaser.yaml— darwin arm64+amd64, ldflag-injected version, brew formula auto-bump inuinaf/homebrew-tapviaTAP_GITHUB_TOKEN.releaserc.json— tag-only mode (no source bump for Go), conventionalcommits preset,chore/ci/docsexcluded from version bumps.gitignore—/dist/,/bin/scripts/release.sh,.github/workflows/release.yml,.github/workflows/ci-go-checks.ymlcmd/root.go— wireVersion/Commit/BuildDate(ldflag-injected) + cobra--versionflag, with adebug.ReadBuildInfofallback for plaingo buildgo mod tidy(new GoReleaser before-hook surfaced this) reclassifiesbubbletea+lipglossas direct deps — they are imported directlyValidation
go run ./cmd/verify— total 82.7%, all packages ≥ 70%actionlint .github/workflows/ci.yml— cleangoreleaser check— cleangoreleaser release --snapshot --clean --skip=publish,sign— produceshealthd_v0.5.0_darwin_arm64.tar.gzcontaining onlyhealthd, pluschecksums.txtand a generated brew formula matching the existing tap shapego build+./healthd --version→dev (4d7c067, 2026-04-26T...)from VCS infofeat:/fix:commit and watch verify→release→tap-updateRisks
TAP_GITHUB_TOKEN— fine-grained PAT (or GitHub App token) withcontents: writeonuinaf/homebrew-taponly. Without it thereleasejob will fail on the GoReleaser brew step. Add to repo secrets before the first feat/fix commit lands on main.package.jsonto bump back). No[skip ci]loop risk, but the guard is in both jobs as defense-in-depth.ci(...)— by.releaserc.jsonrules it does not trigger a release, so merging is safe.brews:is being phased out in favor ofhomebrew_casks. Migration is a separate concern (touches the tap repo too); keepingbrews:for now since the existing tap uses Formula format.Linked Issues
None.
Note
Medium Risk
Medium risk because it replaces the release/tagging flow with an automated GitHub Actions pipeline that depends on repo secrets (
TAP_GITHUB_TOKEN) and new tooling; failures would affect publishing rather than runtime behavior.Overview
Replaces the separate Go CI and tag-based release workflows (and the manual
scripts/release.sh) with a singleci.ymlthat runsgo run ./cmd/verifyon PRs/pushes and, on pushes tomain, automatically tags/releases viasemantic-releaseand publishes binaries/Homebrew updates via GoReleaser (plus build provenance attestation).Adds GoReleaser (
.goreleaser.yaml) and semantic-release (.releaserc.json) configuration, updates the CLI to expose--versionusing ldflag-injectedVersion/Commit/BuildDatewith adebug.ReadBuildInfofallback, and tweaks docs and ignores (/dist,/bin).Reviewed by Cursor Bugbot for commit 9545644. Bugbot is set up for automated code reviews on this repo. Configure here.