Semantic Versioning 2.0.0
This post is a part of our Octopus 3.4 blog series. Follow it on our blog or our twitter feed.
Octopus Deploy 3.4 has shipped! Read the blog post and download it today!
Octopus 3.4 includes support for Semantic Versioning 2.0.0.
The significant changes in SemVer 2.0.0 relate to:
- pre-release versions
- build metadata
In SemVer 1.0.0, the pre-release version was restricted to alpha-numberic characters and dashes
1.0.0-alpha would represent an alpha pre-release of 1.0.0.
The major limitation of this comes as a result of clause 4 in the Semantic Versioning Specification:
Precedence SHOULD be determined by lexicographic ASCII sort order. For instance: 1.0.0-alpha1 < 1.0.0-beta1 < 1.0.0-beta2 < 1.0.0-rc1 < 1.0.0.
Suppose you have multiple versions of the alpha pre-release mentioned above:
1.0.0-alpha1 1.0.0-alpha2 1.0.0-alpha3 etc...
All is well; until you reach
1.0.0-alpha10. Lexicographic sort order places it before
A common work-around was to use something similar to
1.0.0-alpha0001. Not exactly elegant right? Oh yeah, and NuGet restricted the pre-release tag to 20 characters. So this solution was less than ideal.
From the Semantic Version 2.0.0 Specification clause 9:
A pre-release version MAY be denoted by appending a hyphen and a series of dot separated identifiers immediately following the patch version. Identifiers MUST comprise only ASCII alphanumerics and hyphen [0-9A-Za-z-].
And from clause 11:
Precedence for two pre-release versions with the same major, minor, and patch version MUST be determined by comparing each dot separated identifier from left to right until a difference is found as follows: identifiers consisting of only digits are compared numerically and identifiers with letters or hyphens are compared lexically in ASCII sort order. Numeric identifiers always have lower precedence than non-numeric identifiers. A larger set of pre-release fields has a higher precedence than a smaller set, if all of the preceding identifiers are equal. Example: 1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta < 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0.
In other words, we can have
And precedence works as you would expect:
1.0.0-alpha.8 1.0.0-alpha.9 1.0.0-alpha.10
Under SemVer 1.0.0, pre-release tags were used inconsistently.
In some cases, they were used for versioning (as mentioned above). In other cases they were used to attach metadata to the version. For example, a common pattern we saw from our customers was using the pre-release tag to indicate the code branch.
e.g. A package version of
would indicate the package was built from the
featureA code branch.
SemVer 2.0.0 introduces build metadata. From clause 10 of the spec:
Build metadata MAY be denoted by appending a plus sign and a series of dot separated identifiers immediately following the patch or pre-release version. Identifiers MUST comprise only ASCII alphanumerics and hyphen [0-9A-Za-z-].
This adds a component of the version that is explicitly used to attach metadata.
This is essentially a component of the version free from any pre-defined semantics. It is yours to assign whatever meaning you wish. The only interpretation Octopus Deploy applies is equality. i.e.
Is is important to note that the metadata component is not considered when determing precedence. For two versions that differ only by metadata, their precedence should be considered undefined.
Within Octopus Deploy, you are now able to use SemVer 2.0.0 versions for Release Numbers.
Octopus Deploy 3.4 will also allow you to use packages versioned using SemVer 2.0.0.
As of NuGet version 3.5 beta,
nuget.exe pack doesn't support creating NuGet packages with SemVer 2.0.0 versions.
The NuGet team intend to add SemVer 2.0.0 support at some point.
Support for consuming SemVer 2.0.0 NuGet packages has been added to Octopus Deploy. Additionally, we have added the ability to create NuGet packages with SemVer 2.0.0 versions to Octo.exe.
octo.exe pack --id=Acme.Web --version=1.5.0-alpha.1
This means that support will also be available to the 'Package' tasks of our various CI plugins (e.g. TeamCity, TFS).
These packages can be pushed to the built-in Octopus package repository. MyGet also accepts packages with SemVer 2.0.0 versions.
As of the publish-date of this post, we haven't implemented the ability to create SemVer 2.0.0 packages to OctoPack (OctoPack currently invokes NuGet.exe directly). If this is something you particularly want, please provide us with that feedback.
Happy semantically-versioned deployments!