Code crafting and lead climbing share common concepts. The lead climber periodically connects the rope to a safety equipment, keeping in mind the fall factor. The wise developer do the same… but only after experiencing enough non-lethal but time-consuming hardships, of course.
Reading time: 7min
In this post, we will see how a versioning strategy can actually save a lot of precious time. It will provide links on regression, open-closed principle and semantic versioning.
Developing a scientific application is a never-ending, irregular and often chaotic process. But the real pain comes when the end-users come with good questions concerning the feared Regression:
- We fixed this bug last summer, why is it happening again?
- This was working until now, but not anymore, what did you do?
- Ok the result was written, nice. But how come it is significantly different from the previous version?
- Can I switch back to the previous formulation?
The reason these questions put the developer in bad mood from the start, is because it could have been avoided. Let us have a look at computer engineering principles to see how scholars dealt with it.
The Open/Closed principle is one of the SOLID principles to remember. While born from the Object-Oriented Programming best practices, this is applicable to any development. The full description is “software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification”. This means that a development must “Add” a functionality, never “Change” or “Remove” it. One may counter :
Yes but what if the previous functionality was wrong? Is not it better to simply remove it?”
There we get subjective. A “wrong” result according to the author can be “Sufficiently good” for its user. The author can convince him otherwise, but this will take priceless time.
Some people designed a moral contract to avoid these issues, called semantic versioning.
Semantic Versioning — or SemVer — is an international standard that quickly became the cornerstone of many installations processes. See the original source for a full length description, but let me give you a short takeaway. One way to shorten it is to state that a new software version can only be ONE of the three following options.
We will use as an illustration an imaginary application “PokeScore, the reference software to compute in real-time the score of a Pokemon Battle”, initially at version 2.12.4
The new version does everything the same as the previous one. No new functionality, no losses. The pledge is : Some features’ behaviors that were declared to the users as BUGS and are now fixed. And that is all.. X.Y.BugFix is a drop-in replacement (with identical functionality) in any context where X.Y.Z, Z ≠ BigFix was used.
Pokescore illustration: [BUGFIX] In case of “water attack” the score could become negative. This was creating a visual glitch on the Score Board for NintenBox terminals. Corrected for versions 2.12.5 and higher.
The new version does everything the same as the previous one, no losses. However, in this one: A new functionality is present, but we still pledge that all the former behaviors are the same. X.Minor.Z is a drop-in replacement in any context where X.Y.Z, Y < Minor was used.
Pokescore illustration: [MINOR] New in 2.13.0, the scores can now be live-streamed on Facebook and Twitter using the feature `score.pokelivestream()”. Tested on legacy devices.
This is the big earthquake for the versions. The only thing you can know for sure is We do not vouch for backward compatibility with any of the previous versions. Indeed, major versions are dedicated to overhauls, and are the only occasion unused functionality can be removed. A Major revision can even have more bugs and no new features with respect to the previous one.
Pokescore illustration: [MAJOR] 3.0.0 is out! This version will allow the computing of PokeBattles on the next-generation quantic consoles. Massive melee involving thousands pokemons in several factions will soon be possible!
With SemVer, 90% of questions on versions are auto-answered on the end-user side by comparison of two SemVer numbers. For example, if a new version comes out:
- I have 2.3.4, The latest version is 2.3.12 : Good, less bugs, probably.
- I have 2.3.4, The latest version is 2.4.0 : Cool, I can test new stuff.
- I have 2.3.4, The latest version is 3.0.0 : I will face hardships, better not bet my next results on it.
Similarly, when two end users want to share work based upon the same software:
- I worked on 2.3.4, you worked on 2.3.12: No risks.
- I worked in 2.3.4, you worked on 2.2.0 : Hem, let us check if you are not missing something.
- I worked in 3.0.0, you worked on 2.3.12: You need to update if you want to test my stuff.
One might be thinking this all boils down to pick tag names looking like 12.34.56.
All this is nice and clean, we just have to use the proper tags and yell to any one : read the SemVer Number dude!.
Or, if the author is hoarding enough more important tasks, he could even be tempted by outsourcing:
SemVer seems great, but since I do not fully understand it, I will leave this to the techs guys.
In fact SemVer deeply impacts the way you think about your development. The author must know on what revision, either BugFix/Minor/Major, he is before writing it, and stick to it until the tag. In practice, one cannot start a new smart functionality he just thought of while preparing a Bugfix. He will delay it to the next Minor, and focus on the Bugfix to release it fast and early. Wrong or disappointing features will need to wait for the next major version before being removed, and will pollute the code a bit longer.
Yes, committing to SemVer means some tempting shortcuts are forbidden. It is intrusive, and feel time-consuming at first. But in the long run, it saves a lot of time.
Pro tip: git is your best friend for versioning. Organize your features in dedicated branches, so that you can merge them at the correct time corresponding to your SemVer-compatible release schedule. Use good commit messages in the process.
If you want save more time, the change log will tackle 90 % of the questions unanswered by the SemVer. These are NOT compilations of git logs by the way, because changelog readers are Humans, and not Machines. Just read the nice keep a changelog page.
This work has been supported by the EXCELLERAT project which has received funding from the European Union’s Horizon 2020 research and innovation program under grant agreement No 823691.
A. Dauptain, July 2020. Many thanks to G. Staffelbach, C. Lapeyre, L. Laberie and A. Suau for their comments.