Using a software versioning strategy for your builds can reduce the cognitive load for everyone developing and using your software. Versioning Strategies allow you to identify each build artifact quickly and easily. What versioning strategy you use for your software is up to you and your team’s personal preferences. Here are some different options and some pros/cons for each.
When you’re using Git for your Version Control System (VCS), you already have a unique hash for every commit that you make. You can find the hash on the terminal with
git log -1. If your Git repository is on production, you can easily tell exactly what is running by checking the git log.
Whenever you make a production release of your project, it’s best practice to identify the release with a Git Tag. This makes it easy to know what you shipped and when, and gives you some additional methods for rolling back to a previous version.
git tag v1.0.0 && git push --follow tags origin master
If you’re paying attention, in order to create a Git Tag, you’ve got to name it something.
Semantic Versioning: “SemVer”
MAJOR.MINOR.PATCH SemVer Documentation
Semantic Versioning is the most popular choice in open source and is widely adopted by the Ruby, Python, PHP, and Node.js ecosystems, with minor variations. Semantic Versioning is built using the glorious RFC2119. Each numerical version has its own meaning.
MAJOR version must be incremented if there are any backward-incompatible breaking changes included in a release. This has the benefit of making it easy for anyone to quickly identify if a new version will work differently than a previous one.
MINOR version must be incremented if there are backward-compatible functionality is introduced. In the strictest sense, this means you should be able to upgrade to a new minor version without experiencing any breaking changes.
PATCH version is meant for backward-compatible bug fixes. You should expect no new functionality with a new patch version, only improvements.
Remember that each number in SemVer is treated independently. This means version
3.14.2 is more than 11 releases ahead of version
3.3.0. This will not be apparent as version
3.3.0 is higher in priority when sorted alphabetically.
SemVer also allows for pre-releases, but we do not recommend using them. Pre-releases A pre-release defy all logic of semantic versioning, meaning they ignore the conventions around breaking changes. Any pre-release may break at any time. If you’re considering releasing your software as
2.0.0-beta-24, you might as well throw away SemVer all together and use Incrementing Build Number or Date Based Versioning systems, since there is no meaning in incrementing a beta number indefinitely.
Resetting the Version
Occasionally developers decide to reset their versioning for various reasons. MySQL released versions
5.7, and then jumped to version
8.0, leading some folks to refer to the previous 3
MINOR releases under
7. Similarly, React made a change when they released version
0.14.8, followed by
v15.0.1. SemVer’s recommendation is to start with version
0.x.x, which React did. In their case, the React Team decided their project was mature enough to skip version
1.0 all together as in their case the
MINOR version had much more meaning than the
Incrementing Build Number
Another somewhat popular methodology for versioning your software is to simply use the build number as set by your Continuous Integration System. This gives you a simple incrementing version to your Git Tags. You can still easily reference the Git Commit Hash and find the date of the release using Git.
Date Based Versioning
Date Based Versioning provides you with some information about when the release was made. Arch Linux uses Date Based Versioning in the following format:
If you are on a more frequent release cycle than once-a-day, you may have to also include time information to maintain a unique identifier for the artifact.
Ubuntu is the most popular Linux distribution for web servers. Ubuntu follows a strict 6-month release cycle using a date-based schema. For example,
19.04, etc. Since Ubuntu is so critical to so many people, this release schedule makes sense for them. Like many mature projects, there is documentation for the Ubuntu Release Cycle, which allows everyone to plan ahead for changes.
Further, additional updates to each major version Ubuntu uses patch versions to indicate follow up releases to their major versions such as
Software Versioning System Comparison
|SemVer||– Widely Adopted|
– Generally Meaningful
– Most open source ecosystems require usage for package distribution.
|– Attempts to reduce the nature of changes to a number|
– Specific conventions may vary from project to project and language to language, for example, Python PEP 440
– Pre-releases negate any worth
– Referrences CI Builds
|– Does not convey any infromation about the nature of the changes|
|Date Based||– Simple|
– Very easy to identify when releases were made
|– Does not convey any information about the nature of the changes |
– Not ideal for releasing multiple times daily
|Hybrid||– Can use the best parts from SemVer, Incrementing, Date Based versioning systems|
– You get to define for your own project how the system will work
|– May not be consistent with any specific package manager’s requirements. |
– Anyone developer using your software must understand your versioning conventions via your documentation