Release Skills
Universal release workflow supporting any project type with multi-language changelog.
User Input Tools
When this skill prompts the user, follow this tool-selection rule (priority order):
- Prefer built-in user-input tools exposed by the current agent runtime — e.g.,
AskUserQuestion,request_user_input,clarify,ask_user, or any equivalent. - Fallback: if no such tool exists, emit a numbered plain-text message and ask the user to reply with the chosen number/answer for each question.
- Batching: if the tool supports multiple questions per call, combine all applicable questions into a single call; if only single-question, ask them one at a time in priority order.
Concrete AskUserQuestion references below are examples — substitute the local equivalent in other runtimes.
Quick Start
Just run /release-skills - auto-detects your project configuration.
Supported Projects
Options
Workflow
Step 1: Detect Project Configuration
- Check for
.releaserc.yml(optional config override)- If present, inspect whether it defines release hooks
- Auto-detect version file by scanning (priority order):
package.json(Node.js)pyproject.toml(Python)Cargo.toml(Rust)marketplace.jsonor.claude-plugin/marketplace.json(Claude Plugin)VERSIONorversion.txt(Generic)
- Scan for changelog files using glob patterns:
CHANGELOG*.mdHISTORY*.mdCHANGES*.md
- Identify language of each changelog by filename suffix
- Detect GitHub release support:
- Check whether
originpoints to GitHub - Check whether
ghis installed and authenticated - Check existing releases with
gh release list --limit 5when available
- Check whether
- Display detected configuration
Project Hook Contract:
If .releaserc.yml defines release.hooks, keep the release workflow generic and delegate project-specific packaging/publishing to those hooks.
Supported hooks:
Supported placeholders:
Execution rules:
- Keep the skill generic: do not hardcode registry/package-manager/project layout details into this SKILL.
- If
prepare_artifactexists, run it once per target before publish-related checks that need the final releasable target state. - Write release notes to a temp file and pass that file path to
publish_artifact; do not inline multiline changelog text into shell commands. - If hooks are absent, fall back to the default project-agnostic release workflow.
Language Detection Rules:
Changelog files follow the pattern CHANGELOG_{LANG}.md or CHANGELOG.{lang}.md, where {lang} / {LANG} is a language or region code.
Common language codes: zh (Chinese), ja (Japanese), ko (Korean), de (German), fr (French), es (Spanish).
Output Example:
Step 2: Analyze Changes Since Last Tag
Categorize by conventional commit types:
Breaking Change Detection:
- Commit message starts with
BREAKING CHANGE - Commit body/footer contains
BREAKING CHANGE: - Removed public APIs, renamed exports, changed interfaces
If breaking changes detected, warn user: "Breaking changes detected. Consider major version bump (--major flag)."
Step 3: Determine Version Bump
Rules (in priority order):
- User flag
--major/--minor/--patch→ Use specified - BREAKING CHANGE detected → Major bump (1.x.x → 2.0.0)
feat:commits present → Minor bump (1.2.x → 1.3.0)- Otherwise → Patch bump (1.2.3 → 1.2.4)
Display version change: 1.2.3 → 1.3.0
Step 4: Generate Multi-language Changelogs
For each detected changelog file:
- Identify language from filename suffix
- Detect third-party contributors:
- Check merge commits:
git log ${LAST_TAG}..HEAD --merges --pretty=format:"%H %s" - For each merged PR, identify the PR author via
gh pr view <number> --json author --jq '.author.login' - Compare against repo owner (
gh repo view --json owner --jq '.owner.login') - If PR author ≠ repo owner → third-party contributor
- Check merge commits:
- Generate content in that language:
- Section titles in target language
- Change descriptions written naturally in target language (not translated)
- Date format: YYYY-MM-DD (universal)
- Third-party contributions: Append contributor attribution
(by @username)to the changelog entry
- Insert at file head (preserve existing content)
Section Title Translations (built-in):
Changelog Format:
Only include sections that have changes. Omit empty sections.
Third-Party Attribution Rules:
- Only add
(by @username)for contributors who are NOT the repo owner - Use GitHub username with
@prefix - Place at the end of the changelog entry line
- Apply to all languages consistently (always use
(by @username)format, not translated)
Multi-language Example:
English (CHANGELOG.md):
Chinese (CHANGELOG.zh.md):
Japanese (CHANGELOG.ja.md):
Step 5: Group Changes by Skill/Module
Analyze commits since last tag and group by affected skill/module:
- Identify changed files per commit
- Group by skill/module:
skills/<skill-name>/*→ Group under that skill- Root files (CLAUDE.md, etc.) → Group as "project"
- Multiple skills in one commit → Split into multiple groups
- For each group, identify related README updates needed
Example Grouping:
Step 6: Commit Each Skill/Module Separately
For each skill/module group (in order of changes):
-
Check README updates needed:
- Scan
README*.mdfor mentions of this skill/module - Verify options/flags documented correctly
- Update usage examples if syntax changed
- Update feature descriptions if behavior changed
- Scan
-
Stage and commit:
-
Commit message format:
- Use conventional commit format:
<type>(<scope>): <description> <type>: feat, fix, refactor, docs, perf, etc.<scope>: skill name or "project"<description>: Clear, meaningful description of changes
- Use conventional commit format:
Example Commits:
Common README Updates Needed:
Step 7: Generate Changelog and Update Version
- Generate multi-language changelogs (as described in Step 4)
- Update version file:
- Read version file (JSON/TOML/text)
- Update version number
- Write back (preserve formatting)
- Create release notes file:
- Prefer the new version section from
CHANGELOG.md - If no English/default changelog exists, use the first detected changelog
- Extract only the exact
## {VERSION} - {YYYY-MM-DD}section through the next## - Match both plain version and tag-prefixed headings when needed, e.g.
1.2.3andv1.2.3 - Keep breaking changes near the top; if needed, add a short highlight before other sections
- Write notes to a UTF-8 temp file and reuse it for annotated tag messages, GitHub Releases, and
publish_artifact - In normal mode, stop rather than creating an empty tag or GitHub Release when notes cannot be found
- Prefer the new version section from
Version Paths by File Type:
Step 8: User Confirmation
Before creating the release commit, ask user to confirm:
Use AskUserQuestion with three questions:
-
Version bump (single select):
- Show recommended version based on Step 3 analysis
- Options: recommended (with label), other semver options
- Example:
1.2.3 → 1.3.0 (Recommended),1.2.3 → 1.2.4,1.2.3 → 2.0.0
-
Push to remote (single select):
- Options: "Yes, push after commit", "No, keep local only"
-
Publish GitHub Release (single select):
- Offer this only when GitHub release support is available
- Default to "Yes, publish after tag push" when the user also chose push
- If the user keeps the release local, do not create or edit a GitHub Release
Example Output Before Confirmation:
Step 9: Create Release Commit and Annotated Tag
After user confirmation:
-
Stage version and changelog files:
-
Create release commit:
-
Create annotated tag:
If
.releaserc.ymlsetstag.sign: true, usegit tag -swith the same notes file. -
Push if user confirmed (Step 8):
Note: Do NOT add Co-Authored-By line. This is a release commit, not a code contribution.
Step 10: Publish Release Artifacts and GitHub Release
Project artifact publishing and GitHub Releases are separate outputs:
-
Project artifacts:
- If
release.hooks.publish_artifactexists, run it once per prepared target - Pass the same
{release_notes_file}used for the tag and GitHub Release - In dry-run mode, pass
{dry_run}=trueand report what would be published
- If
-
GitHub Release:
- Run only if the user confirmed remote publishing and GitHub support is available
- Ensure the tag exists on the remote before creating the release
- Create or update using the extracted notes:
- Never inline multiline release notes into shell commands
Post-Release Output:
Backfill Existing GitHub Releases
Use this mode when the user asks to backfill historical releases or passes --backfill-releases.
- Do not bump versions, edit changelogs, or create release commits.
- List existing tags in version order and detect missing releases:
- For each tag without a GitHub Release:
- Normalize the changelog lookup by stripping the configured tag prefix, e.g.
v1.2.3->1.2.3 - Extract the matching section from
CHANGELOG.md; fall back to the first matching changelog file - Skip or ask before publishing if no matching changelog section exists
- Create the release with:
- Normalize the changelog lookup by stripping the configured tag prefix, e.g.
- Detect lightweight tags with
git cat-file -t <tag>(commitmeans lightweight,tagmeans annotated). - Do not rewrite public lightweight tags by default. Converting an existing remote tag to an annotated tag requires explicit user confirmation because it rewrites a published reference.
Configuration (.releaserc.yml)
Optional config file in project root to override defaults:
Dry-Run Mode
When --dry-run is specified:
Example Usage
When to Use
Trigger this skill when user requests:
- "release", "发布", "create release", "new version", "新版本"
- "bump version", "update version", "更新版本"
- "prepare release"
- "release notes", "GitHub Release", "回填 Release"
- "push to remote" (with uncommitted changes)
Important: If user says "just push" or "直接 push" with uncommitted changes, STILL follow all steps above first.


