Author: Burak Köksal, Senior SW Engineer – Web Development – Corporate Applications
0.1.0 What is Software Versioning?
In Wikipedia it’s described as: “Software versioning is the process of assigning either unique version names or unique version numbers to unique states of computer software.”1. Software development is (mostly) a never-ending adventure while you want to equip it with some new features, abandon some rarely used functionality, tweak algorithms to perform better and so on… At specific points you may want to deliver stable releases for other people to use it or build their softwares depend on it —especially if you are developing an API. And you want them to know your software is different than before. Here comes versioning…
If you decide to go with unique names you will eventually end up seeking new cooler-than-ever version names. Therefore numbers makes a little more sense about this matter… It’s not always that you will develop new features, sometimes you need to fix bugs or publish patches to keep up. So importance of the changes on your software may vary. You also need to represent this “importance” on your version label for people to understand how big the change is. Numbers conform this requirement since they may mean magnitude too. At this point I believe you’re convinced that using numbers is more feasible way than using names.
0.2.0 Importance is Important
Speaking of importance of the change, it can be roughly categorized into 3 sections: Major, Minor and Patch. Of course there is more than this like builds, release candidates, alpha-beta stages and so on, but they will be left out from this article for the sake of the brevity.
Ground-breaking and backward-compatibility violating changes fall into “Major” category. Please note that sustaining backward-compatibility is an important aspect of development if you want your clients to continue to use your API safely as you improve it over time… New features will be shining in “Minor” category. And finally, your life-saver patches and clever bug fixes will increase the “Patch” category.
0.3.0 What is Semantic Versioning
Semantic Versioning (henceforth, SemVer) is basically all about incrementing this numbers in a meaningful way. SemVer suggests to start development at 0.1.0 and increase the Minor part as you add new features. There’s no limit for any part. They can go up as much as you want. Major 0 generally means that you’re at initial development and changing the API every other day. Anything can happen at Major 0. You can go back and forth without avoiding to break things (note the headings of this article). So “Until when should I keep increasing this Minor part?” would be an appropriate question. And the answer is until when you are ready to go on a production level or have some clients using your API or library. Then you can proudly label your version 1.0.0. The first official Major version… Celebrate with friends!
0.3.1 Why SemVer? — The Cruel Real World
There’s a term in development world called “dependency hell”. You’re really lucky if you hear this for the first time. It really is challenging once you got caught. Nowadays package managers take the most of the heavy work but you still need to be careful about declaring your dependencies.
Let’s consider a situation you’re developing a library called “Car” but you don’t want to struggle to develop an “Engine” in order your car to work. After hours of searching and investigating thoroughly you found an Engine suit your needs which also follows SemVer practices. That Engine library is at 4.1.2 version and you’re dying to use some functionality released in this version. You can safely tell your package manager it can update this Engine library until Engine version 5.0.0. When it reaches Major 5 you should update your code if you really want to keep up with the Engine. You’re safe since respectable Engine developers follow SemVer, otherwise you wouldn’t know whether changes on Engine library will break your precious code and turn your Car library into a useless statements. It’s not just the Engine… The other relatively small libraries that Engine depends on and what about the Wheel, Transmission etc.? You should really be careful and strict as much as possible when declaring a dependency that doesn’t follow SemVer.
0.4.0 Is it the only way? — Sentimental Versioning
Of course it’s not the only way. There are a lot of popular libraries out there don’t follow SemVer like node.js, backbone.js etc. and the sun still continues to rise every morning… A big number of developers prefer sentimental versioning over SemVer. They say SemVer is good for robots (package managers in this context) but don’t mean a thing for human beings. They claim “Sometimes a version is just a number, but sometimes what we really want is a poem.”2 which I personally agree from time to time. It doesn’t have specifications like SemVer does, however it has a guide encourages you to version your work rather creative and original. They’re like the balancing weight against SemVer lovers. I wouldn’t blame anyone who want to join this “romantic versioners”. You can strictly follow SemVer or you can embrace sentimental versioning and go all the way down to esoteric versioning like TeX did. After they reached Major 3 version, they continued to 3.1, 3.14, 3.141 and so on. As you noticed they were getting closer and closer to π. Their last stable release is 3.14159265 born about 2 years ago.
1.0.0 A New Hope — The Hybrid Model
Why not using both and taking advantages of these two models? For instance Java follows both SemVer and sentimental versioning. It’s recent sentimental version is: Java 8u112 while it’s semantic version is Java 1.8.0_112. And yes, they’re still at Major 1 in spite of the time ruthlessly flying by… Sentimental versioning is a better way than SemVer in terms of practicalness. It makes life easier to mention it in an everyday small talk. You can even go one step further and call it java 8 and package managers still can identify the nuance between versions and take action accordingly.
Adopting both models, sometimes, may lead problems and conflicts. For example Underscore.js has announced its sentimental version as if it were their semantic version once. And it didn’t take long Underscore.js users to make a fuss and quit using the library.
It would be a good practice to isolate those two different approaches for your future projects or libraries.
Happy coding and sane versioning!