semver-release
Versioning Workflow
Automated version release based on Semantic Versioning 2.0.0.
Execution Steps
Step 0: Pre-flight Checks
- Verify inside a git repository:
git rev-parse --is-inside-work-tree - Check working directory is clean:
git status --porcelain- Abort if uncommitted changes exist → prompt user to commit or stash first
- Detect current branch:
git branch --show-current- Store for use in Step 8 completion message
Step 1: Project Configuration Detection
1a: Detect Version Files
Scan the project root for version files. Check these common files first:
| File | Ecosystem |
|---|---|
package.json |
Node.js |
pyproject.toml |
Python |
Cargo.toml |
Rust |
pubspec.yaml |
Dart / Flutter |
VERSION |
Universal |
Also check for: pom.xml, build.gradle(.kts), *.gemspec, setup.py, setup.cfg, *.csproj, CMakeLists.txt.
For complete extraction and update patterns for each file type, see references/version-files.md.
If no version files are found, ask the user which file contains the version, or skip version file updates.
If multiple version files are found, all will be updated to maintain consistency.
1b: Discover CHANGELOG Files
Detect CHANGELOG files in the project root:
- Check if
CHANGELOG.mdexists — mark as primary (do NOT create yet; defer to Step 7) - Glob for
CHANGELOG-*.mdandCHANGELOG.*.mdto discover multilingual variants
Examples: CHANGELOG.zh-CN.md, CHANGELOG-ja.md, CHANGELOG.fr.md
All discovered CHANGELOG files will be updated.
Step 2: Get Last Version Tag
2a: Find Latest Semver Tag
Find the latest semver tag reachable from HEAD:
git tag -l 'v[0-9]*.[0-9]*.[0-9]*' --sort=-v:refname | head -1
This filters for vMAJOR.MINOR.PATCH pattern only, ignoring non-version tags (e.g. deploy-prod, build-123).
If no matching tags exist, also try without v prefix:
git tag -l '[0-9]*.[0-9]*.[0-9]*' --sort=-v:refname | head -1
Use v0.0.0 as baseline if no semver tags exist at all.
2b: Version Consistency Check
Compare the version from the latest git tag with versions found in version files (Step 1a).
- If consistent → proceed with tag version as baseline
- If mismatch → report discrepancy to user:
Ask user which version to use as the baseline. Do not proceed silently.Version mismatch detected: - Git tag: v1.2.0 - package.json: 1.3.0
Step 3: Analyze Commit History
Use the latest tag obtained in Step 2a as the range start:
git log v1.2.3..HEAD --pretty=format:"---commit---%n%s%n%b"
Parse both subject and body of each commit to identify type:
| Pattern | Location | Type | Version Impact |
|---|---|---|---|
BREAKING CHANGE: in body/footer |
body | breaking | MAJOR |
type(scope)!: (exclamation before colon) |
subject | breaking | MAJOR |
feat: / feat(scope): / ✨ feat: |
subject | feat | MINOR |
fix: / fix(scope): / 🐛 fix: |
subject | fix | PATCH |
perf: / perf(scope): / ⚡️ perf: |
subject | perf | PATCH |
refactor: / refactor(scope): / ♻️ refactor: |
subject | refactor | PATCH |
docs: / 📝 docs: |
subject | docs | none |
chore: / 🔧 chore: / ⬆️ deps: |
subject | chore | none |
If no commits found → inform user there are no changes since the last release. Ask whether to abort or force a release.
Step 4: Calculate New Version
User override: If $ARGUMENTS is a valid semver version (e.g. 1.0.0, 2.0.0-rc.1), use that version directly. Skip automatic calculation.
Based on current version MAJOR.MINOR.PATCH:
When MAJOR ≥ 1 (stable API):
- Has breaking →
(MAJOR+1).0.0 - Has feat →
MAJOR.(MINOR+1).0 - Has fix/perf/refactor →
MAJOR.MINOR.(PATCH+1) - Only docs/chore → Ask user whether to force patch release
When MAJOR = 0 (unstable / initial development):
- Has breaking →
0.(MINOR+1).0(not 1.0.0) - Has feat →
0.MINOR.(PATCH+1) - Has fix/perf/refactor →
0.MINOR.(PATCH+1) - Only docs/chore → Ask user whether to force patch release
- Note: Ask user "Do you want to promote to 1.0.0?" if breaking changes detected
Pre-release versions (e.g. 1.0.0-rc.1) are only created via explicit user override.
Step 5: Generate CHANGELOG Content
Read [Unreleased] section from each detected CHANGELOG file.
Merge git analysis with existing [Unreleased] content:
- Check for missing changes from git commits
- Deduplicate by semantic meaning
- Add missing changes to appropriate categories
Organize by category (include only non-empty categories):
### Added
- ✨ New feature
### Changed
- ♻️ Refactor/improvement
- ⚡️ Performance optimization
- ⚠️ 💥 Breaking change
### Deprecated
- Deprecated feature
### Removed
- 🗑️ Removed feature
### Fixed
- 🐛 Bug fix
### Security
- 🔒️ Security fix
For complete category mapping and translation rules, see references/changelog-categories.md.
Scope handling: If commits include scopes (e.g. feat(auth):), include the scope as context in the CHANGELOG entry where it aids readability:
feat(auth): add OAuth login→✨ **auth**: Add OAuth login- If scope adds no value (e.g. generic scope), omit it.
Translation rules for multilingual CHANGELOGs:
- Emoji prefixes — identical across all languages
- Category headings — keep in English (
### Added, etc.) - Entry descriptions — translate to the target language
- Technical terms and proper nouns — preserve as-is
Step 6: Interactive Preview
Show user all planned changes:
## Release Preview
Current version: v1.5.1
New version: v1.6.0
### Version Files to Update
- package.json: 1.5.1 → 1.6.0
- pyproject.toml: 1.5.1 → 1.6.0
### CHANGELOG Files to Update
- CHANGELOG.md (English)
- CHANGELOG.zh-CN.md (Chinese)
### Changes (English)
## [1.6.0] - 2026-02-12
### Added
- ✨ Add release skill for automated versioning
### Changes (中文)
## [1.6.0] - 2026-02-12
### Added
- ✨ 添加 release 技能用于自动化版本发布
Confirm release? (y/n)
Use AskUserQuestion tool to request user confirmation.
Step 7: Execute Changes
After user confirmation, execute in order:
7a: Update Version Files
Modify version in ALL detected version files using file-specific update patterns from references/version-files.md.
7b: Update CHANGELOG Files
For each detected CHANGELOG file:
- Move
[Unreleased]content to new version section[x.y.z] - YYYY-MM-DD - Create new empty
[Unreleased]section
If CHANGELOG.md does not exist, create it now with the new version section.
7c: Git Operations
Stage all version files and CHANGELOG files modified in Steps 7a–7b by name, then commit and tag:
git add package.json pyproject.toml CHANGELOG.md CHANGELOG.zh-CN.md
git commit -m "🔖 release: vX.Y.Z"
git tag -a vX.Y.Z -m "Release vX.Y.Z"
Replace the file list and version with actual values. Use annotated tag (-a) — includes author, date, and message. Required by git push --follow-tags and better supported by GitHub/GitLab Releases.
Failure Recovery
If git commit fails (e.g. pre-commit hook):
- Check what went wrong:
git status - All file modifications are still staged — fix the issue and create a new commit (do NOT use
--amend) - If the user wants to abort entirely, restore all modified files:
Replace the file list with the actual files modified in Steps 7a–7b.git checkout -- package.json pyproject.toml CHANGELOG.md
If git tag fails (e.g. tag already exists):
- The commit has already been created — do NOT undo it
- Report the error to the user
- Suggest:
git tag -d vX.Y.Zto remove the old tag, then retry
Step 8: Completion Message
Use the branch name detected in Step 0 and the publish command matching the detected ecosystem. Example:
Version vX.Y.Z released successfully!
Updated files:
- package.json (1.5.1 → 1.6.0)
- pyproject.toml (1.5.1 → 1.6.0)
- CHANGELOG.md
- CHANGELOG.zh-CN.md
Next steps:
- git push origin main --follow-tags
- npm publish
Replace branch name, version, file list, and publish command with actual values. Use --follow-tags to push commit and annotated tag in a single command.
Ecosystem-specific publish commands:
| Ecosystem | Publish Command |
|---|---|
| Node.js | npm publish / pnpm publish |
| Python | twine upload dist/* |
| Rust | cargo publish |
| Dart/Flutter | dart pub publish / flutter pub publish |
| Java (Maven) | mvn deploy |
| Java (Gradle) | ./gradlew publish |
| Ruby | gem push *.gem |
| .NET | dotnet nuget push |
More from vamdawn/ai-forge
content-summarizer
Fetch, analyze, and summarize web content into structured Obsidian notes. Supports articles, GitHub repositories, and Reddit/HN/Twitter threads. Automatically detects URL type and selects the appropriate fetcher strategy and note template. Triggers include requests like 'summarize this article', 'take notes on this', 'save this repo', 'summarize this thread', or any URL-based request intended to be saved as an Obsidian note.
60git-commit
Create well-formatted atomic git commits with conventional commit messages and emoji. Use when making git commits, splitting large changesets into logical units, or crafting commit messages.
16review-doc
Structured document review and quality improvement. Use when the user asks to review, proofread, check, audit, or improve a document (Markdown, text, or any prose file). Triggers include: 'review this doc', 'check this document', 'proofread', 'audit this spec', 'review and fix', or any request to find and fix issues in written documents. Supports reviewing against referenced standards (PRD, design docs, style guides).
15plan-executor
Orchestrated multi-agent plan execution with TDD and code review. Use when you have a structured plan file to execute via SubAgents. Decomposes tasks, dispatches agents, enforces TDD and code review gates.
13session-summary
分析当前会话内容并按固定格式生成结构化摘要,输出基本信息、会话概要与逐轮明细。触发词:'总结这次会话'、'summarize this session'、'会话总结'、'session summary'、'总结一下'、'生成会话摘要'、'记录本次会话'。
9review-context
从 context engineering 角度审查代码、架构文档、prompt 和设计文档。自动识别内容类型,选择 3-5 个最相关维度进行审查,生成含严重等级和改进建议的结构化报告。触发词:review context、CE 审查、上下文工程审查。
9