Semantic Versioning 2.0.0

Published on: 25 Jul 2016 by: Michael Richardson
Octopus welcomes F# to the family!

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

Pre-Releases

In SemVer 1.0.0, the pre-release version was restricted to alpha-numberic characters and dashes [0-9A-Za-z-].

For example, 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 1.0.0-alpha2.

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

 1.0.0-alpha.1

Or even

 1.0.0-alpha.1.5.20

And precedence works as you would expect:

 1.0.0-alpha.8
 1.0.0-alpha.9
 1.0.0-alpha.10

Build Metadata

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

Acme.Web.1.0.0-featureA

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.

For example:

1.0.0+featureA
1.0.0-alpha.1+31ef756

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. 1.0.0+featureA != 1.0.0+featureB != 1.0.0.

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.

Octopus

Releases

Within Octopus Deploy, you are now able to use SemVer 2.0.0 versions for Release Numbers.

SemVer 2.0.0 pre-releases

Packages

Octopus Deploy 3.4 will also allow you to use packages versioned using SemVer 2.0.0.

SemVer 2.0.0 package created

SemVer 2.0.0 package uploaded

NuGet Packages

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!