SKILL.md
Release Skill
Unified entry point for all release operations. Delegates to the right subcommand template based on the first argument.
Subcommands
| Command |
What it does |
/release plan |
Scope version, analyze milestones/issues/tags, create GitHub milestone |
| `/release verify [commits\ |
tags\ |
history]` |
Integrity checks: commit↔CHANGELOG, tag↔releases↔artifacts, history audit |
/release changelog |
Generate CHANGELOG entries + version bump propagation across manifest files |
/release full |
Full orchestrator: plan → health → fix blockers → docs → tag+ship |
/release |
Auto-detect what's needed (see below) |
Auto-Detection (no subcommand)
LAST_TAG=$(git describe --tags --abbrev=0 --match "v*" 2>/dev/null)
UNRELEASED=$(git log --no-merges --oneline "${LAST_TAG:-$(git rev-list --max-parents=0 HEAD)}..HEAD" | wc -l)
OPEN_MILESTONE=$(gh api "repos/$(gh repo view --json nameWithOwner --jq '.nameWithOwner')/milestones" \
--jq '[.[] | select(.state=="open")] | length' 2>/dev/null || echo 0)
CLOSED_ISSUES=$(gh api "repos/$(gh repo view --json nameWithOwner --jq '.nameWithOwner')/milestones" \
--jq '[.[] | select(.state=="open" and .open_issues==0)] | length' 2>/dev/null || echo 0)
Decision tree:
- Milestone exists with 0 open issues → suggest
/release full
- Unreleased commits > 0, no milestone → suggest
/release plan
- Clean main, recent tag → suggest
/release verify tags
- Default → show the subcommand table above and ask what's needed
Execution
Load the template matching the subcommand and follow it completely:
plan → ~/.claude/skills/release/templates/plan.md
verify → ~/.claude/skills/release/templates/verify.md
changelog → ~/.claude/skills/release/templates/changelog.md
full → ~/.claude/skills/release/templates/cycle.md
Pass any additional args through:
/release verify commits → load verify.md, execute the commits subcommand
/release verify tags → load verify.md, execute the tags subcommand
/release verify history → load verify.md, execute the history subcommand
Gotchas
- Auto-detection commands fail soft (
|| echo 0) when gh is unauthenticated or there's no GitHub remote — a 0 open-milestone count may mean "no GitHub access", not "no milestones"; verify before trusting the decision tree.
git describe --tags --match "v*" only finds tags reachable from HEAD — a tag on a sibling branch is invisible, so "no last tag" can be a false negative.
/release changelog propagates the version bump across manifest files (pyproject.toml, package.json, etc.) — verify all manifests moved together; a partial bump ships mismatched versions.
/release full tags and ships — it is not a dry run. Run /release plan first to confirm scope.