Adding custom properties to TFS build templates

To add custom fields into a TFS build template, you need to merge in the following sections:

<Activity>
  <x:Members>
    <x:Property Name="YourProperty" Type="InArgument(x:String)" />
  </x:Members>
 
  <this:Process.Metadata>
    <mtbw:ProcessParameterMetadataCollection>
      <mtbw:ProcessParameterMetadata Category="#400 GroupName" Description="Property Description" DisplayName="Display Name" ParameterName="Parameter Name" />
    </mtbw:ProcessParameterMetadataCollection>
  </this:Process.Metadata>
 
  <Sequence.Variables>
    <Variable x:TypeArguments="x:String" Name="MSBuildProperties" />
  </Sequence.Variables>
  <Sequence DisplayName="Update Build Arguments" mtbwt:BuildTrackingParticipant.Importance="Low">
    <Assign x:TypeArguments="x:String" mtbwt:BuildTrackingParticipant.Importance="None" To="[MSBuildProperties]" Value="[String.Format(&quot;{0} /p:YourProperty=&quot;&quot;{0}&quot;&quot;&quot;, MSBuildProperties, YourProperty.Replace(&quot;\&quot;, &quot;\\&quot;))]" />
  </Sequence>
 
</Activity>

Then update all instances of the <mtbwa:MSBuild /> tags to reference this additional variable, e.g.

<mtbwa:MSBuild CommandLineArguments="[String.Format(&quot;/p:SkipInvalidConfigurations=true {0} {1} &quot;, MSBuildArguments, MSBuildProperties)]" Configuration="[platformConfiguration.Configuration]" DisplayName="Run MSBuild for Project" GenerateVSPropsFile="[True]" MaxProcesses="[If (MSBuildMultiProc, 0, 1)]" OutDir="[BinariesDirectory]" Platform="[platformConfiguration.Platform]" Project="[localBuildProjectItem]" mva:VisualBasic.Settings="Assembly references and imported namespaces serialized as XML namespaces" Targets="[New String() { &quot;Clean&quot; }]" TargetsNotLogged="[New String() {&quot;GetNativeManifest&quot;, &quot;GetCopyToOutputDirectoryItems&quot;, &quot;GetTargetPath&quot;}]" ToolPlatform="[MSBuildPlatform]" Verbosity="[Verbosity]" />
 
<mtbwa:MSBuild CommandLineArguments="[String.Format(&quot;/p:SkipInvalidConfigurations=true {0} {1} &quot;, MSBuildArguments, MSBuildProperties)]" Configuration="[platformConfiguration.Configuration]" DisplayName="Run MSBuild for Project" GenerateVSPropsFile="[True]" LogFileDropLocation="[logFileDropLocation]" MaxProcesses="[If (MSBuildMultiProc, 0, 1)]" OutDir="[outputDirectoryPerProject]" Platform="[platformConfiguration.Platform]" Project="[localProject]" RunCodeAnalysis="[RunCodeAnalysis]" mva:VisualBasic.Settings="Assembly references and imported namespaces serialized as XML namespaces" TargetsNotLogged="[New String() {&quot;GetNativeManifest&quot;, &quot;GetCopyToOutputDirectoryItems&quot;, &quot;GetTargetPath&quot;}]" ToolPlatform="[MSBuildPlatform]" Verbosity="[Verbosity]" />

The results look something like this:

Example of a customized build template

Example of a customized build template

Whilst the replace isn’t strictly necessary, it’s a good habit to get into to avoid getting stung by common things like file-paths later.