«

Dec
30

The Versioning Problem

Just as I published this, I came across a new posting today by Phil Haack (creator of NuGet) and have changed the guidelines accordingly

Where I work, and I’m sure in many places, versioning software has always been a problem. There were different conflicting ways used to version our frameworks and API’s, or worse using no versioning used at all. Effectively, we had our own version (excuse the pun) of DLL hell.

I was recently charged with resolving, or at least reducing, the problems we had by coming up with some versioning guidelines. I decided to base our guidelines heavily on the Semantic Versioning Guidelines which are, in my opinion, a very clear set of rules to follow when versioning programmatic interfaces. Unfortunately I have yet to find a good way of applying them to visual interfaces or find a set a guidelines that deal with visual interfaces.

We are primarily a .Net house and as such use Visual Studio 2010 as our development environment and since the release of NuGet earlier this year have been using that as our package management system for our internal frameworks. On top of that we use the very venerable Git as our source control system. So finding good versioning guidelines is only part of the problem, tying them in with our existing work flow is harder. The guidelines I’ve written here are my attempt to pull together all these technologies to help aid our development process.

Basic Principals

For the sake of completeness I’ve included the Semantic Versioning Guidelines we use below. They have been slightly modified to suit our needs. The latest official version can be found on their website.

  1. Software using Semantic Versioning MUST declare a public API. This API could be declared in the code itself or exist strictly in documentation. However it is done, it should be precise and comprehensive.
  2. A normal version number MUST take the form X.Y.Z where X, Y, and Z are non-negative integers. X is the major version, Y is the minor version, and Z is the patch version. Each element MUST increase numerically by increments of one. For instance: 1.9.0 -> 1.10.0 -> 1.11.0.
  3. When a major version number is incremented, the minor version and patch version MUST be reset to zero. When a minor version number is incremented, the patch version MUST be reset to zero. For instance: 1.1.3 -> 2.0.0 and 2.1.7 -> 2.2.0.
  4. Once a versioned package has been released, the contents of that version MUST NOT be modified. Any modifications must be released as a new version.
  5. Major version zero (0.y.z) is for initial development. Anything may change at any time. The public API should not be considered stable.
  6. Version 1.0.0 defines the public API. The way in which the version number is incremented after this release is dependent on this public API and how it changes.
  7. Patch version Z (x.y.Z | x > 0) MUST be incremented if only backwards compatible bug fixes are introduced. A bug fix is defined as an internal change that fixes incorrect behaviour.
  8. Minor version Y (x.Y.z | x > 0) MUST be incremented if new, backwards compatible functionality is introduced to the public API. It MUST be incremented if any public API functionality is marked as deprecated. It MAY be incremented if substantial new functionality or improvements are introduced within the private code. It MAY include patch level changes. Patch version MUST be reset to 0 when minor version is incremented.
  9. Major version X (X.y.z | X > 0) MUST be incremented if any backwards incompatible changes are introduced to the public API. It MAY include minor and patch level changes. Patch and minor version MUST be reset to 0 when major version is incremented.
  10. A pre-release version MAY be denoted by appending a dash and an identifier immediately following the patch version. The identifier MUST be comprised of only ASCII alphanumerics and dash [0-9A-Za-z-]. Pre-release versions satisfy but have a lower precedence than the associated normal version. Examples: 1.0.0-alpha, 1.0.0-alpha1, 1.0.0-0-3-7, 1.0.0-x-7-z-92.
  11. Precedence MUST be calculated by separating the version into major, minor, patch and pre-release identifiers in that order. Major, minor, and patch versions are always compared numerically. Pre-release version precedence MUST be determined by comparing the identifier as follows: identifiers consisting of only digits are compared numerically and identifiers with letters or dashes are compared lexically in ASCII sort order. Numeric identifiers always have lower precedence than non-numeric identifiers. Example: 1.0.0-0-3-7 < 1.0.0-alpha < 1.0.0-alpha-1 < 1.0.0-beta-2 < 1.0.0-beta-11 < 1.0.0-rc-1 < 1.0.0.

Visual Studio and Version Numbers

  1. AssemblyVersion, AssemblyFileVersion and AssemblyInformationalVersion MUST be specified in the AssemblyInfo.vb or AssemblyInfo.cs files.
  2. AssemblyVersion and AssemblyFileVersion version numbers MUST have the same value.
  3. AssemblyVersion and AssemblyFileVersion version numbers are defined within Visual Studio and MUST be in the form of X.Y.Z.B where X,Y and Z are defined by the basic principals and B is the build number.
  4. Build version B (x.y.z.B) MUST NOT be incremented under any circumstances and MUST remain at 0.
  5. AssemblyInformationalVersion MUST be in form X.Y.Z where  X, Y and Z are specified in the basic principals and are the same X, Y and Z values of the AssemblyVersion and AssemblyFileVersion version numbers.
  6. Pre-release version numbers MAY be included in the AssemblyInformationalVersion in the format specified in the basic principals e.g. 1.3.4-rc-1.

NuGet and Version Numbers

  1. Projects built and pushed using NuGet MUST follow the Visual Studio version number guidelines. NuGet gets the version number from the AssemblyInformationalVersion in Visual Studio.

Git and Version Numbers

  1. As soon as a new version is released the commit that version was built from MUST be tagged in Git and pushed to the central repository for that project.
  2. Release version commits MUST be on the master branch and the testing releases MUST NOT be on the master branch.
  3. Tags MUST be in the form of vX.Y.Z or <assembly name>-vX.Y.Z if there are multiple projects in a repository. If there is a pre-release associated with the version is should be appended to the version number e.g. v1.0.1-beta.1.

Permanent link to this article: http://www.jamestoyer.me.uk/2011/12/30/the-versioning-problem/