Semantic Versioning
Determine correct version bumps following Semantic Versioning 2.0.0: analyze the commits since the last tag and recommend the appropriate increment.
When to use
- Releasing a new version or creating a release tag
- Determining the version bump after a set of changes
- Managing changelogs or any version-management operation
- The analysis relies on commit types — write them per [[conventional-commit]]
Version format
Strict format from the specification:
MAJOR.MINOR.PATCH[-pre-release][+build]
Rules:
- Each element is a non-negative integer, no leading zeros
- Elements increase numerically: 1.9.0 → 1.10.0 → 1.11.0
- Once released, the contents of a version MUST NOT be modified
- The
v prefix is a tag convention, not part of the version
Increment rules
Decision tree for version bumps (commit types per [[conventional-commit]]):
MAJOR (X.0.0) — Incompatible API changes:
- Commits containing
BREAKING CHANGE: in body or footer
- Commits with
! after type: feat!:, fix!:, refactor!:
- Removing a public API, changing function signatures, renaming exports
MINOR (0.X.0) — New backward-compatible functionality:
- Commits with type
feat: (without breaking changes)
- Adding new endpoints, functions, options, or features
- Deprecating existing functionality (without removing it)
- Resets PATCH to 0
PATCH (0.0.X) — Backward-compatible bug fixes:
- Commits with type
fix:
- Commits with type
perf: (performance improvements)
- Internal changes that correct incorrect behavior
No bump needed:
- Commits with types:
docs:, style:, refactor:, test:, build:, ci:, chore:
- Unless combined with
feat: or fix: commits in the same release
Analysis process
- Find the last version tag:
git describe --tags --abbrev=0
- List commits since that tag:
git log <last-tag>..HEAD --oneline
- Classify each commit by its conventional commit type
- Check for BREAKING CHANGE markers (footer or
! suffix)
- Apply the highest-priority rule: MAJOR > MINOR > PATCH
- Calculate the new version number
- Report: current version → new version, with justification
Pre-release and Build Metadata
- Pre-release: appended with hyphen:
1.0.0-alpha, 1.0.0-beta.1, 1.0.0-rc.1
- Build metadata: appended with plus:
1.0.0+20240101, 1.0.0-alpha+001
- Pre-release has lower precedence than release:
1.0.0-alpha < 1.0.0
- Build metadata is ignored in precedence comparisons
Precedence Rules
Version comparison order:
- Compare MAJOR, then MINOR, then PATCH (numerically)
- Release > pre-release for same version
- Pre-release identifiers: numeric < alphanumeric, compared left to right
- Example:
1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-beta < 1.0.0-rc.1 < 1.0.0
Initial Development (0.y.z)
- Major version zero is for initial development
- Anything may change at any time — public API is not stable
- Start at 0.1.0, bump minor for each pre-stable release
- Version 1.0.0 defines the first stable public API
Files to Update
Common version files by ecosystem:
- Go:
.version, ldflags in build, MCP server version constant
- Node.js:
package.json (version field)
- Python:
pyproject.toml, __version__
- Rust:
Cargo.toml
- Java:
pom.xml or build.gradle
Release Workflow
After determining the version bump:
- Update version files
- Commit:
chore(release): bump version to X.Y.Z
- Create annotated tag:
git tag -a vX.Y.Z -m "Release vX.Y.Z"
- Push commit and tag:
git push origin main && git push origin vX.Y.Z
Anti-patterns
- Bumping MAJOR for non-breaking changes (version inflation)
- Skipping versions (1.2.0 → 1.4.0)
- Modifying a released version instead of releasing a new one
- Ignoring BREAKING CHANGE markers in commit analysis
- Bumping version for docs/style/test-only changes
- Forgetting to reset MINOR and PATCH when bumping MAJOR
- Forgetting to reset PATCH when bumping MINOR
Verification
Before releasing:
1---2name: semantic-versioning3description: Semantic Versioning4---5# Semantic Versioning67Determine correct version bumps following Semantic Versioning 2.0.0: analyze the commits since the last tag and recommend the appropriate increment.89## When to use1011- Releasing a new version or creating a release tag12- Determining the version bump after a set of changes13- Managing changelogs or any version-management operation14- The analysis relies on commit types — write them per [[conventional-commit]]1516## Version format17Strict format from the specification:18```19MAJOR.MINOR.PATCH[-pre-release][+build]20```2122Rules:23- Each element is a non-negative integer, no leading zeros24- Elements increase numerically: 1.9.0 → 1.10.0 → 1.11.025- Once released, the contents of a version MUST NOT be modified26- The `v` prefix is a tag convention, not part of the version2728## Increment rules2930Decision tree for version bumps (commit types per [[conventional-commit]]):3132**MAJOR (X.0.0)** — Incompatible API changes:33- Commits containing `BREAKING CHANGE:` in body or footer34- Commits with `!` after type: `feat!:`, `fix!:`, `refactor!:`35- Removing a public API, changing function signatures, renaming exports3637**MINOR (0.X.0)** — New backward-compatible functionality:38- Commits with type `feat:` (without breaking changes)39- Adding new endpoints, functions, options, or features40- Deprecating existing functionality (without removing it)41- Resets PATCH to 04243**PATCH (0.0.X)** — Backward-compatible bug fixes:44- Commits with type `fix:`45- Commits with type `perf:` (performance improvements)46- Internal changes that correct incorrect behavior4748**No bump needed:**49- Commits with types: `docs:`, `style:`, `refactor:`, `test:`, `build:`, `ci:`, `chore:`50- Unless combined with `feat:` or `fix:` commits in the same release5152## Analysis process53541. Find the last version tag: `git describe --tags --abbrev=0`552. List commits since that tag: `git log <last-tag>..HEAD --oneline`563. Classify each commit by its conventional commit type574. Check for BREAKING CHANGE markers (footer or `!` suffix)585. Apply the highest-priority rule: MAJOR > MINOR > PATCH596. Calculate the new version number607. Report: current version → new version, with justification6162## Pre-release and Build Metadata63- Pre-release: appended with hyphen: `1.0.0-alpha`, `1.0.0-beta.1`, `1.0.0-rc.1`64- Build metadata: appended with plus: `1.0.0+20240101`, `1.0.0-alpha+001`65- Pre-release has lower precedence than release: `1.0.0-alpha < 1.0.0`66- Build metadata is ignored in precedence comparisons6768## Precedence Rules69Version comparison order:701. Compare MAJOR, then MINOR, then PATCH (numerically)712. Release > pre-release for same version723. Pre-release identifiers: numeric < alphanumeric, compared left to right734. Example: `1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-beta < 1.0.0-rc.1 < 1.0.0`7475## Initial Development (0.y.z)76- Major version zero is for initial development77- Anything may change at any time — public API is not stable78- Start at 0.1.0, bump minor for each pre-stable release79- Version 1.0.0 defines the first stable public API8081## Files to Update82Common version files by ecosystem:83- **Go**: `.version`, ldflags in build, MCP server version constant84- **Node.js**: `package.json` (version field)85- **Python**: `pyproject.toml`, `__version__`86- **Rust**: `Cargo.toml`87- **Java**: `pom.xml` or `build.gradle`8889## Release Workflow90After determining the version bump:911. Update version files922. Commit: `chore(release): bump version to X.Y.Z`933. Create annotated tag: `git tag -a vX.Y.Z -m "Release vX.Y.Z"`944. Push commit and tag: `git push origin main && git push origin vX.Y.Z`9596## Anti-patterns97- Bumping MAJOR for non-breaking changes (version inflation)98- Skipping versions (1.2.0 → 1.4.0)99- Modifying a released version instead of releasing a new one100- Ignoring BREAKING CHANGE markers in commit analysis101- Bumping version for docs/style/test-only changes102- Forgetting to reset MINOR and PATCH when bumping MAJOR103- Forgetting to reset PATCH when bumping MINOR104105## Verification106107Before releasing:108- [ ] All commits since last tag have been classified109- [ ] Breaking changes trigger MAJOR (or MINOR if still on 0.y.z)110- [ ] New features trigger at minimum MINOR111- [ ] Bug fixes trigger at minimum PATCH112- [ ] Version files are updated consistently113- [ ] Tag format matches `vMAJOR.MINOR.PATCH`114- [ ] No version was skipped