blog.reis.se

It's all about looks

In the first part I wrote about how to get the version number that is available in TeamCity into the assemblies that are built and also how to maintain the dynamic unit testing feedback. I will now continue to explain how to get the complete chain working up until naming the finished package.

Propagating the version number

I left out one bit of MSBuild script that is vital for the next step. How can you transfer a version number from one project to another? Well, it’s actually quite simple, just save it as a text file among your artifacts and you can read it back up in a property in your MSBuild files. This is what it looks like in the MSBuild script:

<WriteLinesToFile File="SoftwareVersion.txt"
Lines="$(BUILD_NUMBER)"
Overwrite="true" />

This gives you a file named SoftwareVersion.txt that you can save as an artifact and use in the following build projects, how simple some solutions are.

File renaming and creating a package

The good thing about about MSBuild is all the extra things around just executing builds, in combination to the WriteLinesToFile there is of course a ReadLinesFromFile, and as you guessed this will read lines from files. These lines can be stored in an item collection (for many lines) or a property (that’s what we are after) like this:

<ReadLinesFromFile File="$(ReleaseDir)\SoftwareVersion.txt">
<Output TaskParameter="Lines"
PropertyName="Version" />
</ReadLinesFromFile>

Now we have what we need to get the version that was built in one project to control the name of a file in another project. The renaming part is easy.Actually there are no rename task but you can of course execute a command directly with the Exec task so renaming will look like this:

<Exec Command="rename $(ReleaseDir)\SoftwareServiceSetup.msi
SoftwareServiceSetup-$(Version).msi" />

Transferring TeamCity versions to Subversion tags

Last is to get the labels created back into subversion (as it is that I’m currently working with, it is what I know well). It is easy to just add the labels in TeamCity. The settings are placed under Version control settings in Build Configuration step two.

However, there might be a mix-up on where you want to save your tags, this is set under the VCS root configuration. The default is set to trunk=>tags but this hasn’t worked for the setup I have. Instead I have to set this to /trunk=>/tags, and remember, don’t checkout the trunk locally it will be a big checkout…

So there you have it. Version numbers that follows every build from development, through testing and ending up on the subversion labels and the package names. Traceability that will make a configuration manager cry with joy.

// Håkan Reis


Last time I posted on MSBuild and TeamCity I showed how you could use it to deploy remotely in Deploy with MSBuild and custom targets Part 1 and Part 2. There are one issue that’s always a part of professional projects - version handling. I will show you a way to let the version get into the assemblies and trickle through all build steps all the way to the production package. In the first part I will concentrate on getting the version number into the assemblies while keeping unit test feedback, where currently running tests are directly visible in TeamCity.

Setting the version in TeamCity

First off is to set the version and build number in TeamCity. This is one of the easiest parts. Just go into the General settings for the project and set up the version number format and the build counter setting. like this:

versionNumber

Now we have something to base our versioning on, the first part 1.0.2. are static and you update that manually as you start a new release, etc. The last {0} will give you a build number, you get the idea.

Getting the version number to the assemblies

Next step is to make sure the version number from TeamCity is used to build the assemblies and added instead of the Assembly, File and Product Version set in the visual studio project properties. But first some background.

When the assemblies are built version values are automatically set from AssemblyInfo.cs files. If nothing is set, it will get the value of 0.0.0.0, file version will get the same version as in Assembly Version and application version will follow the file version. More about this in Assembly version, File version, Product version. The basics is that if we want to control the version we must make sure the AssemblyVersion attribute  is in there. I would suggest setting it to 0.0.0.0 to make it easy to identify if anything fails to update. You could even have safeguards for it in code, aborting execution if the version is zeroed.

Now you have to make sure you change this number after the checkout but before the build has started. This calls for a shift from solution building to using MSBuild. But for the basic solution to build you only need one line of MSBuild script:

<MSBuild Projects="Software.sln"

Targets="Rebuild"

Properties="Configuration=Release;" />

That’s easy enough. Moving on to the version, we first collect the AssemblyInfo.cs files in the solution and then rewrite the version number with the TeamCity number. As it happens, there are a build property available containing the TeamCity number: $(BUILD_NUMBER). To get the build number into the assembly info we can use a task called FileUpdate that is part of a collection of open source MSBuild tasks, it will look like this:

<!— Collect the Assembly info files in the solution –>

<ItemGroup>

<AssemblyInfoFiles

Include="**/Properties/**/AssemblyInfo.cs;" />

</ItemGroup>

 

<!—Identify current AssemblyVersion and replace -–>

<FileUpdate Files="@(AssemblyInfoFiles)"

Regex=’AssemblyVersion\(“.*”\)\]’

ReplacementText=’AssemblyVersion(“$(BUILD_NUMBER)”)]’ />

This will get the desired result, with all assemblies carrying the correct version number. However, it will also give as a new problem; we now loose the unit test feedback in TeamCity, but we can solve that in the next step.

Unit testing with feedback

When you move from solution based execution to MSBuild based, the first issue you come across is that the unit tests are missing. The natural step is to make the MSBuild script execute them. Normally you would call nunit-console or maybe the NUnit task. But that will only give you a file to display as an artifact. Not the direct and continuous feedback you get from TeamCity. Fortunately TeamCity will provide a unit test runner task that can be used instead. The following lines need to be in the MSBuild script:

<!-- Integreate with TC's nunit runner –>

<UsingTask TaskName="NUnit"

AssemblyFile="$(teamcity_dotnet_nunitlauncher_msbuild_task)" />

 

<!-- Select the assemblies to test –>

<ItemGroup>

<TestAssemblies Include="**/release/*UnitTest*.dll;"

Exclude="**\obj\**;" />

</ItemGroup>

 

<!-- Execute the tests –>

<NUnitTeamCity Assemblies="@(TestAssemblies)" />

Read more about the NUnitTeamCity task on the TeamCity wiki, where you find information on how to execute it in 32bit, categories, on specific versions of NUnit, etc. Now we have all the parts to handle versions and still get the feedback. This also opens up some more opportunities as we now execute the build from MSBuild. We can do some pre- and post-processing around the build like zipping up files or exchange files or data after checkout but before build.

Next step is to get the version numbers across to the next project and use it for packaging as well as labeling our builds in subversion.

// Håkan Reis


dw_seminars Well, I just finished my session in Stockholm and as promised here are a set of links and the build scripts used in the presentation:

And you can also download the presentation as well as the msbuild scripts and msbuild tasks. And for some more information on remote deploy on servers, you can lock at a couple of earlier blog post - Deploy with MSBuild and custom targets part 1 and part 2. Have fun and don’t hesitate to contact me if you want more information

// Håkan Reis


This is a bit frustrating but planning can not help all the way. I have to tell you all that the session Continuation of continuous integration in Malmoe on Wednesday, April 1, have been moved to the day before. Tuesday, March 31. Nope no April fools day joke, I swear it’s the truth!

// Håkan Reis


Seminar in Gothenburg cancelled

Unfortunately I have to announce that the session Continuation of continuous integration has been cancelled for Gothenburg. I will still be in Malmoe, Linkoping and Stockholm, so now changes there.

I would love to give it in Gothenburg as well, but it’s out of my control. But who knows, I might show up in another context… :)

// Håkan Reis


TC-Logo_3I will be speaking  in Malmö, Göteborg, Linköping, and Stockholm in March/April. The subject will be build automation, some MSBuild and all done in TeamCity. The following abstract is in Swedish as the session will be in Swedish:

Continuation of continuous integration

Vad är nästa steg för dina automatiska byggen?

2009 års seminarier inleds med en närmare titt på hur man kan vidareutveckla automatiska bygge (Continuous Integration). I dag är de flesta medvetna om hur viktigt ett versionshanteringssystem som Subversion eller Team Foundation Server är. Oftast har man också insett hur viktigt det är att alltid ha byggbar kod, så man har gått vidare med periodiska, eller ännu hellre kontinuerliga byggen. Men i förlängningen vill man ständigt ha en leverans redo.

Vi tittar på hur man kan hantera kodanalys, integrationstester, release och automatisk installation. Fokus kommer att ligga på att utföra detta i en lösning från JetBrains - TeamCity. Men vi kommer inte ensidigt titta på TeamCity utan även på verktygen runt detta samt hur man kan utnyttja MSBuild för mer än att bara kompilera koden.

Bland annat kommer vi gå in på:

  • Vad kommer efter kontinuerliga byggen
  • Artifakthantering och beroende mellan byggen
  • Tricks MSBuild och custom tasks

If there are any other topics that are of interest I can still make room for changes in my material so feel free to contact me.

You can also register for any of the events, and don’t forget to mention where and date.

// Håkan Reis