Using assembly version as TeamCity build number throughout build chain

Let’s say you want to use the version number that is compiled into your assembly as the build number in a TeamCity build chain and label your sources with that build number as last step.

This post will show you how to accomplish that.

1: the Visual Studio part

1.1 Add the AssemblyVersion attribute to a Visual Studio project (dll).

image

This follows the <major version>.<minor version>.<build number>.<revision> format where <revision> is a random incremental number which will uniquely identify the build (we will use that as our label later on).

1.2 Next up you need to add a couple of things to the MSBuild process (edit project file accomplishes that).

1.2.1 First of all, you only want to “instruct” TC when the build executes on the TC build server. The following goes into the top of your project file.

  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <TeamCityBuild>false</TeamCityBuild>

....

 <PropertyGroup Condition=" '$(TEAMCITY_BUILD_PROPERTIES_FILE)' != ''">
    <TeamCityBuild>true</TeamCityBuild>
  </PropertyGroup>

Default set the TeamCityBuild property to false (line 4). Then check whether a TC “only” property exists (line 8) and if so, set the property to true (line 9).

1.2.2 By doing this we can make sure that we only run this (see below) target while on the TC build server.

  <Target Name="TeamCity" AfterTargets="Build" Condition=" '$(TeamCityBuild)'=='true'">
    <GetAssemblyIdentity AssemblyFiles="obj\$(ConfigurationName)\$(TargetFileName)">
      <Output TaskParameter="Assemblies" ItemName="AssemblyIdentity" />
    </GetAssemblyIdentity>
    <Message Text="##teamcity[buildNumber '%(AssemblyIdentity.Version)']" />
  </Target>
</Project>

There are numerous ways of “sending” messages to TC. The “##teamcity[…]” syntax seen above is called a service message and this service message instructs TC to set the build number.

The build number value we send to TC is extracted from the current assembly (after it has been compiled AfterTargets=”Build”) through the GetAssembyIdentity task which we feed with current project assembly output. From that assembly we pick the Version property  which will hold 2.12.0.[some unique incremental number]

Now we have “enabled” sending the assembly version number to TC.

2: the TeamCity part

2.1 In TC we have a build chain consisting of 5 steps. That last step will label the sources and the first step compiles the sources.

image

2.1.1 In order for the build number to “flow” throughout the chain we will need the following dependency chain of build numbers:

  • 1.5 uses 1.4 build number
  • 1.4 uses 1.3 build number
  • 1.3 uses 1.2 build number
  • 1.2 uses 1.1 build number

image

In TC you can use the build number format for that. The screenshot above shows 1.2 which “pulls” in the build number from 1.1 (bt13).

2.1.1.1 The build type id for a configuration/build can be figured out by hovering the build definition of clicking on it and looking in the address bar.

image

2.2 The first build configuration in the chain, 1.1, will however not change anything from the defaults

image

Since that configuration compiles the project the MSBuild task will kick in and tell TC to change the build number, thus putting in the assembly version instead.

2.3 The last step is to label the sources if the whole chain was successful.

image

In the VCS settings of step 5, just use the build number of that build to label the sources if it was successful.

That’s it!

,

  1. #1 by Konstantin Samsonov on November 5, 2013 - 15:31

    You need edit VS project file ‘.xxproj’ in external editor, I prefer Notepad++

    text above has error in line:

    change to

    in field Build Number format you can set %build.number% and number of TeamCity Build completely equals project version
    add in Atrifact path value %system.teamcity.build.workingDir%\%env.TEAMCITY_PROJECT_NAME%\bin\debug => %env.TEAMCITY_PROJECT_NAME%-%build.number%.zip
    you also get zip with right version in name.

    You can install also add-in “http://autobuildversion.codeplex.com/” and project version will incremented on every build (support VS 2005, 2008, 2010).

  2. #2 by Konstantin Samsonov on November 5, 2013 - 15:34

    Some text cut by poster )))
    text above has error in line:
    GetAssemblyIdentity AssemblyFiles=”obj\$(ConfigurationName)\$(TargetFileName)”
    change to
    GetAssemblyIdentity AssemblyFiles=”bin\$(ConfigurationName)\$(TargetFileName)”

  3. #4 by Scott on April 8, 2014 - 20:07

    Is there a way to pass just the Major.Minor per the AssemblyIdentity. I noticed the Version property is just a string, but I’m unaware of any way to parse it from there.

    • #5 by Johan Leino on April 8, 2014 - 21:47

      You could probably do it in a msbuild task but I have nothing ready for you right now…search for some string splitting thing on the web related to msbuild perhaps?!

  1. TeamCity сквозная нумерация билдов по версии в проекте | Konstantin Samsonov

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: