3 min read

A Practical Guide to Semantic Versioning: How and When to Update Your Versions

Table of Contents

by Bruno Sartori

Introduction

Semantic versioning is a convention for naming software versions in a way that clarifies what updates kinds of updates is made in an application or library. The main idea is to use a sequence of three numbers where each number has its specific meaning.

How does it work?

Semantic versioning is based on three core components: MAJOR, MINOR, and PATCH. Each of these components plays a specific role in indicating the nature of changes in a new release. Here’s a breakdown of how each part works:

MAJOR (X.0.0):

This is only incremented when there are changes that are incompatible with previous versions. Many times, updates in the code can affect the contract, making obligatory for users to update the way they use your new version. In this cases you need to specify that the major version was updated.

MINOR (0.X.0):

This one is incremented when there are new features which are compatible with previous versions. Additions like new methods or configuration options enter on this category.

PATCH (0.0.X):

This is incremented only when there are retro compatible bugfixes. These changes don’t add new features but improve stability and performance of the software.

Practical Examples

  • 1.0.0 to 2.0.0: Breakable changes where made. Can include removal of older methods, changes on the API contract or the way parts of the software operates.
  • 1.2.0 to 1.3.0: New features where added, but all that works in 1.2.0 still works on 1.3.0.
  • 1.2.1 to 1.2.3: Bugfixes that don’t affect the API or the way user interacts with the software. For example, fixing an error in a function’s logic.

Pre-release Identifiers

Pre-release identifiers can be used to label version that are in experimental or development phase. Pre-release identifiers are written in by adding an hyphen followed by the identifier: <version core> "-" <pre-release identifier> | <pre-release identifier> "." <dot-separated pre-release identifier>, examples are: 1.0.0-alpha, 1.0.0-beta, 1.0.0-rc (release candidate), e 1.0.0-rc.1. Note that there are two release candidates for 1.0.0 version. In this case, the precedence is determined by comparing each dot separated identifier from left to right until a difference is found.

Example: pre-1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta < 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0.

Build Metadata

Build metadata can be added by appending a plus sign followed by dot separated identifiers, for example: 1.0.0-rc+011, 1.2.15+20240828092135, 2.0.0-alpha+exp.sha.2604f89. Build identifiers are NOT taken into account when determining version precedence like pre-release identifiers.

Conclusion

Semantic versioning is a powerful tool for managing software releases in a clear and predictable way. By adhering to the principles semantic versioning, developers can communicate the impact of changes to users effectively, ensuring that updates are smooth and manageable. This approach not only helps in maintaining backward compatibility but also fosters a disciplined development process where each release is intentional and well-defined.

References

https://semver.org