Alan Dean

CTO, Developer, Agile Practitioner

Photograph of Alan Dean

Friday, June 25, 2010

Consistent Assembly Versioning

Personally, I like to have consistent versioning applied to all assemblies from the same build. Doing this manually is a PITA so I version from my build file and I have a pattern which I apply to achieve this. I typically use subversion for my source control and I will use the Cavity project as an example:

Subversion project structure

I build from the trunk folder:

Subversion trunk folder

I have a batch file for each ‘potted’ configuration I want and, of course, the MSBuild file. Here is the release batch file:

MSBUILD build.xml /p:Configuration=Release
PAUSE

In order to apply consistent versioning, I want to emit a Build.cs file and then link that to each project. If I want this to be a static number, I can simply configure the version directly and use AssemblyInfo task from the MSBuild Community Tasks Project:

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Run" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
    <Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets" />

    <PropertyGroup>
        <Configuration Condition="'$(Configuration)'==''">Release</Configuration>
        <Version Condition="'$(Version)'==''">1.2.3.4</Version>
    </PropertyGroup>

    <Target Name="Run">
        <CallTarget Targets="Clean" />
        <CallTarget Targets="Build" />
    </Target>

    <Target Name="Clean">
        <MSBuild
            Projects="$(MSBuildProjectDirectory)\src\Cavity.sln"
            Targets="Clean"
            Properties="Configuration=$(Configuration)"
        />
    </Target>

    <Target Name="Versioning">
        <AssemblyInfo
            CodeLanguage="CS"
            OutputFile="$(MSBuildProjectDirectory)\src\Build.cs"
            AssemblyVersion="$(Version)"
            AssemblyFileVersion="$(Version)"
            AssemblyInformationalVersion="$(Version)"
            />
    </Target>

    <Target Name="Build" DependsOnTargets="Versioning">
        <MSBuild
            Projects="$(MSBuildProjectDirectory)\src\Cavity.sln"
            Targets="Rebuild"
            Properties="Configuration=$(Configuration)">
            <Output
                TaskParameter="TargetOutputs"
                ItemName="CodeAssemblies"
                />
        </MSBuild>
    </Target>

</Project>

This will emit the following Build.cs:

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:4.0.30319.1
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

using System;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

[assembly: AssemblyVersion("1.2.3.4")]
[assembly: AssemblyFileVersion("1.2.3.4")]
[assembly: AssemblyInformationalVersion("1.2.3.4")]

However, I normally use the subversion Revision number as the build number to be able to identify what was built. To do this you will need to install the CollabNet Subversion client in order to be able to query the subversion repository. Once installed, you can then use the following build file to emit a dynamic version number by utilising the SvnVersion task:

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Run" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
    <Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets" />

    <PropertyGroup>
        <Configuration Condition="'$(Configuration)'==''">Release</Configuration>
        <Version Condition="'$(Version)'==''">1.2.3</Version>
        <Revision>0</Revision>
    </PropertyGroup>

    <Target Name="Run">
        <CallTarget Targets="Clean" />
        <CallTarget Targets="Build" />
    </Target>

    <Target Name="Clean">
        <MSBuild
            Projects="$(MSBuildProjectDirectory)\src\Cavity.sln"
            Targets="Clean"
            Properties="Configuration=$(Configuration)"
            />
    </Target>

    <Target Name="Versioning">
        <SvnVersion LocalPath=".">
            <Output TaskParameter="Revision" PropertyName="Revision" />
        </SvnVersion>
        <AssemblyInfo
            CodeLanguage="CS"
            OutputFile="$(MSBuildProjectDirectory)\src\Build.cs"
            AssemblyVersion="$(Version).$(Revision)"
            AssemblyFileVersion="$(Version).$(Revision)"
            AssemblyInformationalVersion="$(Version).$(Revision)"
            />
    </Target>

    <Target Name="Build" DependsOnTargets="Versioning">
        <MSBuild
            Projects="$(MSBuildProjectDirectory)\src\Cavity.sln"
            Targets="Rebuild"
            Properties="Configuration=$(Configuration)">
            <Output
                TaskParameter="TargetOutputs"
                ItemName="CodeAssemblies"
                />
        </MSBuild>
    </Target>

</Project>

No comments: