| name | dev-release |
| description | Cut a release โ derive the version bump from conventional commits since the last tag, generate a changelog, bump version files, tag, publish a GitHub release. Use on "release", "cut a release", "ship it", "tag a version", "bump the version", "publish a release", "generate a changelog". |
| argument-hint | [lite|full|ultra] |
Release
Turn merged work into a versioned, tagged, published release. Audit first โ never tag or push without showing the user what's about to ship.
Delivery Mode (lite | full | ultra, default lite)
Mode is the trailing argument when it is exactly lite, full, or ultra; everything else is the task/feature description. No mode given โ lite.
lite (default) โ tag + GitHub release with notes generated from commits. No file changes.
full โ also update CHANGELOG.md and bump version files, committed before tagging.
ultra โ full, but publish as a pre-release (vX.Y.Z-rc.1) first; promote to final on user confirmation.
1. Pre-flight
All must hold before anything else:
git branch --show-current
git status --porcelain
git fetch origin && git status -sb
gh run list --branch main --limit 1 --json conclusion
Any failure โ stop and report. Releasing a red or stale main ships broken code with a version number on it.
2. Detect Existing Release Automation
Before doing anything by hand, find out what the repo already automates:
ls .github/workflows/ 2>/dev/null
grep -rlE "tags:|goreleaser|semantic-release|release-please|changesets|npm publish|cargo publish|gh release" .github/workflows/ 2>/dev/null
ls .goreleaser.yml .goreleaser.yaml .releaserc* release-please-config.json .changeset 2>/dev/null
Adapt to what exists โ duplicating automation produces double releases or conflicting tags:
- Release-manager tool (
release-please, semantic-release, changesets) โ it owns versioning and changelogs. Do not hand-tag. Follow its flow instead: merge its release PR, or run its command (npx changeset version, etc.), then verify the release appeared.
- Tag-triggered workflow (
on: push: tags, goreleaser, publish steps) โ the tag is the trigger. Push the tag but skip gh release create (CI does it); watch with gh run watch and report the workflow's release/artifacts.
- Release-triggered workflow (
on: release) โ gh release create is the trigger; proceed as written below, then watch the run.
- Nothing found โ proceed manually as written below.
Read the matched workflow before deciding โ a workflow that only runs tests on tags changes nothing.
3. Derive the Version
git describe --tags --abbrev=0 2>/dev/null
git log <last-tag>..HEAD --oneline
Bump from conventional commit types since the last tag: any ! suffix or BREAKING CHANGE โ major ยท any feat: โ minor ยท else (fix:, perf:, refactor:, โฆ) โ patch. Pre-1.0: breaking โ minor, everything else โ patch. No releasable commits (only docs:/chore:) โ say so and stop; don't tag noise.
If the user named a version, use it โ but flag if it disagrees with the derived bump.
4. Changelog
Group the <last-tag>..HEAD subjects: Breaking / Features (feat:) / Fixes (fix:) / Performance (perf:) โ drop chore:/docs:/ci: noise and merge commits. One line per change, PR/issue refs kept (#42).
full/ultra: prepend to CHANGELOG.md under ## vX.Y.Z โ YYYY-MM-DD (create the file if missing, Keep a Changelog shape).
5. Bump Version Files (full/ultra only)
Detect and update whichever exist: package.json (npm version --no-git-tag-version X.Y.Z), Cargo.toml, pyproject.toml, VERSION. None found โ skip, note it.
Commit hygiene and message style: see the git-safe skill (no Co-authored-by:, git add -u not -A, imperative why-focused subject).
git add CHANGELOG.md <version files> && git commit -m "chore: release vX.Y.Z"
6. Confirm, Tag, Publish
Pause for approval โ show version, bump reasoning, and the changelog; tags and releases are public and painful to retract. On approval:
git push origin main
git tag -a vX.Y.Z -m "vX.Y.Z"
git push origin vX.Y.Z
gh release create vX.Y.Z --title "vX.Y.Z" --notes "<changelog section>"
Per ยง2: skip gh release create when a tag-triggered workflow publishes the release; skip tagging entirely when a release-manager tool owns it. After publishing, if any workflow fired: gh run watch โ a release whose pipeline failed isn't released. No release automation exists and the project should have some? That's github-actions' job, in its own PR โ not something to bolt on mid-release.
ultra: tag vX.Y.Z-rc.1 and gh release create --prerelease instead; on user confirmation ("promote"), repeat with the final tag and mark the release latest.
No remote / no gh โ create the local tag, print the changelog, tell the user what to push.
7. Report
Version (and previous) ยท bump reason (the commit types that drove it) ยท commit count ยท release URL ยท automation found and how it was used (or "none โ manual release") ยท CI run result ยท anything skipped (no version files, no CI). If pre-release: how to promote.