1

I have a property group which includes a property for the build_number which is being passed in from TeamCity as solely the Build Counter. The build number format being set in TeamCity as simply {0} for the counter.

<PropertyGroup>
  <Major>10</Major>
  <Minor>1</Minor>
  <Build>$(BUILD_NUMBER)</Build>
  <Release>0</Release>
   ...
</PropertyGroup>

The Major, Minor and Release properties are then updated from values in a file in source control.

So that TeamCity logs the build as the full 4 part build reference (not just the counter), I set it thus:

<TeamCitySetBuildNumber BuildNumber="$(Major).$(Minor).$(Build).$(Release)" />

However, now when I reference my $(Build) property, it's now set to the 4 part build reference, and any property I have made which makes reference to $(BUILD_NUMBER) prior to setting using TeamCitySetBuildNumber also gets overwritten with the 4 part reference.

NB I've also changed it with a system message:

<Message Text="##teamcity[buildNumber '$(Major).$(Minor).$(Build).$(Release)']" />

but the overall effect is the same.

How Can I refer to the build counter (only) AFTER I have set the BuildNumber above?

abatishchev
  • 98,240
  • 88
  • 296
  • 433
Fetchez la vache
  • 4,940
  • 4
  • 36
  • 55
  • Why dont you just change the format in teamcity to 10.1.{0}.0 then you just use BuildNumber=$(BUILD_NUMBER)? – James Woolfenden Oct 18 '12 at 15:29
  • @JamesWoolfenden That would certainly work, but (rightly or wrongly) currently our setup is to amend the [Major].[Minor] part via a file which is in source control. Certainly this is the fallback position if I can't get a satisfactory conclusion. – Fetchez la vache Oct 18 '12 at 16:09
  • have you tried the assemblyinfo task in the msbuild extension pack. id give that a go. – James Woolfenden Oct 18 '12 at 17:35

1 Answers1

2

If you're using a project file, you could try calling the TeamCitySetBuildNumber command in the AfterBuild section of the *.vbproj or *.csproj file:

<Target Name="AfterBuild">
    <TeamCitySetBuildNumber BuildNumber="$(Major).$(Minor).$(Build).$(Release)" />
</Target>

If you're using a solution file, I'd create a *.proj file that calls your solution file and then after that call the TeamCitySetBuildNumber command (not sure if you can call the TeamCitySetBuildNumber command within the target like this though...):

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="SetBuildNumber">

<PropertyGroup>
  <Major>10</Major>
  <Minor>1</Minor>
  <Build>$(BUILD_NUMBER)</Build>
  <Release>0</Release> 
</PropertyGroup>

  <Target Name="Build">
    <Message Text="Build task called... " Importance="high"/>
    <MSBuild Projects="$(teamcity_build_checkoutDir)\your_solution.sln" Properties="Configuration=Release"/>
  </Target>

  <Target Name="SetBuildNumber" DependsOnTargets="Build">
    <Message Text="Setting build number back to TeamCity... " Importance="high"/>
    <TeamCitySetBuildNumber BuildNumber="$(Major).$(Minor).$(Build).$(Release)" />
  </Target>

</Project>
mattyB
  • 1,094
  • 10
  • 21
  • Hi MattyB, appreciate the answer. I am using a proj file, but the thing with setting the build number later on in the process is that if it fails before this step, then the log again refers to the build counter, and not the 4 part reference, which is why I'm setting the build number in the first target. – Fetchez la vache Oct 18 '12 at 10:13
  • 1
    So, do you want something like a 'finally' block that'll be called regardless of whether the build succeeds or not? If so try this: [try…finally equivalent in MsBuild](http://stackoverflow.com/questions/1313412/try-finally-equivalent-in-msbuild) – mattyB Oct 18 '12 at 10:38
  • Not seen that before. Handy. Ultimately unless I restructure my project that won't work however. Rightly or wrongly (!) my proj file has 8 targets, each called in turn by 8 TeamCity build steps, so that if step 3 fails it doesn't continue, which is what I want (the log also states "[Step 3/8]" etc which is handy ). As I see it, I'd need to restructure it so there was 1 TC build step, and then rework things to add checks that made sure the previous target worked ok before doing anything, whsich isn't really what I'm after. TC seems to lack a definition of "Best Practices" that I have found... – Fetchez la vache Oct 18 '12 at 11:01