1. Introduction
SemVer is a popular versioning scheme that is used by a vast amount of open-source projects to communicate the changes included in a version release. As developers, it’s important for us to understand how to use SemVer in our own projects and also how to interpret a specific version change.
This tutorial will provide a guide to the main concepts of the SemVer specification.
2. Why Is Software Versioning Important?
Software versioning helps us to identify the state software or package is in with a unique name and/or a number. Versions help developers keep track of changes to third-party software or packages they are using.
There are different types of versioning schemes, but one of the popular ones is a scheme called Semantic Versioning (SemVer) which was proposed by Tom Preston-Werner in 2013 to specify how version numbering should be controlled.
3. What Is SemVer?
Under the SemVer versioning scheme, our versioning would take on the following format:
Where x, y, and z are integers that increase numerically and indicate Major, Minor, and Patch, respectively.
The SemVer specification assumes that projects using this scheme MUST have a public API. Based on this, let’s take a look at each part in more detail starting from left to right.
3.1. Major
The major version should increase when we’ve introduced new functionality which breaks our API, i.e., increase this value when we’ve added a backward-incompatible change to our project. When this number is increased, we must reset the Minor and Patch numbers to 0.
For example, if we have a project that is on version 1.2.5 and we have introduced a breaking change under the SemVer scheme, we must set our new version number to 2.0.0.
3.2. Minor
We should increase our minor version when we’ve introduced new functionality which changes our API but is backward compatible, i.e., a non-breaking change. We can also opt to change the Minor version if we’ve made substantial changes to the internal code of our project.
Similarly, when we change the Minor version we should also reset the patch version to 0. For example, updating the Minor version of a project at 2.0.1 would set it to 2.1.0.
3.3. Patch
Under the SemVer specs, we reserve patch changes for backward-compatible bug fixes. A patch change should not involve any changes to the API.
3.4. Pre-Release and Build
After the patch version, there are some optional labels we can add to our versions, such as a pre-release label or a build number.
For example, to mark a package as a pre-release, we must add a hyphen then the pre-release label, which can be a dot-separated identifier, e.g., 1.0.0-alpha.1 tells us that this project is a pre-release version of 1.0.0 labeled alpha.1. A pre-release label indicates that this version is unstable and has a high risk if we use it. When considering version precedence, a pre-release version is always of lower precedence than the normal version.
If we want to indicate the build of that release, we can add a dot-separated identifier of the build appended after the patch (or pre-release) with a + sign. For example, 1.0.0-alpha.1+001. Build meta-data does not factor in precedence, so we can consider two versions that only differ in build number to be of the same precedence.
4. Development SemVer
The SemVer specification reserves the Major version 0.x.y for development purposes. When starting a new project, it makes sense to start initial development at a release 0.1.0 since it will, of course, include features. SemVer assumes a development version to be unstable and can change at any time.
5. Why Is SemVer So Popular?
SemVer has gained popularity in the last few years. Here are a couple of reasons why:
- It is a fairly simple scheme to follow and allows keeping track of changes
- We can immediately tell from comparing versions what kind of change happened; whether it is a breaking or non-breaking change
- We get an immediate idea of the risk we take in updating our packages by checking if it was a Major, Minor, or Patch change. We should always be diligent in checking that our code still runs, but if we update our package with only a patch change, we can feel fairly confident that this will not break our current implementation. That is if the providers of the package are also diligent in their use of SemVer as well
- SemVer helps developers avoid what is known as dependency hell. Dependency hell happens when we have dependencies that share different versions of other dependencies. SemVer provides a clear way of versioning which helps developers resolve these conflicts. We usually do this by specifying a range of acceptable versions which can be used. This is heavily used in an automated way by npm to manage to install JavaScript dependencies in a project
6. Other Versioning Schemes
There are many different versioning schemes in use. Let’s take a brief look at a few of these:
- CalVer – this scheme relies on the date of the release. It is not as specific as the SemVer scheme but is used by projects such as Pip the Python package manager and Ubuntu
- Python Versioning Scheme – a scheme defined to identify distributions of Python. The scheme uses five segments called epoch, release, pre-release, post-release, and development
- Named Versions – some projects opt to name their releases with a unique name. For example, Android has an interesting collection of version names which started off with Cupcake, Donut, and Eclair! We can see a full list of Android releases if needed
- Spring Project Version Naming – this is a common method in Spring Framework and Sprint Boot projects and expands on SemVer with some additional labels such as RC for release candidates and BUILD-SNAPSHOT for a development release
7. Conclusion
SemVer is not the only method of versioning, but it is popular, especially among open-source projects.
This tutorial provided a quick guide to using and interpreting the SemVer specification. SemVer is a Software Versioning scheme that specifies how we version packages in a meaningful way.