Releasing the bench CLI
A release publishes prebuilt bench binaries for macOS and Linux (x86-64 and
arm64) to a
GitLab Release.
GoReleaser drives it from
.goreleaser.yml; the jobs live
in
.gitlab-ci.yml under the release stage.
One-time setup: the publish token
release:goreleaser needs a token with api scope to create the Release and
upload assets. It reads one from the project’s
GitLab Secrets Manager
as goreleaser_token.
To provision the token, a project owner:
- Creates a
project access token
named
goreleaser, with the Developer role and theapiscope. Developer is enough to create a Release and publish to the package registry. The existingdangertoken is configured exactly this way; copy it. - Adds it under Secure > Secrets manager with the name
goreleaser_tokenand Branch set tov*. The job only runs on tag pipelines, whereCI_COMMIT_BRANCHis unset, so a secret scoped tomainnever resolves and the job fails with a 403.v*matches the release tags and nothing else.
Project access tokens expire, and a lapsed one fails the release job at tag time rather than before. GitLab emails project Maintainers and Owners ahead of the token’s expiry, so when the warning arrives, rotate the token and overwrite the secret’s value.
Cutting a release
The binary reports the version from the git tag. The crate manifests don’t affect it, but keep them in step so the source matches the release.
In a merge request, bump
versionincli/Cargo.tomlandconfig/Cargo.toml, then runcargo update -wto refreshCargo.lock. Merge it; the merge commit is what you tag in step 3.Check that the mock release is green on
main. It runs on merge requests touching.goreleaser.yml,.gitlab-ci.yml, or.mise.toml, and builds every archive without publishing. To run it locally on a macOS host:goreleaser release --snapshot --clean --skip=publishCreate and push the tag on the bump MR’s merge commit:
git tag vX.Y.Z <merge-commit-sha> git push origin vX.Y.ZWatch
release:goreleaserin the tag pipeline. It builds all four targets and uploads the archives pluschecksums.txt.Verify the published artifacts:
mise x gitlab:gitlab-org/lab-bench/bench@X.Y.Z -- bench --versionIt should print the tagged version, since the release build stamps
BENCH_VERSIONfrom the tag. Any other build reports0.0.0-dev.
Why the release runs on macOS
The darwin targets link against the macOS SDK, which only Xcode provides; cargo-zigbuild supplies the Linux linker from that same host. So one macOS runner builds all four targets, while a Linux runner could only build two. Splitting the build across two runners and merging the artifacts into a single Release requires GoReleaser Pro.
The tradeoff is a dependency on saas-macos-medium-m1, which is in beta with
documented capacity limits.
If that pool is exhausted at tag time, retry the job; the tag already exists, so
nothing needs recreating.
Notarization
The macOS binaries are not notarized, which needs a paid Apple Developer ID.
Downloading them through a browser therefore trips Gatekeeper. mise and curl
do not set the quarantine attribute, so the documented install path avoids it
entirely.