Semantic versioning uses the format:
MAJOR.MINOR.PATCH
→ 1.2.3
- MAJOR: Incompatible API changes
- MINOR: Backward-compatible new features
- PATCH: Backward-compatible bug fixes
For pre-releases and metadata:
- Pre-releases:
1.2.3-beta.1
- Build metadata:
1.2.3+20240205
A structured Git branching model helps maintain different versions effectively.
main
(ormaster
) → Stable production-ready code (latest release)develop
→ Active development branch (next version)- Feature branches (
feature/*
) → New features - Release branches (
release/*
) → Preparing stable versions before release - Hotfix branches (
hotfix/*
) → Urgent fixes for released versions - Bugfix branches (
bugfix/*
) → Fixes fordevelop
or upcoming releases
- New features go in
feature/my-new-feature
- Merge into
develop
- When stable, create
release/x.y.0
- After testing, merge into
main
and tag asvx.y.0
Use Git tags to mark releases:
git tag -a v1.2.3 -m "Release version 1.2.3"
git push origin v1.2.3
- Tags should match SemVer.
- CI/CD can read tags to trigger deployments.
Instead of manually updating versions, use tools like:
- Python:
bumpversion
orhatch
- Node.js:
npm version major|minor|patch
- Rust:
cargo release
- Go:
goreleaser
Example using bumpversion
:
bumpversion minor # Bumps from 1.2.3 to 1.3.0
Use:
- Conventional Commits (
feat:
,fix:
,chore:
) to automate release notes. standard-version
(Node.js) orrelease-drafter
(GitHub Action) for changelogs.- GitHub Releases:
gh release create vx.y.z --notes "Changelog text"
- Use GitHub Actions, GitLab CI, or Jenkins to automate versioning.
- Extract the latest tag to version builds dynamically:
git describe --tags --abbrev=0
- In Docker:
docker build -t myapp:$(git describe --tags --abbrev=0) .
- Maintain long-term stable versions (
v1.x
,v2.x
) in separate branches if necessary. - Apply hotfixes via
hotfix/
branches.
- Latest release:
v2.3.0
(ongoing development forv2.4.0
). - Need to patch
v2.2.0
(for users still on2.2.x
). - The fix should be released as
v2.2.1
.
git checkout -b hotfix/2.2.1 v2.2.0
git add .
git commit -m "fix: [brief description of the patch]"
git tag -a v2.2.1 -m "Patch release v2.2.1"
git push origin v2.2.1
git checkout main
git merge hotfix/2.2.1
git push origin main
git checkout develop
git merge hotfix/2.2.1
git push origin develop
git branch -d hotfix/2.2.1
git push origin --delete hotfix/2.2.1
- Current active version:
v4.50.1
(developingv4.51.0
). - A new feature
feature/xyz
is being added inv4.51.0
, but also needs to be added tov2.12.0
. - The new minor release should be
v2.13.0
.
git checkout -b feature/xyz-backport v2.12.0
git add .
git commit -m "feat: Add xyz feature to v2.13.0"
git checkout -b release/2.13.0
git merge feature/xyz-backport
git tag -a v2.13.0 -m "Release v2.13.0 with xyz feature"
git push origin v2.13.0
git checkout main
git merge release/2.13.0
git push origin main
git checkout develop
git merge release/2.13.0
git push origin develop
git branch -d feature/xyz-backport
git push origin --delete feature/xyz-backport
git branch -d release/2.13.0
✅ Use hotfix/
for patches and release/x.y
for minor versions.
✅ Tag new minor versions properly (v2.13.0
).
✅ Merge back into main
and develop
to keep history clean.
✅ Consider maintaining release/x.y
branches for backports.