Fork me on GitHub

Version Task and Executable

Motivation

Manual versioning of assemblies is tedious and error-prone. Especially in a continuous deployment environment, versions have to be calculated automatically and environment agnostic.

The Version MSBuild task and executable of Appccelerate solves this problem for you.

Features

Road Map

The current implementation is very limited and copes badly with incorrect usage! This is the road map for improvement:

Specifying a version

A version is specified using a tag on a commit in git. The name of the tag has to follow one of the following version patterns. All patterns have the prefix v= in common.

Commit Counting Pattern

You can specify that the number of commits since the tagged commit is part of the version. When you specify a tag as v=1.{0}.0 and there are 7 commits since the tagged commit, the version will be 1.7.0.0.

When using commit counting by specifying {<base>} as a part of the version, the placeholder will be replaced with base + commits since.

In the following sample, the resulting version for head is 3.5.0.0 (version is always extended to contain 4 parts).

Version sample

When you want to use commit counting in the pre-release version part for nuget packages, you can specify how many digits should be used. For example v=1.0-pre{0000} with 15 commits since the tag results in 1.0.0-pre0015 (nuget version) and 1.0.0.0 (assembly version). This guarantees correct version ordering with the current nuget implementation of Semantic Versioning (SemVer).

Fix Version Pattern

You can set a fix version for a commit by tagging it with a fix version (a version without commit counting placeholder). E.g. v=2.3.4.

If there are commits since this tag, the version task or executable will throw an exception.

Specifying a seperate file version

If you want the file version to be different from the assembly version, you can extend the pattern of the tag with ;fv=. For example v=1.{0};fv=1.1.{0}.

Semantic Versioning, Assembly Version, Nuget Version, Informational Version

The version task and executable calculate three versions: assembly version, nuget version and informational version.

The assembly version is always a version with 4 parts: <major>.<minor>.<patch>.0 The forth part is always 0.

The nuget version is always a version with 3 parts (SemVer) and an optional pre-relase part: <major>.<minor>.<patch>[-<pre-release>] If you specify a version pattern with only one or two parts, 0s will be used.

See Nuget Versioning for more information.

The informational version is built using the annotated message of the tag (for more information about tagging in git see Git-Basics-Tagging.

You can use placeholders to insert the calculated version. There exist the following two placeholders (case sensitive):

The informational version is empty if the tag has no annotated message.

Examples

version patterncommits since tagannotated messageresulting
assembly/file
version
resulting nuget versionresulting informational version
v=1.201.2.0.01.2.0
v=1.21error!error!
v=1.{2}51.7.0.01.7.0
v=1.{2}5RC 1 Build: {version}1.7.0.01.7.0RC 1 Build: 1.7.0.0
v=1.{2}5RC 1 Build: {nugetVersion}1.7.0.01.7.0RC 1 Build: 1.7.0
v=1.{2}-pre5RC 1 Build: {nugetVersion}1.7.0.01.7.0-preRC 1 Build: 1.7.0-pre
v=1.2-rc{0000}5RC 1 Build: {nugetVersion}1.2.0.01.2.0-rc0005RC 1 Build: 1.2.0-rc0005

GitVersion Task

The Appccelerate.GitVersionTask is a MSBuild task than can be used to version assemblies during building.

The task will set the assembly, file and informational version. Therefore, you need to delete the corresponding attributes from the AssemblyInfo.cs (AssemblyVersion, AssemblyFileVersion, AssemblyInformationalVersion). Otherwise an error will occur.

There is currently no way to have different assembly and file versions.

Installation

You can install the version task into a project using nuget. The package id is Appccelerate.VersionTask.

GitVersion Executable

The Appccelerate.Version executable is a console application that writes the calculated version(s) to the console.

Usage:

path: path pointing inside a git repository (does not have to be the root).

--output: optional, defines what output to write. Specifying nugetversion results in an output only containing the nuget version. This simplifies parsing.

Examples

Writing all calculated versions as json to the console:

Writing only the nuget version to the console:

Installation

Using NuGet

You can install the version executable using nuget. The package id is Appccelerate.Version. The executable can be found at tools\Appccelerate.Version.exe

Using Chocolatey

When you want to install the version executable with Chocolatey, use the following command:

You have to specify the source because the package is not listed on the chocolatey gallery.

TeamCity Integration

Add a powershell build step with the following code:

This will install the version executable, run it and set the calculated nuget version as the build number.

The build number can later be used to set for example the version of a created nuget package.

Samples

All projects of Appccelerate use the Appccelerate.Version.Task. Take a look at the code at GitHub.

Branching, Pull Requests

Appccelerate.Version does not consider the name of the current branch. It only checks whether it is a GitHub pull request.

If it is a pull request, the nuget version will contain the pre-release version part -commit<hash>. Any existing pre-release version part will be overwritten.

If you work with several branches (e.g. release branches), we suggest to branch and then tag both branches.

Example:

If this sounds too complicated, consider one of the alternatives below.

Alternatives

GitVersion is a better alternative if you follow GitFlow as a branching strategy. GitVersion also offers support for GitHubFlow (but I had some problems with it and therefore built Appccelerate.Version). It deals with release and hot-fix branches automatically.

Appccelerate.Version works best in continuous deployment scenarios with a single master branch in the main repository and pull requests. You can push to master in the main repository, you can integrate pull requests (versioned as pre-releases for nuget) and use any kind of branching strategy. However you have to make sure that you don't give the same version number to commits on different branches.