
The versioning problem was significant part of my work for the last 6 years. During that time we wrote a versioning library used for automatic bump of versioning of various schemas. On several occasions I was doing talks and materials on versioning, including my blog post on combinatorial explosion and another one on minor component separation in SemVer and also slides from one of the talks available here.
Recently I started following closely Package URL (PURL) project which contains among other ideas Vers (version range specification). I believe this is a great project and based on that I would like to describe here my updated understanding of the versioning problem in terms of dimensions.
Since the versioning problem is actually huge, I am quite certain there will be further updates to this understanding in the future. Still I find what follows good enough for today.
1st Dimension – Versioning Schema
Version schema is a subject that I dedicated most of my time so far. In example, popular versioning standard – Semantic Versioning 2.0.0 or SemVer utilizes the following schema
MAJOR.MINOR.PATCH-IDENTIFIER+METADATA
Where Identifier and Metadata parts are optional. Additional requirements for each schema component are described in the standard.
Alternatively, there are various Calendar Versioning (CalVer) schemas, for example, Ubuntu flavor of CalVer looking as
YY.0M.Micro
Where YY stands for 2 digit year and 0M stands for 0-padded month. I.e. 25.02.1 is a valid Ubuntu flavor CalVer.
For non-main branches, we found it to be a good policy, to use the
Branch.Micro
schema. So that a valid version could be my-version-branch.5 .
There are many other schemas and approaches used in the industry. Although, frequently they re-use elements from the mainstream approaches described above with certain additions.
It is important to note here, that the first dimension being Schema is only Schema – meaning given a set of characters, we can establish whether it matches certain version schema representation or not.
2nd Dimension – Version Increment Rules
Next dimension is how versions are incremented between releases. While standards like SemVer may have rather specific rules, in practice those rules may or may not be respected. In practice this is usually a result of lack of clarity how to apply standard rules.
In example, per SemVer specification any Patch updates must be compatible with a client using API level access. In other words, nothing on the client should have to change unless Minor version changes. However, I recently encountered a Patch level library update that would introduce stricter checks on certain documented behaviours that would break somewhat non-compliant implementations. While one may argue that this is a grey area, it is almost impossible to prevent such use-cases given The Law of Leaky Abstractions.
In other examples, sometimes I see SemVer projects version incremented via Identifier (i.e. 0.1.0-1 < 0.1.0-2) – while this is valid, it may not fit the versioning policies or recommendations of the versioning standard. More so, I sometimes see versions incremented via Metadata (i.e. 0.1.0+1 < 0.1.0+2) – which directly contradicts the SemVer standard, as Metadata must not be used in version increment or comparison.
3rd Dimension – Ordering Comparison Rules
The third dimension is how we compare versions. While increment rules may be somewhat arbitrary, we have to be strict about comparison.
For example, a Maven project may follow SemVer schema, but if a version has -SNAPSHOT identifier it should be treated as lower version than -alpha identifier – but that would contradict the SemVer standard. Another example is pypi
versioning having specific rules on pre-releases.
Vers project does a great job of listing various comparison standards used in package managers.
Summary
From above, it appears clear that versioning schema, version increment rules and comparison rules constitute 3 distinct dimensions. For the same schema, we may have differing increment rules and even further different comparison rules – which makes otherwise very similar versioning policies incompatible.
The key implication of this is difficulty in creating common registry of software assets. Such registry is required for comprehensive dependency tracking – needed to achieve cyber security compliance.
In simpler terms, without solving the versioning problem reasonably well, it is very difficult to answer questions such as “Is my dependency using the latest available version?” across the spectre of dependencies.
Other consequences of the problem include unexpected breaking changes between versions, the problem especially big in mission-critical applications.
As tooling improves, we can expect better containment of the versioning problem. It is hard to imagine though that the problem as a whole would be fully solved in the foreseeable future.