Summary
A comparison of our release workflow with the preflight pattern used in
unbound-force/gaze (PR unbound-force/gaze#100) and
unbound-force/unbound-force identified several improvement opportunities
to make the release process more robust.
Current State
The release workflow is a single workflow_dispatch job that runs GoReleaser
immediately on dispatch. It relies on branch protection to ensure code quality
before code reaches main. This works well but leaves room for additional
safety nets.
Improvement Opportunities
1. No CI verification
The workflow trusts branch protection to ensure CI passed on the commit being
released. Adding an explicit query to the GitHub Checks API for required check
run conclusions would provide defense in depth — catching edge cases where
branch protection is temporarily adjusted or bypassed by an admin.
2. No concurrency protection
No concurrency: group is defined. If two workflow_dispatch runs are
triggered in quick succession, they could race. A concurrency group would
serialize releases safely.
3. No semver ordering check
Nothing prevents releasing v1.1.0 after v1.2.0 has already been released,
which could confuse downstream consumers.
4. No unreleased commits guard
Nothing prevents triggering a release that produces the same artifacts as the
previous tag (no new commits). A simple git rev-list --count check would
catch this early.
5. No tag creation by workflow
The workflow uses GORELEASER_CURRENT_TAG to name the release but does not
create a git tag. The tag may or may not exist in git history depending on
whether the maintainer also pushed one separately. Having the workflow create
an annotated tag (idempotently) after validation would ensure consistency.
Suggested Improvements
Reference
Summary
A comparison of our release workflow with the preflight pattern used in
unbound-force/gaze(PR unbound-force/gaze#100) andunbound-force/unbound-forceidentified several improvement opportunitiesto make the release process more robust.
Current State
The release workflow is a single
workflow_dispatchjob that runs GoReleaserimmediately on dispatch. It relies on branch protection to ensure code quality
before code reaches
main. This works well but leaves room for additionalsafety nets.
Improvement Opportunities
1. No CI verification
The workflow trusts branch protection to ensure CI passed on the commit being
released. Adding an explicit query to the GitHub Checks API for required check
run conclusions would provide defense in depth — catching edge cases where
branch protection is temporarily adjusted or bypassed by an admin.
2. No concurrency protection
No
concurrency:group is defined. If twoworkflow_dispatchruns aretriggered in quick succession, they could race. A concurrency group would
serialize releases safely.
3. No semver ordering check
Nothing prevents releasing
v1.1.0afterv1.2.0has already been released,which could confuse downstream consumers.
4. No unreleased commits guard
Nothing prevents triggering a release that produces the same artifacts as the
previous tag (no new commits). A simple
git rev-list --countcheck wouldcatch this early.
5. No tag creation by workflow
The workflow uses
GORELEASER_CURRENT_TAGto name the release but does notcreate a git tag. The tag may or may not exist in git history depending on
whether the maintainer also pushed one separately. Having the workflow create
an annotated tag (idempotently) after validation would ensure consistency.
Suggested Improvements
release-${{ github.ref }},cancel-in-progress: false)git rev-list --count)Reference
unbound-force/gazePR chore(deps): bump github.com/evanphx/json-patch/v5 from 5.9.0 to 5.9.11 #100: preflight gate implementationunbound-force/unbound-forcerelease workflow: original pattern