Semantic Versioning
Determine the next version from commit history. Every pushed change gets classified; the highest-impact commit drives the bump.
When to Activate
- Before or after pushing changes (suggest the version bump)
- When the user asks "what version should this be?"
- When preparing a release or tag
- When reviewing a set of commits for release notes
Version Rules
Follows Semantic Versioning 2.0.0:
| Bump |
Trigger |
Examples |
| Major (X.0.0) |
Breaking change |
feat!:, fix!:, BREAKING CHANGE: in body/footer |
| Minor (x.Y.0) |
New feature |
feat:, feature: |
| Patch (x.y.Z) |
Everything else |
fix:, chore:, docs:, style:, refactor:, test:, ci:, perf: |
The highest bump wins: if any commit is major, the release is major — regardless of how many patches are in the batch.
How to Check
Run the analysis script:
uv run skills/semantic-versioning/scripts/version-bump.py [repo-path]
Options:
--apply — update the version file after confirmation
--tag — also create a git tag
Version File Detection
The script auto-detects where the version lives:
| File |
Field |
pyproject.toml |
[project] version = "x.y.z" |
package.json |
"version": "x.y.z" |
Cargo.toml |
[package] version = "x.y.z" |
VERSION |
Plain text file |
Workflow
- Analyze — scan commits since last tag, classify each
- Report — show the bump type, commit breakdown, and suggested next version
- Confirm — wait for user approval before making changes
- Apply (if
--apply) — update version file and optionally tag
Never auto-apply version changes without user confirmation.
Commit Format Guide
For best results, follow conventional commits:
<type>[optional scope][!]: <description>
[optional body]
[optional footer(s)]
If commits don't follow conventional format, fall back to keyword analysis:
- Words like "add", "new", "feature" → minor
- Words like "fix", "bug", "patch", "correct" → patch
- Words like "breaking", "remove", "drop", "rename API" → major
Pre-1.0 Semantics
For versions 0.y.z (pre-stable):
- API is considered unstable
- Minor bumps may include breaking changes
- Use
0.y.z until the project declares stability
Common Mistakes
| Mistake |
Fix |
Bumping major for every feat! in pre-1.0 |
Pre-1.0: breaking changes go in minor |
| Forgetting to tag after version bump |
Always tag: git tag v<version> |
| Version in multiple files getting out of sync |
Use the script to update all detected version files |
| Non-conventional commit messages |
Fall back to keyword analysis, but encourage conventional commits |
1---2name: semantic-versioning3description: Use when committing or pushing changes and the repository needs a version bump. Analyzes commits using conventional commit prefixes to determine whether the next release is a major, minor, or patch increment. Also use when the user asks about versioning, release planning, or changelog generation.4---56# Semantic Versioning78Determine the next version from commit history. Every pushed change gets classified; the highest-impact commit drives the bump.910## When to Activate1112- Before or after pushing changes (suggest the version bump)13- When the user asks "what version should this be?"14- When preparing a release or tag15- When reviewing a set of commits for release notes1617## Version Rules1819Follows [Semantic Versioning 2.0.0](https://semver.org):2021| Bump | Trigger | Examples |22|------|---------|----------|23| **Major** (X.0.0) | Breaking change | `feat!:`, `fix!:`, `BREAKING CHANGE:` in body/footer |24| **Minor** (x.Y.0) | New feature | `feat:`, `feature:` |25| **Patch** (x.y.Z) | Everything else | `fix:`, `chore:`, `docs:`, `style:`, `refactor:`, `test:`, `ci:`, `perf:` |2627The highest bump wins: if any commit is `major`, the release is major — regardless of how many patches are in the batch.2829## How to Check3031Run the analysis script:3233```bash34uv run skills/semantic-versioning/scripts/version-bump.py [repo-path]35```3637Options:38- `--apply` — update the version file after confirmation39- `--tag` — also create a git tag4041## Version File Detection4243The script auto-detects where the version lives:4445| File | Field |46|------|-------|47| `pyproject.toml` | `[project] version = "x.y.z"` |48| `package.json` | `"version": "x.y.z"` |49| `Cargo.toml` | `[package] version = "x.y.z"` |50| `VERSION` | Plain text file |5152## Workflow53541. **Analyze** — scan commits since last tag, classify each552. **Report** — show the bump type, commit breakdown, and suggested next version563. **Confirm** — wait for user approval before making changes574. **Apply** (if `--apply`) — update version file and optionally tag5859Never auto-apply version changes without user confirmation.6061## Commit Format Guide6263For best results, follow conventional commits:6465```66<type>[optional scope][!]: <description>6768[optional body]6970[optional footer(s)]71```7273If commits don't follow conventional format, fall back to keyword analysis:74- Words like "add", "new", "feature" → minor75- Words like "fix", "bug", "patch", "correct" → patch76- Words like "breaking", "remove", "drop", "rename API" → major7778## Pre-1.0 Semantics7980For versions `0.y.z` (pre-stable):81- API is considered unstable82- Minor bumps may include breaking changes83- Use `0.y.z` until the project declares stability8485## Common Mistakes8687| Mistake | Fix |88|---------|-----|89| Bumping major for every `feat!` in pre-1.0 | Pre-1.0: breaking changes go in minor |90| Forgetting to tag after version bump | Always tag: `git tag v<version>` |91| Version in multiple files getting out of sync | Use the script to update all detected version files |92| Non-conventional commit messages | Fall back to keyword analysis, but encourage conventional commits |