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 fordevelopor upcoming releases
- New features go in
feature/my-new-feature - Merge into
develop - When stable, create
release/x.y.0 - After testing, merge into
mainand 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:
bumpversionorhatch - 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.0Use:
- 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.0git 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.1git checkout main
git merge hotfix/2.2.1
git push origin main
git checkout develop
git merge hotfix/2.2.1
git push origin developgit 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/xyzis 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.0git add .
git commit -m "feat: Add xyz feature to v2.13.0"git checkout -b release/2.13.0git merge feature/xyz-backport
git tag -a v2.13.0 -m "Release v2.13.0 with xyz feature"
git push origin v2.13.0git checkout main
git merge release/2.13.0
git push origin main
git checkout develop
git merge release/2.13.0
git push origin developgit 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.