Back to blogs

Semantic Versioning: How Commits Become Version Bumps

Published July 9, 2026

If you've ever wondered how tools like semantic-release automatically decide whether your next release is 1.2.3 or 2.0.0, the answer is: your commit messages. Here's how SemVer works and how to automate it on GitHub.

1. What is SemVer?

Semantic Versioning follows the pattern:

MAJOR.MINOR.PATCH
1 . 4 . 2

Part

Bumped when...

Example

MAJOR

You make a breaking change

1.4.22.0.0

MINOR

You add a new feature (backward-compatible)

1.4.21.5.0

PATCH

You fix a bug (backward-compatible)

1.4.21.4.3

The idea: anyone reading your version number can immediately tell if upgrading is safe, adds features, or might break their code.

2. How Commits Map to Version Bumps

Tools like semantic-release don't guess the version — they read your commit messages, following the Conventional Commits format:

<type>(<scope>): <description>

[optional body]

[optional footer]

Commit type

Version bump

fix: correct null pointer on login

PATCH

feat: add dark mode toggle

MINOR

feat!: change auth API response shape OR footer with BREAKING CHANGE:

MAJOR

chore:, docs:, style:, refactor:, test:

No release (unless configured otherwise)

Examples

git commit -m "fix: resolve crash on empty cart"
# → 1.4.2 → 1.4.3

git commit -m "feat: add CSV export to orders page"
# → 1.4.2 → 1.5.0

git commit -m "feat!: remove deprecated /v1/users endpoint

BREAKING CHANGE: /v1/users is removed, use /v2/users instead"
# → 1.4.2 → 2.0.0

The commit-analyzer plugin scans every commit since the last release, finds the highest-impact type, and decides the next version accordingly — no manual version bumping needed.

3. Implementing It on GitHub

Step 1: Install semantic-release

npm install --save-dev semantic-release \
@semantic-release/commit-analyzer \
@semantic-release/release-notes-generator \
@semantic-release/changelog \
@semantic-release/github \
@semantic-release/git

Step 2: Add the release config

Create release.config.js in your project root:

module.exports = {
branches: ["master"],
plugins: [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
[
"@semantic-release/changelog",
{
changelogFile: "CHANGELOG.md"
}
],
"@semantic-release/github",
[
"@semantic-release/git",
{
assets: ["CHANGELOG.md"],
message:
"chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
}
]
]
};

What each plugin does

Plugin

Responsibility

commit-analyzer

Reads commit messages since last release, determines bump type (patch/minor/major)

release-notes-generator

Generates human-readable release notes from commits

changelog

Writes/updates CHANGELOG.md with the new release notes

github

Creates a GitHub Release with notes, and can comment on related issues/PRs

git

Commits the updated CHANGELOG.md back to the repo, tagged [skip ci] to avoid an infinite CI loop

branches: ["master"] restricts releases to only run off the master branch — commits merged elsewhere won't trigger a release.

Step 3: Add a GitHub Actions workflow

# .github/workflows/release.yml
name: Release

on:
push:
branches:
- master

jobs:
release:
runs-on: ubuntu-latest
permissions:
contents: write
issues: write
pull-requests: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- uses: actions/setup-node@v4
with:
node-version: 20

- run: npm ci

- name: Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: npx semantic-release

Notes:

Step 4: Commit using conventional commits going forward

git commit -m "fix: handle expired token gracefully"
git push origin master

On push to master, the workflow runs, analyzes commits, bumps the version, updates CHANGELOG.md, tags the release, and publishes it to GitHub Releases — all automatically.

Takeaway

SemVer isn't just a numbering convention — paired with Conventional Commits and semantic-release, it turns your commit history into an automated release pipeline. Write disciplined commit messages (fix:, feat:, feat!:/BREAKING CHANGE:), push to your release branch, and let CI handle versioning, changelogs, and GitHub Releases for you.