Voicebox release-bump
Use this skill to finalize a release. It stamps the [Unreleased] changelog section with a version and date, runs bumpversion to update all version files, and creates the release commit and tag. Only run this when you're ready to ship.
git clone https://github.com/jamiepine/voicebox
T=$(mktemp -d) && git clone --depth=1 https://github.com/jamiepine/voicebox "$T" && mkdir -p ~/.claude/skills && cp -r "$T/.agents/skills/release-bump" ~/.claude/skills/jamiepine-voicebox-release-bump && rm -rf "$T"
.agents/skills/release-bump/SKILL.mdRelease Bump
Goal
Finalize the changelog draft, bump the version across all tracked files, and create a tagged release commit. After this skill runs, the repo has a clean release commit and tag ready to push.
Prerequisites
CLI installed and authenticated (gh
).gh auth status
installed (bumpversion
or available in the project venv).pip install bumpversion- The
section of[Unreleased]
should already contain the release narrative. If it's empty or stale, run theCHANGELOG.md
skill first.draft-release-notes
Workflow
-
Verify the working tree is clean (except
which may have the draft).CHANGELOG.mdgit status --porcelainOnly
(and optionallyCHANGELOG.md
files) should be modified. If there are other uncommitted changes, stop and ask the user to commit or stash them first..agents/ -
Determine the bump level.
Ask the user if not specified:
,patch
, orminor
. Check the current version:majorgrep '^current_version' .bumpversion.cfg -
Stamp the changelog.
Read the current
content from[Unreleased]
. Compute the new version (based on bump level and current version). Then:CHANGELOG.mda. Replace the
section body with an empty placeholder. b. Insert a new stamped section immediately after## [Unreleased]
:## [Unreleased]## [Unreleased] ## [X.Y.Z] - YYYY-MM-DD <the content that was in [Unreleased]>c. Update the reference links at the bottom of the file:
- Change the
link to compare against the new tag[Unreleased] - Add a new link for the new version
[Unreleased]: https://github.com/jamiepine/voicebox/compare/vX.Y.Z...HEAD [X.Y.Z]: https://github.com/jamiepine/voicebox/compare/vPREVIOUS...vX.Y.Z - Change the
-
Stage the changelog.
git add CHANGELOG.md -
Run bumpversion.
bumpversion --allow-dirty <patch|minor|major>The
flag is needed because--allow-dirty
is already staged. bumpversion will:CHANGELOG.md- Update version strings in all tracked files (see
).bumpversion.cfg - Create a commit with message
Bump version: X.Y.Z -> A.B.C - Create a tag
vA.B.C
The staged
will be included in this commit automatically.CHANGELOG.md - Update version strings in all tracked files (see
-
Verify results.
git show --name-only --stat HEAD git tag --list "v*" --sort=-v:refname | head -n 5Confirm the commit contains:
CHANGELOG.md.bumpversion.cfgtauri/src-tauri/tauri.conf.jsontauri/src-tauri/Cargo.tomlpackage.jsonapp/package.jsontauri/package.jsonlanding/package.jsonweb/package.jsonbackend/__init__.py
Confirm the new tag exists.
-
Do NOT push unless the user explicitly asks. Report the tag name and suggest:
Ready to push. When you're ready: git push origin main --follow-tags
Version Calculation Reference
Given current version
X.Y.Z:
->patchX.Y.(Z+1)
->minorX.(Y+1).0
->major(X+1).0.0
Error Recovery
- If bumpversion fails, the tag won't exist. Fix the issue and re-run — bumpversion is idempotent as long as the tag doesn't already exist.
- If you need to undo a release commit (before pushing):
git tag -d vX.Y.Z && git reset --soft HEAD~1 - Never amend a release commit that has been pushed.
Notes
- When the tag is pushed, the release CI (
) automatically extracts the matching version section from.github/workflows/release.yml
and uses it as the GitHub Release body. No manual copy-paste needed.CHANGELOG.md - The release commit message is controlled by
(.bumpversion.cfg
). Do not override it.Bump version: X.Y.Z -> A.B.C - If you need to manually update the GitHub Release body after the fact:
gh release edit vX.Y.Z --notes-file <(sed -n '/## \[X.Y.Z\]/,/## \[/p' CHANGELOG.md | head -n -1)