views:

992

answers:

1

I want to adjust the output from my TeamCity build configuration of my class library so that the produced dll files have the following version number: 3.5.0.x, where x is the subversion revision number that TeamCity has picked up.

I've found that I can use the BUILD_NUMBER environment variable to get x, but unfortunately I don't understand what else I need to do.

The "tutorials" I find all say "You just add this to the script", but they don't say which script, and "this" is usually referring to the AssemblyInfo task from the MSBuild Community Extensions.

Do I need to build a custom MSBuild script somehow to use this? Is the "script" the same as either the solution file or the C# project file?

I don't know much about the MSBuild process at all, except that I can pass a solution file directly to MSBuild, but what I need to add to "the script" is XML, and the solution file decidedly does not look like XML.

So, can anyone point me to a step-by-step guide on how to make this work?


This is what I ended up with:

  1. Install the MSBuild Community Tasks
  2. Edit the .csproj file of my core class library, and change the bottom so that it reads:

    <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
    <Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets" />
    <Target Name="BeforeBuild">
      <AssemblyInfo Condition=" '$(BUILD_NUMBER)' != '' "
          CodeLanguage="CS"
          OutputFile="$(MSBuildProjectDirectory)\..\GlobalInfo.cs"
          AssemblyVersion="3.5.0.0"
          AssemblyFileVersion="$(BUILD_NUMBER)" />
    </Target>
    <Target Name="AfterBuild">
    

  3. Change all my AssemblyInfo.cs files so that they don't specify either AssemblyVersion or AssemblyFileVersion (in retrospect, I'll look into putting AssemblyVersion back)

  4. Added a link to the now global GlobalInfo.cs that is located just outside all the project
  5. Make sure this file is built once, so that I have a default file in source control

This will now update GlobalInfo.cs only if the environment variable BUILD_NUMBER is set, which it is when I build through TeamCity.

I opted for keeping AssemblyVersion constant, so that references still work, and only update AssemblyFileVersion, so that I can see which build a dll is from.

+4  A: 

The CSPROJ file is effectively an MSBuild file.

Unload the relevant class project in VS.NET, edit it and uncomment the BeforeBuild target. Add the FileUpdate MSBuild task from the MSBuild Community Extensions.

In your MSBuild file, you can retrieve the BUILD_NUMBER from TeamCity by using the environment variable $(build_vcs_number_1). Note that you may want to create an additional Configuration for 'Production' which' condition you check for, as this will obviously not work when you build locally.

Simply use that as input for the FileUpdate task's ReplacementText property.

Note that if your revisions numbers go above the 65535 mark (UInt16), you cannot use it in the AssemblyVersion attribute.

What I'd suggest you use instead though, is AssemblyInformationalVersion, which is just a string that does not have that limitation. Unless of course you are confident that you won't hit this revision upper boundary, but that seems a dodgy way of going about it.

Alternatively, you can devise a way (a.b.c.d being your version number) of using revision div 1000 for c and revision mod 1000 for d.

Wim Hollebrandse