Release Management skill for Claude Code

Version numbers that tell consumers the truth. Claude derives the next version from the actual changes rather than gut feel, cuts annotated tags that CI builds and publishes from, and picks fitting automation such as release-please, semantic-release, Changesets or git-cliff. Release branches and hotfixes follow a fix-on-main-then-cherry-pick flow, and every push or publish waits for your confirmation behind a pre- and post-release checklist.

  • namerelease-management
  • size202 lines · ≈2,200 tokens
  • files1
  • licenseMIT
  • updated

What Claude sees before loading it

This description is the only part of the skill that sits in context all the time. Claude reads it to decide when to load the full playbook below.

description: Cuts software releases with correct semantic version bumps, annotated tags, generated changelogs, release branches when needed, and hotfixes that land on both the release line and main. Covers release-please, semantic-release, Changesets, git-cliff, npm version, gh release, and a pre- and post-release checklist. Use when the user asks to cut or tag a release, decide the next version number, set up automated releases, create a release branch, ship a hotfix or backport, or write a release checklist.

Try asking

  • Cut the next release — figure out whether it's a minor or major
  • Set up release-please so merges to main produce release PRs
  • We need a hotfix for 2.5.0 that's already in production

Use it when

  • You need to decide the next version number from recent changes
  • A release needs tagging, publishing, and a GitHub release
  • You want automated release PRs or changelogs from commits
  • An old release line needs a hotfix or backport

Skip it when

How to check the result

The tag points at the commit CI tested, the registry lists the new version, and a clean install of the published artifact passes a smoke test.

The common mistake it prevents

Deleting and re-pushing a tag to fix a bad release, which breaks everyone who already fetched it; publish a new patch version instead.

~/.claude/skills/release-management/SKILL.md

--- name: release-management description: Cuts software releases with correct semantic version bumps, annotated tags, generated changelogs, release branches when needed, and… license: MIT ---

A release is done when the version number tells consumers the truth about compatibility, the tag points at exactly the commit that was built and tested, the artifacts and changelog are published from that tag, and you know how to roll back. Releases should be boring and repeatable; anything done by hand twice belongs in a script.

Ground rules

  • The tag is the source of truth. Build and publish artifacts from the tagged commit in CI, never from a laptop’s working tree.
  • Never move or delete a pushed tag. If a release is bad, ship a new patch version.
  • Choose the bump from the actual changes (commits, changesets, API diff), not from how big the release feels.
  • Pushing tags, publishing packages, and deploying to production require explicit user confirmation in the session. Prepare everything, show the plan, then ask.
  • Match the repo’s existing process before introducing tooling. Check for release-please-config.json, .releaserc*, .changeset/, cliff.toml, release workflows in .github/workflows/.

Choosing the version (SemVer 2.0.0)

Change since last releaseBumpExample
Removed/renamed public API, changed behavior callers rely on, raised minimum runtimeMAJOR2.4.1 -> 3.0.0
New backward-compatible feature, new optional parameter, deprecation noticeMINOR2.4.1 -> 2.5.0
Backward-compatible bug fix, performance, docs, internal refactorPATCH2.4.1 -> 2.4.2
Pre-release for testingpre-release suffix3.0.0-rc.1, 3.0.0-beta.2
  • 0.y.z: anything may change; by convention breaking changes bump minor (0.4 -> 0.5). Move to 1.0.0 once people depend on it in production.
  • “Public API” includes CLI flags, config file keys, env vars, HTTP endpoints, event schemas, and DB schemas others read, not just exported functions.
  • Applications deployed continuously (not consumed as libraries) may use date or build versions instead; still tag every deploy.
  • Pre-release ordering: 1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-beta < 1.0.0-rc.1 < 1.0.0.

Find what changed:

git describe --tags --abbrev=0                       # last tag
git log --oneline $(git describe --tags --abbrev=0)..HEAD
git log --format='%s' v2.4.1..HEAD | grep -E '^(feat|fix|perf)(\(.+\))?!?:|BREAKING'

Workflow: standard release

- [ ] 1. Confirm main is green and contains everything intended
- [ ] 2. Determine the version from changes
- [ ] 3. Generate and edit the changelog
- [ ] 4. Bump version files; commit "chore(release): vX.Y.Z"
- [ ] 5. Create an annotated tag on that commit
- [ ] 6. (Confirm with user) push commit and tag
- [ ] 7. CI builds, publishes, and creates the GitHub release from the tag
- [ ] 8. Post-release verification and announcement

Manual path with common tools:

git switch main && git pull --ff-only
npm version minor -m "chore(release): v%s"     # bumps package.json, commits, tags v2.5.0
# or, non-npm projects:
git cliff --bump -o CHANGELOG.md               # infer next version from conventional commits
git cliff --bumped-version                     # print the version it would choose
git commit -am "chore(release): v2.5.0"
git tag -a v2.5.0 -m "v2.5.0"
# after user confirmation:
git push origin main --follow-tags             # --follow-tags pushes annotated tags only
gh release create v2.5.0 --verify-tag --notes-file RELEASE_NOTES.md
gh release create v2.5.0 --verify-tag --generate-notes    # GitHub-generated notes

Python with uv: uv version --bump minor updates pyproject.toml. Rust: cargo set-version (cargo-edit) or cargo release (cargo-release) if installed.

Choosing automation

SituationTool
Single package or polyrepo, conventional commits, want a reviewable release PRrelease-please (googleapis/release-please-action@v4)
Fully automated publish on every merge to main, conventional commitssemantic-release
JS/TS monorepo, contributors describe changes explicitly per PRChangesets (npx changeset, changeset version, changeset publish)
Any language, just need changelog + next version from commitsgit-cliff
Apps deployed continuouslyTag per deploy from CI; changelog optional

Default recommendation: release-please for most repos (a human merges the release PR, so no surprise publishes), Changesets for JS monorepos.

release-please minimal setup:

# .github/workflows/release-please.yml
on:
  push:
    branches: [main]
permissions:
  contents: write
  pull-requests: write
jobs:
  release-please:
    runs-on: ubuntu-latest
    steps:
      - uses: googleapis/release-please-action@v4
        with:
          release-type: node     # or python, go, rust, simple

Publish jobs then run on the release.published event or on tag push, using OIDC trusted publishing (npm, PyPI) instead of long-lived tokens where supported.

Release branches

Use them only when you must support more than one line at once (customers on 2.x while main moves to 3.x) or need a stabilization period. Otherwise release from main.

git switch -c release/2.x v2.5.0       # create from the last 2.x tag
git push -u origin release/2.x         # after confirmation
  • Fixes land on main first, then are cherry-picked to release branches (-x records the origin), unless the bug exists only on the old line.
  • Tag patch releases on the release branch: v2.5.1.
  • Document which lines are supported and until when (SECURITY.md or README).

Hotfix workflow

- [ ] 1. Reproduce on the released version (check out the tag)
- [ ] 2. Write the fix + regression test on a branch from main (or the release branch if main diverged)
- [ ] 3. Review and merge
- [ ] 4. Cherry-pick to release/X.Y if it exists: git cherry-pick -x <sha>
- [ ] 5. Bump PATCH only; changelog entry names the bug
- [ ] 6. Tag, (confirm) push, publish
- [ ] 7. Verify in production; confirm main also has the fix
git switch -c hotfix/2.5.1 v2.5.0
git cherry-pick -x <fix-sha-from-main>
npm version patch -m "chore(release): v%s"

A hotfix contains the fix and nothing else, even if main has other ready changes.

Release checklist

Pre-release:

  • CI green on the exact commit to be tagged
  • Version bump matches changes (breaking changes -> major, with migration notes)
  • Changelog reviewed by a human: user-facing language, breaking changes first
  • Database migrations backward compatible with the previous version (rollback safe)
  • Feature flags for risky features default off
  • Dependencies: no pre-release or git-URL dependencies in a stable release
  • Docs and upgrade guide updated for new or changed behavior

Post-release:

  • Artifacts exist and install: npm view <pkg>@2.5.0 version, pip index versions <pkg>, container tag pulls
  • Smoke test the published artifact in a clean environment, not the build workspace
  • Error rates and key metrics normal after deploy (watch at least one traffic cycle)
  • Release announced where consumers look (GitHub release, changelog page, channel)
  • Milestone/issues closed; next development cycle opened if the repo uses -dev versions

Rollback

  • Libraries: you cannot unpublish safely in most registries (npm restricts unpublish; PyPI files cannot be re-uploaded with the same version). Deprecate the bad version (npm deprecate <pkg>@2.5.0 "broken, use 2.5.1", yank on PyPI/crates.io) and ship a fixed patch.
  • Applications: redeploy the previous tag’s artifact; database migrations must allow it. Write the rollback command in the release notes before deploying.

Gotchas

  • Lightweight tags (git tag v1.0.0 without -a) lack author/date/message and are not pushed by --follow-tags; use annotated (or signed -s) tags.
  • Tag naming must be consistent (v1.2.3 vs 1.2.3); tools and Go modules expect the v prefix. Monorepos use [email protected] or pkg-v1.2.3 per tool convention.
  • Squash-merge rewrites conventional commit messages to the PR title; enforce the convention on PR titles or automated bumps will be wrong.
  • GITHUB_TOKEN-created tags and releases do not trigger other workflows; use a GitHub App token or chain jobs in the same workflow.
  • Publishing from a dirty tree or unpushed commit produces artifacts nobody can rebuild.
  • A “minor” release that bumps the minimum Node/Python version is a breaking change for consumers on the old runtime.

Verification

  • git show v2.5.0 points at the commit CI tested; git describe --exact-match on the build commit returns the tag.
  • Registry/version listing shows the new version; a clean install of it passes a smoke test.
  • Changelog lists every user-facing change since the previous tag, breaking changes first.

About this skill

Written and maintained by the Claude Skills editors to the same editorial standard as every skill in the directory: a selective trigger, a real workflow, known pitfalls and a verification step. First published , last updated . MIT licensed.

esc