Add release workflow with dual-tag versioning#56
Merged
Conversation
Replace the manual bump-tag workflow with a workflow_dispatch release workflow that creates an annotated semver tag, force-updates the floating major tag (e.g. v1), and publishes a GitHub Release with auto-generated notes spanning the previous semver tag. Inputs validate the vX.Y.Z(-prerelease) format up front and short-circuit if the tag already exists. Build, lint, and test run before any tag is pushed so a broken main never makes it into a release. The major tag update is gated by the update-major input, which preserves the manual escape hatch the deleted bump-tag.yaml provided. Co-authored-by: Codesmith <codesmith-bot@users.noreply.github.com>
github.event.inputs.* returns strings, so the bare 'if: github.event.inputs.update-major' was always truthy (the literal string 'false' is truthy in GitHub Actions expressions). Compare explicitly against 'true' to match the Summary step's check and restore the documented escape hatch when releasing without bumping the major tag. Co-authored-by: Codesmith <codesmith-bot@users.noreply.github.com>
The previous bump-tag.yaml explicitly checked out 'main', which the
new release.yml dropped, allowing a dispatch from any branch to tag
a non-main commit. Add 'ref: main' to the checkout to restore that
guarantee.
Also move every workflow_dispatch input out of '${{ ... }}'
expressions inside 'run:' bodies and into 'env:' bindings on the
step. GitHub Actions substitutes expressions before the shell sees
them, so a crafted version like 'v1.0.0"; rm -rf /; #' would have
executed before the regex check could reject it. Referencing the
inputs as shell variables ($VERSION, $UPDATE_MAJOR, $GIT_USER,
$REPOSITORY) keeps the values quoted by the shell instead.
Co-authored-by: Codesmith <codesmith-bot@users.noreply.github.com>
The Summary step already exposes $REPOSITORY (${{ github.repository
}}) for the release link, but the 'uses:' examples still hardcoded
'useblacksmith/stickydisk'. Reference $REPOSITORY in the example
block too so the summary stays correct if the repo is ever renamed
or transferred.
Co-authored-by: Codesmith <codesmith-bot@users.noreply.github.com>
The version regex permits prerelease suffixes (e.g. v2.0.0-beta.1) and 'update-major' defaults to true, so dispatching a prerelease would force-push the floating major tag (e.g. v2) onto unstable code. Anyone pinning '@v2' in their workflow would then silently pick up the beta. Detect prerelease versions by checking for a hyphen in $VERSION and short-circuit the tag-update step before any push. Mirror the same guard in the Summary so it does not claim a major tag move that did not happen. Stable releases are unaffected. Co-authored-by: Codesmith <codesmith-bot@users.noreply.github.com>
The Tags Created list already hides the major tag entry when update-major is false or the release is a prerelease, but the Usage block kept telling users to reference '$REPOSITORY@$MAJOR_VERSION' unconditionally. For a fresh major prerelease (e.g. v2.0.0-beta.1) that tag may not exist at all, so the recommendation could point nowhere. Gate the major-tag 'uses:' line behind the same condition so the example only appears when the floating major tag was created or updated this run. The pinned semver line is always shown. Co-authored-by: Codesmith <codesmith-bot@users.noreply.github.com>
The version regex permits suffixes like v2.0.0-beta.1, but the gh release create call never set --prerelease, so a beta would land on the Releases page as a stable, latest release. Detect prereleases by the SemVer hyphen in $VERSION and pass --prerelease via an array so both the no-previous-tag and notes-start-tag branches stay in sync. Co-authored-by: Codesmith <codesmith-bot@users.noreply.github.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit e7f1f21. Configure here.
Git's default 'version:refname' sort treats v1.0.0-alpha as greater than v1.0.0, the opposite of SemVer. Without versionsort.suffix configured, releasing v1.0.1 when both v1.0.0 and v1.0.0-alpha exist would pick v1.0.0-alpha as the previous tag and regenerate release notes that already shipped with v1.0.0. Pass '-c versionsort.suffix=-' to the git command so it treats any '-…' suffix as a prerelease that sorts before the corresponding stable. The query is otherwise unchanged. Co-authored-by: Codesmith <codesmith-bot@users.noreply.github.com>
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Replaces the manual
bump-tag.yamlwith aworkflow_dispatchrelease workflow modeled on the one inuseblacksmith/setup-docker-builder. A single dispatch creates an annotatedvX.Y.Ztag, force-updates the floating major tag (e.g.v1), and publishes a GitHub Release with auto-generated notes scoped to commits since the previous semver tag.How it works:
^v[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.]+)?$and bails if the tag already exists, so typos do not produce orphan releases.npm ci,npm run lint,npm run build, andnpm test(with the existing buf registry config and.nvmrc-pinned Node) before any tag is pushed, so a brokenmainnever lands in a release.update-majoris true, preserving the escape hatch the oldbump-tag.yamlprovided.gh release create --generate-notes [--notes-start-tag <previous>], with the previous tag selected fromgit tag -l 'v*.*.*' --sort=-version:refnameto avoid pulling inv1/v2major aliases.The workflow does not commit
dist/; the existing PR-time guard inbuild.yamlkeeps that artifact in sync via normal review. The legacy1.1.0tag (novprefix) is ignored by the version-tag glob, so the first run will diff release notes against the most recentvX.Y.Ztag.Need help on this PR? Tag
@codesmithwith what you need.Need help on this PR? Tag
@codesmithwith what you need.