Tags, Releases & SemVer

Marking Releases

You met tags briefly in the History module - permanent labels on a commit, used to mark the exact point in history you shipped as a version. This section covers using them properly for releases, plus the numbering convention almost every ecosystem expects.

$ git tag -a v1.2.0 -m "Release 1.2.0"   # annotated (recommended)
$ git push origin v1.2.0                   # tags aren't pushed by default!
$ git tag                                  # list
$ git checkout v1.2.0                      # inspect exactly what shipped in that release

Semantic Versioning (SemVer)

Versions are written MAJOR.MINOR.PATCH (e.g. 1.4.2), and each number carries a specific promise to anyone depending on your software:

BumpWhenExample
MAJORBreaking changes - old code using this might now break1.4.2 → 2.0.0
MINORNew features added, but everything old still works the same1.4.2 → 1.5.0
PATCHBug fixes only, no new features, nothing about the API changes1.4.2 → 1.4.3

The whole point of SemVer is that someone depending on your package can glance at a version bump and immediately know how risky it is to upgrade - a PATCH bump is (in theory) always safe to take automatically; a MAJOR bump means "read the changelog before upgrading".

Tip: Annotated tags (-a) store the tagger's name, date and a message, and can additionally be cryptographically signed - always use annotated tags for real releases. Lightweight tags (just git tag v1, no -a/-m) are fine for quick, private bookmarks you don't intend to publish.
Warning: git push does not push tags, even though it feels like it should after everything else you've pushed. Ship the release marker explicitly with git push origin <tag> or git push --tags, or your carefully-labeled v1.2.0 exists only on your own machine and nobody else will ever see it.