I’ve recently headed up a new project at work and we’ve switched from using a fairly arcane system of numbering our builds based on the svn build number and the phases of the moon to Semantic Versioning, or “SemVer” for short.
Full information about Semantic Versioning can be found here. It is a well established standard for dealing with the difficulties of dependencies. The basics are as follows:
A semantic version consists of three numbers, representing Major, Minor and Patch releases. These are in the format:
Each number conveys some meaning to the user about what has changed in the update.
- The Major version should be incremented whenever a breaking change is introduced.
- The Minor version should be incremented whenever a new feature is added but backwards compatibility is maintained.
- The Patch version should in incremented whenever a bug fix is added but backwards compatibility is maintained.
This means that when you see the version number change for a dependency which uses semvar, you’re given some important context information about what the change means for you. If the patch number changes, then you should know the change is limited to bug fixes – feel free to update to the newer version without worrying about anything changing or breaking. If the minor version changes then similarly you can feel safe in updating, but you might want to check to see what new features have been added. If the major version changes then you can expect breaking changes – you may need to do some work to keep your code working if you update to the latest version.
There are tools for working with SemVer in pretty much every language. On my home machine (running Windows) you can install semver from Ruby using:
gem install semver
(By the way, to install Ruby on your Windows machine I’d recommend using Chocolatey as it’ll also allow you to easily install the dev kit using the following packages: ruby, ruby2.devkit. The dev kit will be needed later in this article for working with the Albacore gem in Rake).
To create a new SemVer file use:
This will create a .semver file, which can live at the root of the solution, with the following contents:
<pre>--- :major: 0 :minor: 0 :patch: 0 :special: ''
To increment the patch version use:
semver inc patch
To increment the minor version use:
semver inc minor
Note that incrementing the Minor version resets the Patch version back to zero.
To increment the major version use:
semver inc major
Note that incrementing the Major version resets both the Minor and Patch versions back to zero.
This is all well and good, but how do I use the semvar file to actually version a .NET project?
The Semantic Version will be used within our build process by Rake. Rake is a build language which can be used to define tasks which help you build, test and deploy code. These tasks are stored within a rakefile, which is simply a Ruby file that can be stored alongside your .semver file at the root of your solution. We’d previously used MsBuild as our build language, but that has proved to often be painful as it involves working with verbose XML files, whilst Rake uses a comparatively clean domain specific language. If you ever need to do any complex or unusual then you have the entire Ruby language at your disposal. However Rake isn’t just for Ruby projects – by using a gem called Albacore, Rake can work with .NET tools like NUnit, MsBuild and (in our new project’s case) Mono’s xBuild.
(To be continued with examples of wiring Rake up to use the semvar file to automatically version a .NET project).