views:

2854

answers:

2

I am wondering if there is a way to synchronize the build numbers (20080213.1) without using the BuildNumberOverrideTarget where I would have to generate my own build number? I basically want to use the default/built-in tfs buildnumber generator but want to access it to align my assembly versions with it. Can this be done and is it a sensible way to do it this way?

+2  A: 

Yes you can. At some point, possibly at AfterGet, you can use the BuildNumber and create a custom task to update the AssemblyInfo.cs files in your source code.

We've hooked into AfterGet and caused our target to be dependant:

<Target Name="AfterGet" DependsOnTargets="VersionAssemblies" />

Our VersionAssemblies Target pulls all of the AssemblyInfo.cs files from $(SolutionRoot):

<CreateItem Include="$(SolutionRoot)\**\AssemblyInfo.cs;">
    <Output TaskParameter="Include" ItemName="AssemblyInfos"/>
 </CreateItem>

checks them out:

<Exec Command="$(TfCommand) checkout &quot;AssemblyInfo.cs&quot; -r"
          WorkingDirectory="$(MSBuildProjectDirectory)\..\sources" ContinueOnError="true"/>

edits them and replaces the file version with the $(BuildNumber):

<File.Replace Path="%(AssemblyInfos.FullPath)"
                  NewValue="AssemblyFileVersion(&quot;$(BuildNumber)&quot;)"
                  RegularExpression="AssemblyFileVersion\(\&quot;(\d+.\d+.\d+.\d+)\&quot;\)"
                  IgnoreCase="true"
                  Force="true"/>

and then checks the files back in:

<Exec Command="$(TfCommand) checkin /override:&quot;Automated&quot; /comment:&quot;Update AssemblyInfo files to version number $(BuildNumber) - $(NoCICheckinComment) &quot; /noprompt &quot;AssemblyInfo.cs&quot; /recursive"
          WorkingDirectory="$(MSBuildProjectDirectory)\..\sources" ContinueOnError="false"/>

For the replacement of the file versions I use the File.Replace task that comes with the Microsoft SDC tasks on CodePlex.

Also note, that if you have a build that is triggered on a checkin, when checking in the AssemblyInfo.cs files, make sure the comment includes $(NoCICheckinComment) as this causes TFS not to trigger another build otherwise you'll end up in an infinite build loop.

Ray Booysen
How do you pull the build and revision from $(BuildNumber) as it is by default of the format "MyBuildDefinition_20090213.1"?
Fadeproof
You could write a custom task to strip out the MyBuildDefinition_ part and strip it out.
Ray Booysen
A: 

What you are asking for is very sensible and there are a number of ways to achieve this.

Personally, when I do this I don't like to check the files in to version control that have the build server generated number in them - it just introduces too many head-aches when merging code across branches but also I like a known version number to be used when a developer does a workstation build vs a proper build server derived assembly to make it really easy to tell them apart.

For more information on how I like to do it, take a look at the TFS Build Recipies wiki:

or my blog post on the topic

Hope that helps,

Martin.

Martin Woodward
Thank you Martin. I had already come across your excellent post on the alignment and have used that method. When you say you like a known version number to be used on developer builds you mean that those would be the ones from the assembly info file without any overrides? say 1.0.0.0?
Fadeproof
For developers do you only use the VS build or do you use build scripts that developers should use on their workstations?
Fadeproof
For developers I only use the VS build. I sometimes use Developer Workstation builds using the TeamBuild script - however VS builds tend to be able to do the job 90% of the time and makes things much simpler.In answer to your earlier comment, I indeed use 1.0.0.0 in the AssemblyInfo files.
Martin Woodward