Jul 1, 2010

MSBuild Properties in TFS 2010

In a TFS 2010 build running on the default workflow template, we can access some of the build properties at runtime within an MSBuild project file. Use the GetBuildProperties task in your target to get the initial values of the build number, the build definition name, etc.
Checkout this task in
$(MSBuildExtensionsPath)\Microsoft\VisualStudio\TeamBuild\Microsoft.TeamFoundation.Build.targets to get the complete list of properties that can be accessed.

Note:
Pass this as an MSBuild Argument in your build definition's advanced settings:
TeamBuildRefPath="C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\PrivateAssemblies"
Else, the build might fail with this error:
The "Microsoft.TeamFoundation.Build.Tasks.GetBuildProperties" task could not be loaded from the assembly \PrivateAssemblies\Microsoft.TeamFoundation.Build.ProcessComponents.dll

Apr 1, 2010

Recursive Targets

Here's a way to "recursively" call an MSBuild target for unique items in a list:


Output:

Jan 18, 2010

The Script Task in MSBuild

As part of your build process customization, you may sometimes prefer invoking a simple piece of C# or VB code to relatively elaborate MSBuild script segments while implementing certain functionalities.
In case you are not interested in writing your own custom tasks and compiling them into a dll for these small customization needs, MSBuild Community Tasks has a Script task for such cases

Sticking to tradition, let's go with a 'hello world' example:


<Import Project="$(MSBuildExtensionsPath)/MSBuildCommunityTasks/MSBuild.Community.Tasks.Targets" />
<PropertyGroup>
  <Text1>Hello</Text1>
  
  <GetFullText>
    <![CDATA[
      public static string ScriptMain()  {
        string Text2 = "World";
        return "$(Text1)" + Text2;
      }
    ]]>
  </GetFullText>
</PropertyGroup>

<Target Name="TestScriptTask">
    <Script Language="C#" Code="$(GetFullText)">
        <Output TaskParameter="ReturnValue" PropertyName="FullText" />
    </Script>
    <Message Text="My String: $(FullText)" />
</Target>
     
The return type of ScriptMain() can be void or string.
Now, the auto-generated code and the build output would look something like this:

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
    
public class msbc96d6fb42e75a487c93c422f4f56a72da {      
    public static string ScriptMain() {
        string Text2 = "World";
  
        return "Hello" + Text2;
    }        
}
  
Done executing task "Script".
Task "Message"
    My String: HelloWorld