feat(release): overhaul release process — manual dispatch with auto-bump suggestion#12
Merged
feat(release): overhaul release process — manual dispatch with auto-bump suggestion#12
Conversation
release.yml already fires on v*.*.* tag push to update the floating v1/v1.2 pointers; extend it to also publish a GitHub Release via `gh release create --generate-notes --verify-tag`, with an idempotent pre-check so re-runs (or manual tag re-pushes) don't error. Rename the workflow from "Update Floating Version Tags" to "Publish Release" — the file stays release.yml to preserve any external references, only the display name and job id change to reflect the broader responsibility. Also commit the design spec under docs/superpowers/specs/ documenting the rationale, failure modes, and the GitHub API limitation that prevents retroactive `published_at` timestamps on backfilled Releases.
…ump suggestion Two orthogonal-but-related changes landing together: 1. Replace merge-triggered tagging with operator-initiated dispatch. `auto-tag.yml` → `tag-release.yml`, trigger switches from `pull_request.closed` → `workflow_dispatch` with a `bump` choice input (auto/patch/minor/major, default auto). Merged PRs accumulate on main and ship in one coherent release when the operator decides, rather than one release per merge. The conventional-commit heuristic (feat → minor, BREAKING → major, else patch) is preserved — it now powers the `auto` default. Explicit picks override the heuristic; the step summary flags the override so mismatches are visible. Safety gates: `if: github.ref == 'refs/heads/main'` at job level, `concurrency.group: tag-release` with `cancel-in-progress: false`, explicit error + step summary when no commits exist since the last tag (no ghost releases). 2. Publish GitHub Release on every `v*.*.*` tag push. `release.yml` (display name renamed to "Publish Release") gains a final `gh release create --title --generate-notes --verify-tag` step, idempotent via a `gh release view` pre-check. Fires regardless of how the tag got there (tag-release.yml dispatch, manual push, backfill loop, future migrations). Backfill of the 7 pre-existing semver tags (v1.0.0 → v1.2.4) was executed out-of-band via a local `gh` loop — not committed as a workflow, since it's a one-time operation and a dedicated file would sit unused afterward. Design spec added at docs/superpowers/specs/2026-04-11-release-process-overhaul-design.md.
j7an
added a commit
that referenced
this pull request
Apr 12, 2026
feat(release): overhaul release process — manual dispatch with auto-bump suggestion
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.
Summary
Overhauls the release process so a release happens on an operator's cadence, not per-merge. Two related changes landing together:
auto-tag.yml→tag-release.yml— trigger switches from "every merged PR" toworkflow_dispatchwith abumpdropdown (auto | patch | minor | major, defaultauto). Merged PRs batch onmainuntil an operator clicks Run workflow.release.yml— gets a newPublish GitHub Releasestep that fires on everyv*.*.*tag push (idempotent viagh release viewpre-check). Also renames display name to Publish Release. Filename unchanged to preserve any external references.The conventional-commit heuristic (
feat:→ minor,BREAKING CHANGE→ major, else patch) is preserved — it powers theautodefault. Explicit picks override it; the step summary shows a warning when the override contradicts the analysis.Why
Release-per-merge was wasteful. A week of 4 dependabot PRs used to become 4 tags, 4 Releases, 4 floating-tag force-pushes. The semver contract (bumps are deliberate compatibility statements) got diluted into "every merge is a patch."
Empty Releases page (separate defect, same logical fix): 7 pre-existing semver tags had zero corresponding GitHub Releases. Backfilled out-of-band during implementation — all 7 Releases now live at https://github.com/j7an/shared-workflows/releases with original tag dates in titles and notes banners.
Design doc
docs/superpowers/specs/2026-04-11-release-process-overhaul-design.md— full design, failure modes, rationale for manual dispatch overrelease-please/semantic-release, and backfill approach.Files changed
.github/workflows/auto-tag.yml→.github/workflows/tag-release.yml— renamed and rewritten (content similarity <50% so git shows delete+add).github/workflows/release.yml— new Publish GitHub Release step, display name renamed to "Publish Release"docs/superpowers/specs/2026-04-11-release-process-overhaul-design.md— new design specSafety gates in
tag-release.ymlif: github.ref == 'refs/heads/main'at job level — refuses to run from non-main branches (workflow_dispatch lets the operator pick any branch)concurrency.group: tag-releasewithcancel-in-progress: false— serializes parallel dispatches instead of killing in-flight ones (a half-cancelled tag-push is worse than a queued second dispatch)permissions: contents: write— minimum scope for tag pushTest plan
v1.2.4..HEADon this branch — correctly pickedminorfrom thefeat(release):commitv1.0.0→v1.2.4) via localghloop;v1.2.4correctly got the "Latest" badge from GitHub's semver orderingbump=auto→ Runv1.3.0(minor, driven by this PR'sfeat:commit)release.ymlshould fire automatically on the tag pushv1.3.0Release should appear on the Releases page with auto-generated notesv1andv1.2tags should force-push tov1.3.0auto-tag.ymlno longer appears in.github/workflows/and noAuto-Tag on Mergeruns are scheduledRollback plan
If the new flow misbehaves:
git revertthis PR's merge commit onmaingit push origin :v1.3.0(or whatever tag was created)gh release delete v1.3.0Everything is reversible in under a minute.