Release Skill
Manage releases: version bumping, changelog generation, release notes, git tagging, and full publish workflow.
<user-input>$ARGUMENTS</user-input> <current-command>release</current-command>
Action Detection
Parse $ARGUMENTS to determine action:
- •If
$ARGUMENTSprovided → Parse for action keyword - •If no arguments → Default to "status"
Actions:
- •
status(default) → Show release status - •
bump [level]→ Bump version (major/minor/patch, default: patch) - •
changelog→ Generate/update CHANGELOG.md - •
notes→ Show release notes for current version - •
tag→ Create git tag for current version - •
publish [level]→ Full release workflow
Set action and action_args based on parsed arguments.
Action: status
Show current release state.
Implementation
- •
Read version from plugin.json:
bashgrep '"version"' plugins/do/.claude-plugin/plugin.json | head -1 | sed 's/.*: *"\([^"]*\)".*/\1/'
- •
Get last git tag:
bashgit describe --tags --abbrev=0 2>/dev/null || echo "none"
- •
Count commits since tag:
bash# If tag exists: git rev-list <tag>..HEAD --count # If no tag: git rev-list HEAD --count
- •
Check for uncommitted changes:
bashgit status --porcelain
- •
Get all plugin versions:
- •Read plugins/do/.claude-plugin/plugin.json
- •Read plugins/do-more/.claude-plugin/plugin.json
- •Read plugins/do-extra/.claude-plugin/plugin.json (if exists)
Output
Display formatted status:
═══════════════════════════════════════ Release Status Current Version: 0.5.21 Last Tag: v0.5.20 (or "none" if no tags) Commits Since Tag: 15 Uncommitted Changes: [yes/no] Plugins: - do: 0.5.21 - do-more: 0.5.21 - do-extra: 0.5.15 (if exists) Next: /do:release bump | changelog | publish ═══════════════════════════════════════
Action: bump [level]
Increment version using semantic versioning.
Implementation
- •
Parse level from action_args:
- •"major" → Increment major, reset minor and patch to 0
- •"minor" → Increment minor, reset patch to 0
- •"patch" or empty → Increment patch (default)
- •
Bump version:
- •For patch: Delegate to
just bump(existing behavior) - •For minor or major: Manually update version:
- •Read current version from
plugins/do/.claude-plugin/plugin.json - •Parse: MAJOR.MINOR.PATCH
- •Calculate new version based on level
- •Update version in plugin.json files using
just bump-pluginapproach - •Update
.claude-plugin/marketplace.json
- •Read current version from
- •For patch: Delegate to
- •
Display result
Output
═══════════════════════════════════════ Version Bump Previous: 0.5.21 New: 0.6.0 (minor) Updated: - plugins/do/.claude-plugin/plugin.json - plugins/do-more/.claude-plugin/plugin.json - .claude-plugin/marketplace.json Next: /do:release changelog | tag | publish ═══════════════════════════════════════
Error Cases
- •Invalid level → "Invalid level: must be major, minor, or patch"
Action: changelog
Generate or update CHANGELOG.md from git commits.
Implementation
- •
Get commits since last tag:
bash# If tag exists: git log <tag>..HEAD --oneline --no-merges # If no tag: git log --oneline --no-merges
- •
Parse and group commits:
- •Scan commit messages for conventional commit prefixes
- •Group by type:
- •
feat:,add:→ Added - •
fix:,bug:→ Fixed - •
change:,update:,refactor:→ Changed - •Others → Other
- •
- •Strip prefix and clean up message
- •
Read existing CHANGELOG.md (if exists)
- •
Generate new section:
- •Current version from plugin.json
- •Current date (YYYY-MM-DD)
- •Grouped changes
- •
Write CHANGELOG.md:
- •If file exists: Prepend new section
- •If file doesn't exist: Create with header + new section
CHANGELOG.md Format
Follow Keep a Changelog format:
# Changelog All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [0.5.22] - 2026-01-19 ### Added - New feature X - New feature Y ### Changed - Updated Z ### Fixed - Bug fix A ## [0.5.21] - 2026-01-18 ...
Output
═══════════════════════════════════════ Changelog Updated Version: 0.5.22 Commits Processed: 15 Added: 3 entries Changed: 5 entries Fixed: 2 entries Other: 5 entries File: CHANGELOG.md Next: /do:release notes | tag | publish ═══════════════════════════════════════
Error Cases
- •No commits since tag → "No commits since last release. Nothing to add to changelog."
- •Git error → Display git error message
Action: notes
Display release notes for current version.
Implementation
- •
Read current version from plugin.json
- •
Extract section from CHANGELOG.md:
- •If CHANGELOG.md exists:
- •Find section with
## [version] - •Extract everything until next
## [or EOF
- •Find section with
- •If CHANGELOG.md doesn't exist:
- •Generate from commits (same logic as changelog action)
- •Don't save to file
- •If CHANGELOG.md exists:
- •
Format for display
Output
═══════════════════════════════════════ Release Notes: v0.5.22 ### Added - New feature X - New feature Y ### Changed - Updated Z implementation ### Fixed - Bug fix A - Bug fix B ═══════════════════════════════════════
Error Cases
- •No CHANGELOG.md and no commits → "No release notes available. Run /do:release changelog first."
Action: tag
Create git tag for current version.
Implementation
- •
Read current version from plugin.json
- •
Check if tag exists:
bashgit tag -l "v<version>"
- •
If tag exists → Error with instructions
- •
Create annotated tag:
- •Tag name:
v<version>(e.g.,v0.5.22) - •Tag message:
Release v<version>
bashgit tag -a v<version> -m "Release v<version>"
- •Tag name:
- •
Display success
Output
═══════════════════════════════════════
Git Tag Created
Tag: v0.5.22
Type: Annotated
Message: "Release v0.5.22"
Next: git push origin v0.5.22
(or use /do:release publish to automate)
═══════════════════════════════════════
Error Cases
- •Tag already exists → "Tag v0.5.22 already exists. Delete with: git tag -d v0.5.22"
- •Git error → Display git error message
Action: publish [level]
Full release workflow - orchestrates all actions.
Implementation
Steps:
- •
Validate:
- •Run
just validate - •If fails: Abort with error details
- •Run
- •
Check state:
- •Check for uncommitted changes
- •If yes: Display warning and prompt for confirmation
- •If user declines: Abort
- •
Bump version:
- •Run
bumpaction with specified level (from action_args) - •Default: patch
- •Run
- •
Generate changelog:
- •Run
changelogaction
- •Run
- •
Commit changes:
bashgit add -A git commit -m "Release v<version>"
- •
Create tag:
- •Run
tagaction
- •Run
- •
Display summary:
- •Show completion status
- •Show push commands
Output
═══════════════════════════════════════
Release Complete: v0.5.22
✓ Validation passed
✓ Version bumped: 0.5.21 → 0.5.22 (patch)
✓ Changelog updated
✓ Changes committed
✓ Tag created: v0.5.22
Push to remote:
git push origin master
git push origin v0.5.22
═══════════════════════════════════════
Error Cases
| Condition | Response |
|---|---|
| Validation fails | Abort with error details |
| Tag exists | Error with delete instructions |
| No commits since tag | "Nothing to release. No commits since last tag." |
| Uncommitted changes | Warning, prompt for confirmation |
| Git error | Display error and rollback instructions |
Error Handling Summary
| Error Type | Action | Response |
|---|---|---|
| Validation failure | All | Abort with details |
| Tag exists | tag, publish | Error + delete instructions |
| No commits | changelog, publish | "Nothing to release" |
| Uncommitted changes | publish | Warning + confirmation |
| Invalid level | bump | Error with valid options |
| Git error | All | Display error message |
Dependencies
- •
just validate- Plugin validation (must pass) - •
just bump- Existing patch bump (delegates for patch level) - •Git commands - For commits, tags, logs
- •plugin.json files - Source of truth for versions
Notes
- •Version source of truth:
plugins/*/. claude-plugin/plugin.json - •Marketplace sync:
.claude-plugin/marketplace.jsonis updated in sync - •Tag format:
v{version}(e.g.,v0.5.22) - •Changelog format: Keep a Changelog standard
- •Commit message:
Release v{version}for publish workflow