GitVersion and NuGet - Unexpected Version Ordering

285 views Asked by At

I have a project that is packaged up using nuget and saved to DevOps Artifacts.

I have a current develop version of say 1.0.0-alpha.1 and I create a new branch feature/Branch1. The build process runs and creates a new version 1.0.0-branch1 and, if I merge that branch back in to develop I get 1.0.0-alpha.2.

The problem stats when I look at the nuget feed in VS; it is showing 1.0.0-branch1 as a more recent prerelease branch than 1.0.0-alpha.2.

This is an abbreviated set to steps that resulted in this...

The numbers identify the order the branches were created

The numbers indicate the order that the versions were actually created.

Are my expectations wrong? All I'm doing when it comes to specifying the package version is setting it to GitVersion.NugetVersion (although you can see that I've tried some other options too)

1

There are 1 answers

0
zivkan On

NuGet implements Semantic Versioning 2.0.0. Well, technically it extends SemVer2 because the very first version of NuGet used System.Version. So, when SemVer2 support was added, it was a superset of both version formats.

Anyway, from the SemVer2 spec:

  1. Precedence refers to how versions are compared to each other when ordered.
    1. Precedence MUST be calculated by separating the version into major, minor, patch and pre-release identifiers in that order (Build metadata does not figure into precedence).

    2. Precedence is determined by the first difference when comparing each of these identifiers from left to right as follows: Major, minor, and patch versions are always compared numerically.

      Example: 1.0.0 < 2.0.0 < 2.1.0 < 2.1.1.

    3. When major, minor, and patch are equal, a pre-release version has lower precedence than a normal version:

      Example: 1.0.0-alpha < 1.0.0.

    4. 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:

      1. Identifiers consisting of only digits are compared numerically.
      2. Identifiers with letters or hyphens are compared lexically in ASCII sort order.
      3. Numeric identifiers always have lower precedence than non-numeric identifiers.
      4. 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.

Lexically "alpha" < "another" < "azure" < "more", so the sort order in your question's screenshot is sorting the versions correctly as per the SemVer2 spec.

You can change the order of your prerelease segments to get the order you desire, plus remember to separate the numeric from alphabetic characters with a . to ensure that numbers don't require leading zeros to be sorted correctly. For example 1.7.0-11.alpha, 1.7.0-11.another-new-bran.1, 1.7.0-11.another-new-bran.2, 1.7.0-14.alpha.