Team Build 2010 generic post processing scripting


My team is switching from the 2008 style builds to the workflow builds in 2010. We have a lot of customized post build activities. We wanted to preserve the legacy .cmd files that run the show, but still get the automatic symbol management in the new default template. Adding a node in the workflow turned out to be quite an adventure. It's great stuff, but really bleeding edge right now. I can't wait till some really good books can be written about this stuff. This post is just a few of the points I ran across.

Challenge #1 - See my previous post on pure XAML actions not getting loaded. http://blogs.msdn.com/b/dustin_andrews/archive/2010/08/31/tf215097-cannot-create-unknown-type-when-using-pure-xaml-actions.aspx

Challenge #2 - XAML Namespaces. If you load the defualt template with custom actions into the designer of VS2010, it will wreck them.

Challenge #3 - Getting the post processing script the data that it needs about the build directory and drop location.

Challenge #4 - Everything has to be checked in to test the workflow. The development cycle was pretty slow. You can do some mocking, but for this activity you need to just slog through. Solution: I recomend a private TFS server to run your tests on. I managed to crash my build controller once while changing the path to custom assemblies.

Challenge #2. Namespace.

This is the error spam I got when I tried to run my new activity on the build server.

The build process failed validation. Details:  Validation Error: The private implementation of activity '1: DynamicActivity' has the following validation error:   Compiler error(s) encountered processing expression "WorkspaceName.Length > Microsoft.TeamFoundation.VersionControl.Common.RepositoryConstants.MaxWorkspaceNameSize". 'Common' is not a member of 'VersionControl'.  Validation Error: The private implementation of activity '1: DynamicActivity' has the following validation error:   Compiler error(s) encountered processing expression "WorkspaceName.Substring(0, Microsoft.TeamFoundation.VersionControl.Common.RepositoryConstants.MaxWorkspaceNameSize).TrimEnd()". 'Common' is not a member of 'VersionControl'.  Validation Error: The private implementation of activity '1: DynamicActivity' has the following validation error:   Compiler error(s) encountered processing expression "String.Format("The workspace name '{0}' exceeds the maximum allowed limit of '{1}' characters. Truncating it to match the maximum limit.", WorkspaceName, Microsoft.TeamFoundation.VersionControl.Common.RepositoryConstants.MaxWorkspaceNameSize)". 'Common' is not a member of 'VersionControl'. 

 

Solution:

I also had to change the "common" namespace to my own namespace. This is the one the VS2010 unhelpfully changes back all the time. You have to load your template in the project with your custom actions in order to use the designer. The designer is a little aggressive about namespaces and formatting. There may be a viable workaround with a second solution, but if you want to work in the designer you will have to edit the XAML by hand before it will work on the server again. Worse, the compare feature in VS2010 is line by line, which makes seeing the diff really hard until you hand edit the XML to make it more readable. (For XML it should load the DOM and go node-by-node IMHO.)

Challenge #3. Post processing data.

Solution: Pass in the build drop location and build location. Use some fancy .cmd scripting to get the scripts running in the root of the drop directory.

PostProcess.cmd:

@echo off
REM %1 is always the droplocation for the build.
REM Change directory to the dir of the script since the build will run it in C:\windows\system32
pushd %1
ECHO Current Directory is
cd
ECHO Running as
whoami.exe
ECHO BuildDirectory = %BuildDirectory%

REM Add post proccessing commands here 
 

Source Code

DefaultTemplateWithPostProcessScripting.xaml:

<Activity mc:Ignorable="sap" x:Class="TfsBuild.Process" 
this:Process.BuildSettings="[New Microsoft.TeamFoundation.Build.Workflow.Activities.BuildSettings()]" 
this:Process.TestSpecs="[New Microsoft.TeamFoundation.Build.Workflow.Activities.TestSpecList(New Microsoft.TeamFoundation.Build.Workflow.Activities.TestAssemblySpec( &quot;**\*test*.dll&quot;))]" 
this:Process.BuildNumberFormat="[&quot;$(BuildDefinitionName)_$(Date:yyyyMMdd)$(Rev:.r)&quot;]" 
this:Process.CleanWorkspace="[Microsoft.TeamFoundation.Build.Workflow.Activities.CleanWorkspaceOption.All]" 
this:Process.RunCodeAnalysis="[Microsoft.TeamFoundation.Build.Workflow.Activities.CodeAnalysisOption.AsConfigured]" 
this:Process.SourceAndSymbolServerSettings="[New Microsoft.TeamFoundation.Build.Workflow.Activities.SourceAndSymbolServerSettings(True, Nothing)]" 
this:Process.AgentSettings="[New Microsoft.TeamFoundation.Build.Workflow.Activities.AgentSettings() With {.MaxWaitTime = New System.TimeSpan(4, 0, 0), .MaxExecutionTime = New System.TimeSpan(0, 0, 0), .TagComparison = Microsoft.TeamFoundation.Build.Workflow.Activities.TagComparison.MatchExactly }]" 
this:Process.AssociateChangesetsAndWorkItems="[True]" 
this:Process.CreateWorkItem="[True]" 
this:Process.DropBuild="[True]" 
this:Process.MSBuildPlatform="[Microsoft.TeamFoundation.Build.Workflow.Activities.ToolPlatform.Auto]" 
this:Process.PerformTestImpactAnalysis="[True]" this:Process.CreateLabel="[True]" this:Process.DisableTests="[False]" 
this:Process.Verbosity="[Microsoft.TeamFoundation.Build.Workflow.BuildVerbosity.Normal]" 
this:Process.SupportedReasons="All" 
          xmlns="http://schemas.microsoft.com/netfx/2009/xaml/activities" 
          xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
          xmlns:mt="clr-namespace:Microsoft.TeamFoundation;assembly=Microsoft.TeamFoundation.Common" 
          xmlns:mtbc="clr-namespace:Microsoft.TeamFoundation.Build.Client;assembly=Microsoft.TeamFoundation.Build.Client" 
          xmlns:mtbw="clr-namespace:Microsoft.TeamFoundation.Build.Workflow;assembly=Microsoft.TeamFoundation.Build.Workflow" 
          xmlns:mtbwa="clr-namespace:Microsoft.TeamFoundation.Build.Workflow.Activities;assembly=Microsoft.TeamFoundation.Build.Workflow" 
          xmlns:mtbwt="clr-namespace:Microsoft.TeamFoundation.Build.Workflow.Tracking;assembly=Microsoft.TeamFoundation.Build.Workflow" 
          xmlns:mttbb="clr-namespace:Microsoft.TeamFoundation.TestImpact.BuildIntegration.BuildActivities;assembly=Microsoft.TeamFoundation.TestImpact.BuildIntegration" 
          xmlns:mtvc="clr-namespace:Microsoft.TeamFoundation.VersionControl.Client;assembly=Microsoft.TeamFoundation.VersionControl.Client" 
          xmlns:mtvcc="clr-namespace:Microsoft.TeamFoundation.VersionControl.Common;assembly=Microsoft.TeamFoundation.VersionControl.Common" 
          xmlns:t="clr-namespace:BuildActivityPack;assembly=BuildActivityPack"
          xmlns:mva="clr-namespace:Microsoft.VisualBasic.Activities;assembly=System.Activities" 
          xmlns:s="clr-namespace:System;assembly=mscorlib" 
          xmlns:sa="clr-namespace:System.Activities;assembly=System.Activities" 
          xmlns:sad="clr-namespace:System.Activities.Debugger;assembly=System.Activities" 
          xmlns:sap="http://schemas.microsoft.com/netfx/2009/xaml/activities/presentation" 
          xmlns:scg="clr-namespace:System.Collections.Generic;assembly=mscorlib" 
          xmlns:sl="clr-namespace:System.Linq;assembly=System.Core" 
          xmlns:this="clr-namespace:TfsBuild" 
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <x:Members>
    <x:Property Name="BuildSettings" Type="InArgument(mtbwa:BuildSettings)" />
    <x:Property Name="TestSpecs" Type="InArgument(mtbwa:TestSpecList)" />
    <x:Property Name="BuildNumberFormat" Type="InArgument(x:String)" />
    <x:Property Name="CleanWorkspace" Type="InArgument(mtbwa:CleanWorkspaceOption)" />
    <x:Property Name="RunCodeAnalysis" Type="InArgument(mtbwa:CodeAnalysisOption)" />
    <x:Property Name="SourceAndSymbolServerSettings" Type="InArgument(mtbwa:SourceAndSymbolServerSettings)" />
    <x:Property Name="AgentSettings" Type="InArgument(mtbwa:AgentSettings)" />
    <x:Property Name="AssociateChangesetsAndWorkItems" Type="InArgument(x:Boolean)" />
    <x:Property Name="CreateWorkItem" Type="InArgument(x:Boolean)" />
    <x:Property Name="DropBuild" Type="InArgument(x:Boolean)" />
    <x:Property Name="MSBuildArguments" Type="InArgument(x:String)" />
    <x:Property Name="MSBuildPlatform" Type="InArgument(mtbwa:ToolPlatform)" />
    <x:Property Name="PerformTestImpactAnalysis" Type="InArgument(x:Boolean)" />
    <x:Property Name="CreateLabel" Type="InArgument(x:Boolean)" />
    <x:Property Name="DisableTests" Type="InArgument(x:Boolean)" />
    <x:Property Name="GetVersion" Type="InArgument(x:String)" />
    <x:Property Name="PrivateDropLocation" Type="InArgument(x:String)" />
    <x:Property Name="Verbosity" Type="InArgument(mtbw:BuildVerbosity)" />
    <x:Property Name="Metadata" Type="mtbw:ProcessParameterMetadataCollection" />
    <x:Property Name="SupportedReasons" Type="mtbc:BuildReason" />
    <x:Property Name="ServerPathToScript" Type="InArgument(x:String)" />
    <x:Property Name="ScriptArguments" Type="InArgument(x:String)" />
  </x:Members>
  <this:Process.MSBuildArguments>
    <InArgument x:TypeArguments="x:String" />
  </this:Process.MSBuildArguments>
  <this:Process.GetVersion>
    <InArgument x:TypeArguments="x:String" />
  </this:Process.GetVersion>
  <this:Process.Metadata>
    <mtbw:ProcessParameterMetadataCollection>
      <mtbw:ProcessParameterMetadata BrowsableWhen="Always" Category="Post Process" Description="The server path to the post process script &quot;$/Main/.../Script&quot;." DisplayName="Server Path To Script" ParameterName="ServerPathToScript" />
      <mtbw:ProcessParameterMetadata BrowsableWhen="Always" Category="Post Process" Description="Arguements for the post process script" DisplayName="Script Arguments" ParameterName="ScriptArguments" />
    </mtbw:ProcessParameterMetadataCollection>
  </this:Process.Metadata>
  <mva:VisualBasic.Settings>Assembly references and imported namespaces serialized as XML namespaces</mva:VisualBasic.Settings>
  <Sequence sad:XamlDebuggerXmlReader.FileName="C:\Users\dustinan\Documents\Visual Studio 2010\Projects\BuildActivityPack\BuildActivityPack\SandboxScriptingBuildProcessTemplate.xaml" mtbwt:BuildTrackingParticipant.Importance="None" mva:VisualBasic.Settings="Assembly references and imported namespaces serialized as XML namespaces">
    <Sequence.Variables>
      <Variable x:TypeArguments="mtbc:IBuildDetail" Name="BuildDetail" />
    </Sequence.Variables>
    <mtbwa:GetBuildDetail DisplayName="Get the Build" mtbwt:BuildTrackingParticipant.Importance="Low" Result="[BuildDetail]" />
    <Sequence DisplayName="Update Drop Location" mtbwt:BuildTrackingParticipant.Importance="Low">
      <mtbwa:InvokeForReason DisplayName="Update Build Number for Triggered Builds" Reason="Triggered">
        <mtbwa:UpdateBuildNumber BuildNumberFormat="[BuildNumberFormat]" DisplayName="Update Build Number" />
      </mtbwa:InvokeForReason>
      <If Condition="[DropBuild AndAlso (BuildDetail.Reason And Microsoft.TeamFoundation.Build.Client.BuildReason.Triggered) = BuildDetail.Reason]" DisplayName="If DropBuild And Build Reason is Triggered" mtbwt:BuildTrackingParticipant.Importance="Low">
        <If.Then>
          <Sequence mtbwt:BuildTrackingParticipant.Importance="None">
            <If Condition="[String.IsNullOrEmpty(BuildDetail.DropLocationRoot)]" DisplayName="If DropLocationRoot is empty" mtbwt:BuildTrackingParticipant.Importance="Low">
              <If.Then>
                <Throw DisplayName="Throw EmptyDropLocationRootException" Exception="[New Microsoft.TeamFoundation.Build.Workflow.Activities.EmptyDropLocationRootException(BuildDetail.BuildDefinition.Name)]" mtbwt:BuildTrackingParticipant.Importance="Low" />
              </If.Then>
            </If>
            <mtbwa:SetBuildProperties DisplayName="Set Drop Location" DropLocation="[BuildDetail.DropLocationRoot + &quot;\&quot; + BuildDetail.BuildDefinition.Name + &quot;\&quot; + BuildDetail.BuildNumber]" mtbwt:BuildTrackingParticipant.Importance="Low" PropertiesToSet="DropLocation" />
            <mtbwa:CreateDirectory Directory="[BuildDetail.DropLocation]" DisplayName="Create the Drop Location" mtbwt:BuildTrackingParticipant.Importance="Normal" />
          </Sequence>
        </If.Then>
      </If>
      <If Condition="[DropBuild AndAlso BuildDetail.Reason = Microsoft.TeamFoundation.Build.Client.BuildReason.ValidateShelveset]" DisplayName="If DropBuild And Build Reason is ValidateShelveset" sap:VirtualizedContainerService.HintSize="611,420" mtbwt:BuildTrackingParticipant.Importance="Low">
        <If.Then>
          <If Condition="[Not String.IsNullOrEmpty(PrivateDropLocation)]" sap:VirtualizedContainerService.HintSize="464,314" mtbwt:BuildTrackingParticipant.Importance="None">
            <If.Then>
              <Sequence sap:VirtualizedContainerService.HintSize="231,208" mtbwt:BuildTrackingParticipant.Importance="None">
                <sap:WorkflowViewStateService.ViewState>
                  <scg:Dictionary x:TypeArguments="x:String, x:Object">
                    <x:Boolean x:Key="IsExpanded">True</x:Boolean>
                  </scg:Dictionary>
                </sap:WorkflowViewStateService.ViewState>
                <mtbwa:SetBuildProperties DisplayName="Set Drop Location for Private Build" DropLocation="[PrivateDropLocation + &quot;\&quot; + BuildDetail.BuildDefinition.Name + &quot;\&quot; + BuildDetail.BuildNumber]" sap:VirtualizedContainerService.HintSize="200,22" mtbwt:BuildTrackingParticipant.Importance="Low" PropertiesToSet="DropLocation" />
                <mtbwa:CreateDirectory Directory="[BuildDetail.DropLocation]" DisplayName="Create the Drop Location" sap:VirtualizedContainerService.HintSize="200,22" mtbwt:BuildTrackingParticipant.Importance="Normal" />
              </Sequence>
            </If.Then>
            <If.Else>
              <mtbwa:WriteBuildWarning sap:VirtualizedContainerService.HintSize="208,208" Message="The build outputs for this private build will not be copied to the drop location because the PrivateDropLocation is not set." />
            </If.Else>
          </If>
        </If.Then>
      </If>
    </Sequence>
    <mtbwa:AgentScope DisplayName="Run On Agent" sap:VirtualizedContainerService.HintSize="633,1589" MaxExecutionTime="[AgentSettings.MaxExecutionTime]" MaxWaitTime="[AgentSettings.MaxWaitTime]" ReservationSpec="[AgentSettings.GetAgentReservationSpec()]" mva:VisualBasic.Settings="Assembly references and imported namespaces serialized as XML namespaces">
      <mtbwa:AgentScope.Variables>
        <Variable x:TypeArguments="mtbc:IBuildAgent" Name="BuildAgent" />
        <Variable x:TypeArguments="mtvc:Workspace" Name="Workspace" />
        <Variable x:TypeArguments="x:String" Name="BuildDirectory" />
        <Variable x:TypeArguments="x:String" Default="[BuildDetail.BuildNumber]" Name="LabelName" />
        <Variable x:TypeArguments="x:String" Name="WorkspaceName" />
        <Variable x:TypeArguments="x:String" Name="SourcesDirectory" />
        <Variable x:TypeArguments="x:String" Name="BinariesDirectory" />
        <Variable x:TypeArguments="x:String" Name="TestResultsDirectory" />
      </mtbwa:AgentScope.Variables>
      <Sequence DisplayName="Initialize Variables" sap:VirtualizedContainerService.HintSize="222,638" mtbwt:BuildTrackingParticipant.Importance="Low">
        <sap:WorkflowViewStateService.ViewState>
          <scg:Dictionary x:TypeArguments="x:String, x:Object">
            <x:Boolean x:Key="IsExpanded">True</x:Boolean>
          </scg:Dictionary>
        </sap:WorkflowViewStateService.ViewState>
        <mtbwa:GetBuildAgent DisplayName="Get the Agent" sap:VirtualizedContainerService.HintSize="200,22" mtbwt:BuildTrackingParticipant.Importance="Low" Result="[BuildAgent]" />
        <mtbwa:GetBuildDirectory DisplayName="Get the Build Directory" sap:VirtualizedContainerService.HintSize="200,22" mtbwt:BuildTrackingParticipant.Importance="Low" Result="[BuildDirectory]" />
        <Assign x:TypeArguments="x:String" DisplayName="Initialize Workspace Name" sap:VirtualizedContainerService.HintSize="200,22" mtbwt:BuildTrackingParticipant.Importance="Low" To="[WorkspaceName]" Value="[String.Format(&quot;{0}_{1}_{2}&quot;, BuildDetail.BuildDefinition.Id, Microsoft.TeamFoundation.LinkingUtilities.DecodeUri(BuildAgent.Uri.AbsoluteUri).ToolSpecificId, BuildAgent.ServiceHost.Name)]" />
        <Assign x:TypeArguments="x:String" DisplayName="Initialize Sources Directory" sap:VirtualizedContainerService.HintSize="200,22" mtbwt:BuildTrackingParticipant.Importance="Low" To="[SourcesDirectory]" Value="[String.Format(&quot;{0}\Sources&quot;, BuildDirectory)]" />
        <Assign x:TypeArguments="x:String" DisplayName="Initialize Binaries Directory" sap:VirtualizedContainerService.HintSize="200,22" mtbwt:BuildTrackingParticipant.Importance="Low" To="[BinariesDirectory]" Value="[String.Format(&quot;{0}\Binaries&quot;, BuildDirectory)]" />
        <Assign x:TypeArguments="x:String" DisplayName="Initialize TestResults Directory" sap:VirtualizedContainerService.HintSize="200,22" mtbwt:BuildTrackingParticipant.Importance="Low" To="[TestResultsDirectory]" Value="[String.Format(&quot;{0}\TestResults&quot;, BuildDirectory)]" />
        <If Condition="[Not BuildSettings.HasPlatformConfigurations]" DisplayName="If Not BuildSettings.HasPlatformConfigurations" sap:VirtualizedContainerService.HintSize="200,51" mtbwt:BuildTrackingParticipant.Importance="Low">
          <sap:WorkflowViewStateService.ViewState>
            <scg:Dictionary x:TypeArguments="x:String, x:Object">
              <x:Boolean x:Key="IsExpanded">False</x:Boolean>
              <x:Boolean x:Key="IsPinned">False</x:Boolean>
            </scg:Dictionary>
          </sap:WorkflowViewStateService.ViewState>
          <If.Then>
            <AddToCollection x:TypeArguments="mtbwa:PlatformConfiguration" Collection="[BuildSettings.PlatformConfigurations]" DisplayName="Use Default Platform Configuration" sap:VirtualizedContainerService.HintSize="269,100" mtbwt:BuildTrackingParticipant.Importance="Low" Item="[Microsoft.TeamFoundation.Build.Workflow.Activities.PlatformConfiguration.Default]" />
          </If.Then>
        </If>
        <If Condition="[WorkspaceName.Length &gt; Microsoft.TeamFoundation.VersionControl.Common.RepositoryConstants.MaxWorkspaceNameSize]" DisplayName="If WorkspaceName &gt; MaxSize" sap:VirtualizedContainerService.HintSize="200,51" mtbwt:BuildTrackingParticipant.Importance="Low">
          <sap:WorkflowViewStateService.ViewState>
            <scg:Dictionary x:TypeArguments="x:String, x:Object">
              <x:Boolean x:Key="IsExpanded">False</x:Boolean>
              <x:Boolean x:Key="IsPinned">False</x:Boolean>
            </scg:Dictionary>
          </sap:WorkflowViewStateService.ViewState>
          <If.Then>
            <Sequence sap:VirtualizedContainerService.HintSize="281,208" mtbwt:BuildTrackingParticipant.Importance="None">
              <sap:WorkflowViewStateService.ViewState>
                <scg:Dictionary x:TypeArguments="x:String, x:Object">
                  <x:Boolean x:Key="IsExpanded">True</x:Boolean>
                </scg:Dictionary>
              </sap:WorkflowViewStateService.ViewState>
              <mtbwa:WriteBuildWarning sap:VirtualizedContainerService.HintSize="200,22" Message="[String.Format(&quot;The workspace name '{0}' exceeds the maximum allowed limit of '{1}' characters. Truncating it to match the maximum limit.&quot;, WorkspaceName, Microsoft.TeamFoundation.VersionControl.Common.RepositoryConstants.MaxWorkspaceNameSize)]" />
              <Assign x:TypeArguments="x:String" DisplayName="Truncate WorkspaceName to MaxSize" sap:VirtualizedContainerService.HintSize="200,22" mtbwt:BuildTrackingParticipant.Importance="Low" To="[WorkspaceName]" Value="[WorkspaceName.Substring(0, Microsoft.TeamFoundation.VersionControl.Common.RepositoryConstants.MaxWorkspaceNameSize).TrimEnd()]" />
            </Sequence>
          </If.Then>
        </If>
      </Sequence>
      <Sequence DisplayName="Initialize Workspace" sap:VirtualizedContainerService.HintSize="222,543" mtbwt:BuildTrackingParticipant.Importance="Low">
        <sap:WorkflowViewStateService.ViewState>
          <scg:Dictionary x:TypeArguments="x:String, x:Object">
            <x:Boolean x:Key="IsExpanded">True</x:Boolean>
          </scg:Dictionary>
        </sap:WorkflowViewStateService.ViewState>
        <mtbwa:DeleteDirectory Directory="[TestResultsDirectory]" DisplayName="Delete Test Results Directory" sap:VirtualizedContainerService.HintSize="200,22" mtbwt:BuildTrackingParticipant.Importance="Normal" Recursive="[True]" />
        <If Condition="[Not CleanWorkspace = Microsoft.TeamFoundation.Build.Workflow.Activities.CleanWorkspaceOption.None]" DisplayName="If Not CleanWorkspace = CleanWorkspaceOption.None" sap:VirtualizedContainerService.HintSize="200,51" mtbwt:BuildTrackingParticipant.Importance="Low">
          <sap:WorkflowViewStateService.ViewState>
            <scg:Dictionary x:TypeArguments="x:String, x:Object">
              <x:Boolean x:Key="IsExpanded">False</x:Boolean>
              <x:Boolean x:Key="IsPinned">False</x:Boolean>
            </scg:Dictionary>
          </sap:WorkflowViewStateService.ViewState>
          <If.Then>
            <mtbwa:DeleteDirectory Directory="[BinariesDirectory]" DisplayName="Delete Binaries Directory" sap:VirtualizedContainerService.HintSize="269,100" mtbwt:BuildTrackingParticipant.Importance="Normal" />
          </If.Then>
        </If>
        <If Condition="[CleanWorkspace = Microsoft.TeamFoundation.Build.Workflow.Activities.CleanWorkspaceOption.All]" DisplayName="If CleanWorkspace = CleanWorkspaceOption.All" sap:VirtualizedContainerService.HintSize="200,51" mtbwt:BuildTrackingParticipant.Importance="Low">
          <sap:WorkflowViewStateService.ViewState>
            <scg:Dictionary x:TypeArguments="x:String, x:Object">
              <x:Boolean x:Key="IsExpanded">False</x:Boolean>
              <x:Boolean x:Key="IsPinned">False</x:Boolean>
            </scg:Dictionary>
          </sap:WorkflowViewStateService.ViewState>
          <If.Then>
            <Sequence DisplayName="Delete Workspace and Sources Directory" sap:VirtualizedContainerService.HintSize="281,208" mtbwt:BuildTrackingParticipant.Importance="Low">
              <sap:WorkflowViewStateService.ViewState>
                <scg:Dictionary x:TypeArguments="x:String, x:Object">
                  <x:Boolean x:Key="IsExpanded">True</x:Boolean>
                </scg:Dictionary>
              </sap:WorkflowViewStateService.ViewState>
              <mtbwa:DeleteWorkspace DeleteLocalItems="[True]" DisplayName="Delete Workspace" sap:VirtualizedContainerService.HintSize="200,22" mtbwt:BuildTrackingParticipant.Importance="Normal" Name="[WorkspaceName]" />
              <mtbwa:DeleteDirectory Directory="[SourcesDirectory]" DisplayName="Delete Sources Directory" sap:VirtualizedContainerService.HintSize="200,22" mtbwt:BuildTrackingParticipant.Importance="Normal" />
            </Sequence>
          </If.Then>
        </If>
        <mtbwa:CreateWorkspace BuildDirectory="[BuildDirectory]" Comment="[&quot;Workspace Created by Team Build&quot;]" DisplayName="Create Workspace" sap:VirtualizedContainerService.HintSize="200,22" Name="[WorkspaceName]" Result="[Workspace]" SourcesDirectory="[SourcesDirectory]" />
        <If Condition="[CleanWorkspace = Microsoft.TeamFoundation.Build.Workflow.Activities.CleanWorkspaceOption.Outputs]" DisplayName="If CleanWorkspace = CleanWorkspaceOption.Outputs" sap:VirtualizedContainerService.HintSize="200,51" mtbwt:BuildTrackingParticipant.Importance="Low">
          <sap:WorkflowViewStateService.ViewState>
            <scg:Dictionary x:TypeArguments="x:String, x:Object">
              <x:Boolean x:Key="IsExpanded">False</x:Boolean>
              <x:Boolean x:Key="IsPinned">False</x:Boolean>
            </scg:Dictionary>
          </sap:WorkflowViewStateService.ViewState>
          <If.Then>
            <ForEach x:TypeArguments="mtbwa:PlatformConfiguration" DisplayName="For Each Configuration in BuildSettings.PlatformConfigurations" sap:VirtualizedContainerService.HintSize="693,834" mtbwt:BuildTrackingParticipant.Importance="Low" Values="[BuildSettings.PlatformConfigurations]">
              <ActivityAction x:TypeArguments="mtbwa:PlatformConfiguration">
                <ActivityAction.Argument>
                  <DelegateInArgument x:TypeArguments="mtbwa:PlatformConfiguration" Name="platformConfiguration" />
                </ActivityAction.Argument>
                <Sequence DisplayName="Clean Configuration" sap:VirtualizedContainerService.HintSize="663,728">
                  <sap:WorkflowViewStateService.ViewState>
                    <scg:Dictionary x:TypeArguments="x:String, x:Object">
                      <x:Boolean x:Key="IsExpanded">True</x:Boolean>
                    </scg:Dictionary>
                  </sap:WorkflowViewStateService.ViewState>
                  <If Condition="[BuildSettings.HasProjectsToBuild]" DisplayName="If BuildSettings.HasProjectsToBuild" sap:VirtualizedContainerService.HintSize="641,604" mtbwt:BuildTrackingParticipant.Importance="Low">
                    <If.Then>
                      <ForEach x:TypeArguments="x:String" DisplayName="For Each Project in BuildSettings.ProjectsToBuild" sap:VirtualizedContainerService.HintSize="516,498" mtbwt:BuildTrackingParticipant.Importance="Low" Values="[BuildSettings.ProjectsToBuild]">
                        <ActivityAction x:TypeArguments="x:String">
                          <ActivityAction.Argument>
                            <DelegateInArgument x:TypeArguments="x:String" Name="serverBuildProjectItem" />
                          </ActivityAction.Argument>
                          <Sequence DisplayName="Clean Project" sap:VirtualizedContainerService.HintSize="486,392" mtbwt:BuildTrackingParticipant.Importance="Normal">
                            <Sequence.Variables>
                              <Variable x:TypeArguments="x:String" Name="localBuildProjectItem" />
                            </Sequence.Variables>
                            <sap:WorkflowViewStateService.ViewState>
                              <scg:Dictionary x:TypeArguments="x:String, x:Object">
                                <x:Boolean x:Key="IsExpanded">True</x:Boolean>
                              </scg:Dictionary>
                            </sap:WorkflowViewStateService.ViewState>
                            <mtbwa:ConvertWorkspaceItem DisplayName="Convert Server Paths to Local Paths" sap:VirtualizedContainerService.HintSize="464,22" mtbwt:BuildTrackingParticipant.Importance="Low" Input="[serverBuildProjectItem]" Result="[localBuildProjectItem]" Workspace="[Workspace]" />
                            <If Condition="[System.IO.File.Exists(localBuildProjectItem)]" DisplayName="If File.Exists(Project)" sap:VirtualizedContainerService.HintSize="464,206" mtbwt:BuildTrackingParticipant.Importance="Low">
                              <If.Then>
                                <mtbwa:MSBuild CommandLineArguments="[String.Format(&quot;/p:SkipInvalidConfigurations=true {0}&quot;, MSBuildArguments)]" Configuration="[platformConfiguration.Configuration]" DisplayName="Run MSBuild for Project" GenerateVSPropsFile="[True]" sap:VirtualizedContainerService.HintSize="269,100" 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]" />
                              </If.Then>
                            </If>
                          </Sequence>
                        </ActivityAction>
                      </ForEach>
                    </If.Then>
                  </If>
                </Sequence>
              </ActivityAction>
            </ForEach>
          </If.Then>
        </If>
        <mtbwa:SyncWorkspace DisplayName="Get Workspace" sap:VirtualizedContainerService.HintSize="200,22" mva:VisualBasic.Settings="Assembly references and imported namespaces serialized as XML namespaces" VersionOverride="[GetVersion]" Workspace="[Workspace]" />
      </Sequence>
      <If Condition="[CreateLabel]" DisplayName="If CreateLabel" sap:VirtualizedContainerService.HintSize="222,51" mtbwt:BuildTrackingParticipant.Importance="Low">
        <sap:WorkflowViewStateService.ViewState>
          <scg:Dictionary x:TypeArguments="x:String, x:Object">
            <x:Boolean x:Key="IsExpanded">False</x:Boolean>
            <x:Boolean x:Key="IsPinned">False</x:Boolean>
          </scg:Dictionary>
        </sap:WorkflowViewStateService.ViewState>
        <If.Then>
          <mtbwa:InvokeForReason DisplayName="Create and Set Label for non-Shelveset Builds" sap:VirtualizedContainerService.HintSize="281,208" Reason="Manual, IndividualCI, BatchedCI, Schedule, ScheduleForced, UserCreated">
            <mtbwa:LabelWorkspace Comment="[&quot;Label Created by Team Build&quot;]" DisplayName="Create Label" sap:VirtualizedContainerService.HintSize="200,22" Name="[LabelName]" Scope="[String.Format(&quot;$/{0}&quot;, BuildDetail.BuildDefinition.TeamProject)]" mva:VisualBasic.Settings="Assembly references and imported namespaces serialized as XML namespaces" Workspace="[Workspace]" />
            <mtbwa:SetBuildProperties DisplayName="Set Label on BuildDetail" sap:VirtualizedContainerService.HintSize="200,22" mtbwt:BuildTrackingParticipant.Importance="Low" LabelName="[String.Format(&quot;{0}@$/{1}&quot;, LabelName, BuildDetail.BuildDefinition.TeamProject)]" PropertiesToSet="LabelName" />
          </mtbwa:InvokeForReason>
        </If.Then>
      </If>
      <TryCatch DisplayName="Try Compile, Test, and Associate Changesets and Work Items" sap:VirtualizedContainerService.HintSize="222,51" mtbwt:BuildTrackingParticipant.Importance="Low">
        <sap:WorkflowViewStateService.ViewState>
          <scg:Dictionary x:TypeArguments="x:String, x:Object">
            <x:Boolean x:Key="IsExpanded">False</x:Boolean>
            <x:Boolean x:Key="IsPinned">False</x:Boolean>
          </scg:Dictionary>
        </sap:WorkflowViewStateService.ViewState>
        <TryCatch.Finally>
          <Sequence DisplayName="Revert Workspace and Copy Files to Drop Location" mtbwt:BuildTrackingParticipant.Importance="Low">
            <mtbwa:InvokeForReason DisplayName="Revert Workspace for Shelveset Builds" Reason="ValidateShelveset, CheckInShelveset">
              <mtbwa:RevertWorkspace DisplayName="Revert Workspace" Workspace="[Workspace]" />
            </mtbwa:InvokeForReason>
            <If Condition="[DropBuild AndAlso Not String.IsNullOrEmpty(BuildDetail.DropLocation)]" DisplayName="If DropBuild And DropLocation is Set" mtbwt:BuildTrackingParticipant.Importance="Low">
              <If.Then>
                <mtbwa:CopyDirectory Destination="[BuildDetail.DropLocation]" DisplayName="Copy Files to Drop Location" Source="[BinariesDirectory]" />
              </If.Then>
            </If>
          </Sequence>
        </TryCatch.Finally>
        <TryCatch.Try>
          <Sequence sap:VirtualizedContainerService.HintSize="1305,2295" mtbwt:BuildTrackingParticipant.Importance="None">
            <Sequence.Variables>
              <Variable x:TypeArguments="s:Exception" Name="compilationException" />
              <Variable x:TypeArguments="scg:IList(mtvc:Changeset)" Name="associatedChangesets" />
              <Variable x:TypeArguments="x:Boolean" Name="treatTestFailureAsBuildFailure" />
            </Sequence.Variables>
            <sap:WorkflowViewStateService.ViewState>
              <scg:Dictionary x:TypeArguments="x:String, x:Object">
                <x:Boolean x:Key="IsExpanded">True</x:Boolean>
              </scg:Dictionary>
            </sap:WorkflowViewStateService.ViewState>
            <Parallel DisplayName="Compile, Test, and Associate Changesets and Work Items" sap:VirtualizedContainerService.HintSize="1283,2051">
              <TryCatch DisplayName="Try Compile and Test" sap:VirtualizedContainerService.HintSize="665,2005" mtbwt:BuildTrackingParticipant.Importance="Low">
                <TryCatch.Try>
                  <Sequence DisplayName="Compile and Test" sap:VirtualizedContainerService.HintSize="647,1819">
                    <sap:WorkflowViewStateService.ViewState>
                      <scg:Dictionary x:TypeArguments="x:String, x:Object">
                        <x:Boolean x:Key="IsExpanded">True</x:Boolean>
                      </scg:Dictionary>
                    </sap:WorkflowViewStateService.ViewState>
                    <ForEach x:TypeArguments="mtbwa:PlatformConfiguration" DisplayName="For Each Configuration in BuildSettings.PlatformConfigurations" sap:VirtualizedContainerService.HintSize="625,1515" mtbwt:BuildTrackingParticipant.Importance="Low" Values="[BuildSettings.PlatformConfigurations]">
                      <ActivityAction x:TypeArguments="mtbwa:PlatformConfiguration">
                        <ActivityAction.Argument>
                          <DelegateInArgument x:TypeArguments="mtbwa:PlatformConfiguration" Name="platformConfiguration" />
                        </ActivityAction.Argument>
                        <Sequence DisplayName="Compile and Test for Configuration" sap:VirtualizedContainerService.HintSize="595,1409" mtbwt:BuildTrackingParticipant.Importance="Low">
                          <Sequence.Variables>
                            <Variable x:TypeArguments="x:String" Name="outputDirectory" />
                            <Variable x:TypeArguments="x:String" Name="logFileDropLocation" />
                          </Sequence.Variables>
                          <sap:WorkflowViewStateService.ViewState>
                            <scg:Dictionary x:TypeArguments="x:String, x:Object">
                              <x:Boolean x:Key="IsExpanded">True</x:Boolean>
                            </scg:Dictionary>
                          </sap:WorkflowViewStateService.ViewState>
                          <Sequence DisplayName="Initialize Variables" sap:VirtualizedContainerService.HintSize="573,392" mtbwt:BuildTrackingParticipant.Importance="Low">
                            <sap:WorkflowViewStateService.ViewState>
                              <scg:Dictionary x:TypeArguments="x:String, x:Object">
                                <x:Boolean x:Key="IsExpanded">True</x:Boolean>
                              </scg:Dictionary>
                            </sap:WorkflowViewStateService.ViewState>
                            <Assign x:TypeArguments="x:String" DisplayName="Initialize OutputDirectory" sap:VirtualizedContainerService.HintSize="464,22" mtbwt:BuildTrackingParticipant.Importance="Low" To="[outputDirectory]" Value="[If (platformConfiguration.IsEmpty Or BuildSettings.PlatformConfigurations.Count = 1, BinariesDirectory, If (platformConfiguration.IsPlatformEmptyOrAnyCpu, BinariesDirectory + &quot;\&quot; + platformConfiguration.Configuration, BinariesDirectory + &quot;\&quot; + platformConfiguration.Platform + &quot;\&quot; + platformConfiguration.Configuration))]" />
                            <If Condition="[Not String.IsNullOrEmpty(BuildDetail.DropLocation)]" DisplayName="If DropLocation is Set" sap:VirtualizedContainerService.HintSize="464,206" mtbwt:BuildTrackingParticipant.Importance="Low">
                              <If.Then>
                                <Assign x:TypeArguments="x:String" DisplayName="Initialize LogFile Drop Location" sap:VirtualizedContainerService.HintSize="269,100" mtbwt:BuildTrackingParticipant.Importance="Low" To="[logFileDropLocation]" Value="[If (platformConfiguration.IsEmpty Or BuildSettings.PlatformConfigurations.Count = 1, BuildDetail.DropLocation + &quot;\logs&quot;, If (platformConfiguration.IsPlatformEmptyOrAnyCpu, BuildDetail.DropLocation + &quot;\logs\&quot; + platformConfiguration.Configuration, BuildDetail.DropLocation + &quot;\logs\&quot; + platformConfiguration.Platform + &quot;\&quot; + platformConfiguration.Configuration))]" />
                              </If.Then>
                            </If>
                          </Sequence>
                          <If Condition="[BuildSettings.HasProjectsToBuild]" DisplayName="If BuildSettings.HasProjectsToBuild" sap:VirtualizedContainerService.HintSize="573,607" mtbwt:BuildTrackingParticipant.Importance="Low">
                            <If.Then>
                              <ForEach x:TypeArguments="x:String" DisplayName="For Each Project in BuildSettings.ProjectsToBuild" sap:VirtualizedContainerService.HintSize="448,501" mtbwt:BuildTrackingParticipant.Importance="Low" Values="[BuildSettings.ProjectsToBuild]">
                                <ActivityAction x:TypeArguments="x:String">
                                  <ActivityAction.Argument>
                                    <DelegateInArgument x:TypeArguments="x:String" Name="serverBuildProjectItem" />
                                  </ActivityAction.Argument>
                                  <TryCatch DisplayName="Try to Compile the Project" sap:VirtualizedContainerService.HintSize="418,395" mtbwt:BuildTrackingParticipant.Importance="Low">
                                    <TryCatch.Try>
                                      <Sequence DisplayName="Compile the Project" sap:VirtualizedContainerService.HintSize="400,208" mtbwt:BuildTrackingParticipant.Importance="Low">
                                        <Sequence.Variables>
                                          <Variable x:TypeArguments="x:String" Name="localProject" />
                                        </Sequence.Variables>
                                        <sap:WorkflowViewStateService.ViewState>
                                          <scg:Dictionary x:TypeArguments="x:String, x:Object">
                                            <x:Boolean x:Key="IsExpanded">True</x:Boolean>
                                          </scg:Dictionary>
                                        </sap:WorkflowViewStateService.ViewState>
                                        <mtbwa:ConvertWorkspaceItem DisplayName="Convert Server Path to Local Path" sap:VirtualizedContainerService.HintSize="200,22" mtbwt:BuildTrackingParticipant.Importance="Low" Input="[serverBuildProjectItem]" Result="[localProject]" Workspace="[Workspace]" />
                                        <mtbwa:MSBuild CommandLineArguments="[String.Format(&quot;/p:SkipInvalidConfigurations=true {0}&quot;, MSBuildArguments)]" Configuration="[platformConfiguration.Configuration]" DisplayName="Run MSBuild for Project" GenerateVSPropsFile="[True]" sap:VirtualizedContainerService.HintSize="200,22" LogFileDropLocation="[logFileDropLocation]" OutDir="[outputDirectory]" 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]" />
                                      </Sequence>
                                    </TryCatch.Try>
                                    <TryCatch.Catches>
                                      <Catch x:TypeArguments="s:Exception" sap:VirtualizedContainerService.HintSize="404,21">
                                        <sap:WorkflowViewStateService.ViewState>
                                          <scg:Dictionary x:TypeArguments="x:String, x:Object">
                                            <x:Boolean x:Key="IsExpanded">False</x:Boolean>
                                          </scg:Dictionary>
                                        </sap:WorkflowViewStateService.ViewState>
                                        <ActivityAction x:TypeArguments="s:Exception">
                                          <ActivityAction.Argument>
                                            <DelegateInArgument x:TypeArguments="s:Exception" Name="ex" />
                                          </ActivityAction.Argument>
                                          <Sequence DisplayName="Handle Exception" sap:VirtualizedContainerService.HintSize="398,266">
                                            <sap:WorkflowViewStateService.ViewState>
                                              <scg:Dictionary x:TypeArguments="x:String, x:Object">
                                                <x:Boolean x:Key="IsExpanded">True</x:Boolean>
                                              </scg:Dictionary>
                                            </sap:WorkflowViewStateService.ViewState>
                                            <mtbwa:SetBuildProperties CompilationStatus="[Microsoft.TeamFoundation.Build.Client.BuildPhaseStatus.Failed]" DisplayName="Set CompilationStatus to Failed" sap:VirtualizedContainerService.HintSize="464,22" mtbwt:BuildTrackingParticipant.Importance="Low" PropertiesToSet="CompilationStatus" />
                                            <If Condition="[CreateWorkItem]" DisplayName="If CreateWorkItem" sap:VirtualizedContainerService.HintSize="464,206" mtbwt:BuildTrackingParticipant.Importance="Low">
                                              <If.Then>
                                                <mtbwa:InvokeForReason DisplayName="Create Work Item for non-Shelveset Builds" Reason="Manual, IndividualCI, BatchedCI, Schedule, ScheduleForced, UserCreated">
                                                  <mtbwa:OpenWorkItem AssignedTo="[BuildDetail.RequestedFor]" Comment="[&quot;This work item was created by TFS Build on a build failure.&quot;]" CustomFields="[New Dictionary(Of String, String) From { {&quot;System.Reason&quot;&quot;Build Failure&quot;}, {&quot;Microsoft.VSTS.TCM.ReproSteps&quot;&quot;Start the build using TFS Build&quot;}, {&quot;Priority&quot;&quot;1&quot;}, {&quot;Severity&quot;&quot;1 - Critical&quot;} }]" DisplayName="Create Work Item" Title="[String.Format(&quot;Build Failure in Build: {0}&quot;, BuildDetail.BuildNumber)]" Type="[&quot;Bug&quot;]" />
                                                </mtbwa:InvokeForReason>
                                              </If.Then>
                                            </If>
                                            <Rethrow DisplayName="Rethrow the exception so the build will stop" mtbwt:BuildTrackingParticipant.Importance="Low" />
                                          </Sequence>
                                        </ActivityAction>
                                      </Catch>
                                    </TryCatch.Catches>
                                  </TryCatch>
                                </ActivityAction>
                              </ForEach>
                            </If.Then>
                          </If>
                          <If Condition="[Not DisableTests]" DisplayName="If Not DisableTests" sap:VirtualizedContainerService.HintSize="573,206" mtbwt:BuildTrackingParticipant.Importance="Low">
                            <If.Then>
                              <Sequence DisplayName="Run Tests" mtbwt:BuildTrackingParticipant.Importance="Low">
                                <If Condition="[Not TestSpecs Is Nothing]" DisplayName="If Not TestSpecs Is Nothing" mtbwt:BuildTrackingParticipant.Importance="Low">
                                  <If.Then>
                                    <ForEach x:TypeArguments="mtbwa:TestSpec" DisplayName="For Each TestSpec in TestSpecs" mtbwt:BuildTrackingParticipant.Importance="Low" Values="[TestSpecs]">
                                      <ActivityAction x:TypeArguments="mtbwa:TestSpec">
                                        <ActivityAction.Argument>
                                          <DelegateInArgument x:TypeArguments="mtbwa:TestSpec" Name="spec" />
                                        </ActivityAction.Argument>
                                        <TryCatch DisplayName="Try Run Tests" mtbwt:BuildTrackingParticipant.Importance="Low">
                                          <TryCatch.Try>
                                            <If Condition="[TypeOf spec Is Microsoft.TeamFoundation.Build.Workflow.Activities.TestMetadataFileSpec]" DisplayName="If spec Is TestMetadataFileSpec" mtbwt:BuildTrackingParticipant.Importance="None">
                                              <If.Then>
                                                <Sequence DisplayName="Run MSTest for Metadata File">
                                                  <Sequence.Variables>
                                                    <Variable x:TypeArguments="mtbwa:TestMetadataFileSpec" Name="testMetadataFile" />
                                                    <Variable x:TypeArguments="x:String" Name="localTestMetadata" />
                                                  </Sequence.Variables>
                                                  <Assign x:TypeArguments="mtbwa:TestMetadataFileSpec" DisplayName="Assign spec to testMetadataFile" mtbwt:BuildTrackingParticipant.Importance="Low" To="[testMetadataFile]" Value="[DirectCast(spec, Microsoft.TeamFoundation.Build.Workflow.Activities.TestMetadataFileSpec)]" />
                                                  <mtbwa:ConvertWorkspaceItem DisplayName="Convert Server Path to Local Path" mtbwt:BuildTrackingParticipant.Importance="Low" Input="[testMetadataFile.MetadataFileName]" Result="[localTestMetadata]" Workspace="[Workspace]" />
                                                  <mtbwa:MSTest Category="[testMetadataFile.CategoryFilter]" CommandLineArguments="[testMetadataFile.MSTestCommandLineArgs]" DisplayName="Run MSTest for Metadata File" Flavor="[platformConfiguration.Configuration]" MaxPriority="[testMetadataFile.MaximumPriority]" MinPriority="[testMetadataFile.MinimumPriority]" PathToResultsFilesRoot="[TestResultsDirectory]" Platform="[platformConfiguration.Platform]" SearchPathRoot="[outputDirectory]" TestLists="[testMetadataFile.TestLists]" TestMetadata="[localTestMetadata]" TestSettings="[String.Empty]" />
                                                </Sequence>
                                              </If.Then>
                                              <If.Else>
                                                <Sequence DisplayName="Run MSTest for Test Assemblies" mtbwt:BuildTrackingParticipant.Importance="Low">
                                                  <Sequence.Variables>
                                                    <Variable x:TypeArguments="mtbwa:TestAssemblySpec" Name="testAssembly" />
                                                    <Variable x:TypeArguments="scg:IEnumerable(x:String)" Name="testAssemblies" />
                                                    <Variable x:TypeArguments="x:String" Default="[String.Empty]" Name="testFlavor" />
                                                    <Variable x:TypeArguments="x:String" Default="[String.Empty]" Name="testPlatform" />
                                                  </Sequence.Variables>
                                                  <Assign x:TypeArguments="mtbwa:TestAssemblySpec" DisplayName="Assign spec to testAssembly" mtbwt:BuildTrackingParticipant.Importance="Low" To="[testAssembly]" Value="[DirectCast(spec, Microsoft.TeamFoundation.Build.Workflow.Activities.TestAssemblySpec)]" />
                                                  <mtbwa:FindMatchingFiles DisplayName="Find Test Assemblies" mtbwt:BuildTrackingParticipant.Importance="Low" MatchPattern="[String.Format(&quot;{0}\{1}&quot;, outputDirectory, testAssembly.AssemblyFileSpec)]" Result="[testAssemblies]" />
                                                  <If Condition="[testAssemblies.Count() &gt; 0]" DisplayName="If Test Assemblies Found" mtbwt:BuildTrackingParticipant.Importance="Low">
                                                    <If.Then>
                                                      <If Condition="[testAssembly.HasTestSettingsFile]" DisplayName="If testAssembly.HasTestSettingsFile" mtbwt:BuildTrackingParticipant.Importance="Low">
                                                        <If.Then>
                                                          <Sequence DisplayName="Find Test Settings File And Run MSTest" mtbwt:BuildTrackingParticipant.Importance="Low">
                                                            <Sequence.Variables>
                                                              <Variable x:TypeArguments="x:String" Name="localTestSettings" />
                                                            </Sequence.Variables>
                                                            <mtbwa:ConvertWorkspaceItem DisplayName="Convert Server Path to Local Path" mtbwt:BuildTrackingParticipant.Importance="Low" Input="[testAssembly.TestSettingsFileName]" Result="[localTestSettings]" Workspace="[Workspace]" />
                                                            <mtbwa:MSTest Category="[testAssembly.CategoryFilter]" CommandLineArguments="[testAssembly.MSTestCommandLineArgs]" DisplayName="Run MSTest for Test Assemblies" Flavor="[platformConfiguration.Configuration]" MaxPriority="[testAssembly.MaximumPriority]" MinPriority="[testAssembly.MinimumPriority]" PathToResultsFilesRoot="[TestResultsDirectory]" Platform="[platformConfiguration.Platform]" SearchPathRoot="[outputDirectory]" TestContainers="[testAssemblies]" TestSettings="[localTestSettings]" />
                                                          </Sequence>
                                                        </If.Then>
                                                        <If.Else>
                                                          <mtbwa:MSTest Category="[testAssembly.CategoryFilter]" CommandLineArguments="[testAssembly.MSTestCommandLineArgs]" DisplayName="Run MSTest for Test Assemblies" Flavor="[platformConfiguration.Configuration]" MaxPriority="[testAssembly.MaximumPriority]" MinPriority="[testAssembly.MinimumPriority]" PathToResultsFilesRoot="[TestResultsDirectory]" Platform="[platformConfiguration.Platform]" SearchPathRoot="[outputDirectory]" TestContainers="[testAssemblies]" />
                                                        </If.Else>
                                                      </If>
                                                    </If.Then>
                                                  </If>
                                                </Sequence>
                                              </If.Else>
                                            </If>
                                          </TryCatch.Try>
                                          <TryCatch.Catches>
                                            <Catch x:TypeArguments="s:Exception">
                                              <ActivityAction x:TypeArguments="s:Exception">
                                                <ActivityAction.Argument>
                                                  <DelegateInArgument x:TypeArguments="s:Exception" Name="testException" />
                                                </ActivityAction.Argument>
                                                <Sequence DisplayName="Handle MSTest Exception">
                                                  <If Condition="[Not (TypeOf testException Is Microsoft.TeamFoundation.Build.Workflow.Activities.TestFailureException)]" DisplayName="If testException is NOT TestFailureException" mtbwt:BuildTrackingParticipant.Importance="Low">
                                                    <If.Then>
                                                      <mtbwa:WriteBuildError DisplayName="Write Test Failure Exception message" Message="[testException.Message]" />
                                                    </If.Then>
                                                  </If>
                                                  <mtbwa:SetBuildProperties DisplayName="Set TestStatus to Failed" mtbwt:BuildTrackingParticipant.Importance="Low" PropertiesToSet="TestStatus" TestStatus="[Microsoft.TeamFoundation.Build.Client.BuildPhaseStatus.Failed]" />
                                                  <If Condition="[spec.FailBuildOnFailure]" DisplayName="If spec.FailBuildOnFailure" mtbwt:BuildTrackingParticipant.Importance="Low">
                                                    <If.Then>
                                                      <Assign x:TypeArguments="x:Boolean" DisplayName="Set treatTestFailureAsBuildFailure to True" mtbwt:BuildTrackingParticipant.Importance="Low" To="[treatTestFailureAsBuildFailure]" Value="[True]" />
                                                    </If.Then>
                                                  </If>
                                                </Sequence>
                                              </ActivityAction>
                                            </Catch>
                                          </TryCatch.Catches>
                                        </TryCatch>
                                      </ActivityAction>
                                    </ForEach>
                                  </If.Then>
                                </If>
                              </Sequence>
                            </If.Then>
                          </If>
                        </Sequence>
                      </ActivityAction>
                    </ForEach>
                    <If Condition="[BuildDetail.CompilationStatus = Microsoft.TeamFoundation.Build.Client.BuildPhaseStatus.Unknown]" DisplayName="If CompilationStatus = Unknown" mtbwt:BuildTrackingParticipant.Importance="Low">
                      <If.Then>
                        <mtbwa:SetBuildProperties CompilationStatus="[Microsoft.TeamFoundation.Build.Client.BuildPhaseStatus.Succeeded]" DisplayName="Set CompilationStatus to Succeeded" mtbwt:BuildTrackingParticipant.Importance="Low" PropertiesToSet="CompilationStatus" />
                      </If.Then>
                    </If>
                    <If Condition="[BuildDetail.TestStatus = Microsoft.TeamFoundation.Build.Client.BuildPhaseStatus.Unknown]" DisplayName="If TestStatus = Unknown" mtbwt:BuildTrackingParticipant.Importance="Low">
                      <If.Then>
                        <mtbwa:SetBuildProperties DisplayName="Set TestStatus to Succeeded" mtbwt:BuildTrackingParticipant.Importance="Low" PropertiesToSet="TestStatus" TestStatus="[Microsoft.TeamFoundation.Build.Client.BuildPhaseStatus.Succeeded]" />
                      </If.Then>
                    </If>
                    <If Condition="[treatTestFailureAsBuildFailure And (BuildDetail.TestStatus = Microsoft.TeamFoundation.Build.Client.BuildPhaseStatus.Failed)]" DisplayName="If TreatTestFailureAsBuildFailure And (TestStatus = Failed)" mtbwt:BuildTrackingParticipant.Importance="Low">
                      <If.Then>
                        <mtbwa:SetBuildProperties DisplayName="Set Status to Failed" mtbwt:BuildTrackingParticipant.Importance="Low" PropertiesToSet="Status" Status="[Microsoft.TeamFoundation.Build.Client.BuildStatus.Failed]" />
                      </If.Then>
                    </If>
                  </Sequence>
                </TryCatch.Try>
                <TryCatch.Catches>
                  <Catch x:TypeArguments="s:Exception">
                    <ActivityAction x:TypeArguments="s:Exception">
                      <ActivityAction.Argument>
                        <DelegateInArgument x:TypeArguments="s:Exception" Name="compilationExceptionArgument" />
                      </ActivityAction.Argument>
                      <Assign x:TypeArguments="s:Exception" DisplayName="Save the Compilation Exception" mtbwt:BuildTrackingParticipant.Importance="None" To="[compilationException]" Value="[compilationExceptionArgument]" />
                    </ActivityAction>
                  </Catch>
                </TryCatch.Catches>
              </TryCatch>
              <If Condition="[AssociateChangesetsAndWorkItems]" DisplayName="If AssociateChangesetsAndWorkItems" sap:VirtualizedContainerService.HintSize="464,2005" mtbwt:BuildTrackingParticipant.Importance="Low">
                <If.Then>
                  <mtbwa:InvokeForReason DisplayName="Associate Changesets and Work Items for non-Shelveset Builds" sap:VirtualizedContainerService.HintSize="281,146" Reason="Manual, IndividualCI, BatchedCI, Schedule, ScheduleForced, UserCreated">
                    <mtbwa:AssociateChangesetsAndWorkItems DisplayName="Associate Changesets and Work Items" sap:VirtualizedContainerService.HintSize="200,22" Result="[associatedChangesets]" />
                  </mtbwa:InvokeForReason>
                </If.Then>
              </If>
            </Parallel>
            <If Condition="[Not compilationException Is Nothing]" DisplayName="If a Compilation Exception Occurred" mtbwt:BuildTrackingParticipant.Importance="Low">
              <If.Then>
                <Throw DisplayName="Rethrow Compilation Exception" Exception="[compilationException]" mtbwt:BuildTrackingParticipant.Importance="Low" />
              </If.Then>
            </If>
            <Parallel DisplayName="Get Impacted Tests, Index Sources and Publish Symbols">
              <If Condition="[PerformTestImpactAnalysis]" DisplayName="If PerformTestImpactAnalysis" mtbwt:BuildTrackingParticipant.Importance="Low">
                <If.Then>
                  <Sequence DisplayName="Get Impacted Tests" mtbwt:BuildTrackingParticipant.Importance="Low">
                    <Sequence.Variables>
                      <Variable x:TypeArguments="scg:IEnumerable(x:String)" Name="assemblies" />
                    </Sequence.Variables>
                    <mtbwa:FindMatchingFiles DisplayName="Find Build Outputs" mtbwt:BuildTrackingParticipant.Importance="Low" MatchPattern="[String.Format(&quot;{0}\**\*.dll;{0}\**\*.exe&quot;, BinariesDirectory)]" Result="[assemblies]" />
                    <mttbb:GetImpactedTests BaselineBuildDropLocation="{x:Null}" CodeChanges="{x:Null}" ImpactedTests="{x:Null}" Assemblies="[assemblies]" AssociatedChangesets="[associatedChangesets]" BinariesRoot="[BinariesDirectory]" Build="[BuildDetail]" DisplayName="Get Impacted Tests" Workspace="[Workspace]" />
                  </Sequence>
                </If.Then>
              </If>
              <If Condition="[SourceAndSymbolServerSettings.IndexSources Or SourceAndSymbolServerSettings.HasSymbolStorePath]" DisplayName="If SourceAndSymbolServerSettings.IndexSources Or SourceAndSymbolServerSettings.HasSymbolStorePath" mtbwt:BuildTrackingParticipant.Importance="Low">
                <If.Then>
                  <mtbwa:InvokeForReason DisplayName="Index Sources and Publish Symbols for Triggered Builds" Reason="Triggered">
                    <mtbwa:InvokeForReason.Variables>
                      <Variable x:TypeArguments="scg:IEnumerable(x:String)" Name="symbolFiles" />
                    </mtbwa:InvokeForReason.Variables>
                    <mtbwa:FindMatchingFiles DisplayName="Find Symbol Files" mtbwt:BuildTrackingParticipant.Importance="Low" MatchPattern="[String.Format(&quot;{0}\**\*.pdb&quot;, BinariesDirectory)]" Result="[symbolFiles]" />
                    <If Condition="[SourceAndSymbolServerSettings.IndexSources]" DisplayName="If SourceAndSymbolServerSettings.IndexSources" mtbwt:BuildTrackingParticipant.Importance="Low">
                      <If.Then>
                        <TryCatch DisplayName="Try Index Sources" mtbwt:BuildTrackingParticipant.Importance="Low">
                          <TryCatch.Try>
                            <mtbwa:IndexSources DisplayName="Index Sources" FileList="[symbolFiles]" />
                          </TryCatch.Try>
                          <TryCatch.Catches>
                            <Catch x:TypeArguments="s:Exception">
                              <ActivityAction x:TypeArguments="s:Exception">
                                <ActivityAction.Argument>
                                  <DelegateInArgument x:TypeArguments="s:Exception" Name="exception" />
                                </ActivityAction.Argument>
                                <mtbwa:WriteBuildError Message="[exception.Message]" />
                              </ActivityAction>
                            </Catch>
                          </TryCatch.Catches>
                        </TryCatch>
                      </If.Then>
                    </If>
                    <If Condition="[SourceAndSymbolServerSettings.HasSymbolStorePath]" DisplayName="If SourceAndSymbolServerSettings.HasSymbolStorePath" mtbwt:BuildTrackingParticipant.Importance="Low">
                      <If.Then>
                        <TryCatch DisplayName="Try Publish Symbols" mtbwt:BuildTrackingParticipant.Importance="Low">
                          <TryCatch.Try>
                            <mtbwa:SharedResourceScope DisplayName="Synchronize Access to Symbol Store" mtbwt:BuildTrackingParticipant.Importance="Low" MaxExecutionTime="[TimeSpan.Zero]" MaxWaitTime="[New TimeSpan(1, 0, 0)]" ResourceName="[SourceAndSymbolServerSettings.SymbolStorePath]">
                              <mtbwa:PublishSymbols DisplayName="Publish Symbols" FileList="[symbolFiles]" ProductName="[BuildDetail.BuildDefinition.Name]" StorePath="[SourceAndSymbolServerSettings.SymbolStorePath]" Version="[BuildDetail.BuildNumber]" />
                            </mtbwa:SharedResourceScope>
                          </TryCatch.Try>
                          <TryCatch.Catches>
                            <Catch x:TypeArguments="s:Exception">
                              <ActivityAction x:TypeArguments="s:Exception">
                                <ActivityAction.Argument>
                                  <DelegateInArgument x:TypeArguments="s:Exception" Name="exception" />
                                </ActivityAction.Argument>
                                <mtbwa:WriteBuildError Message="[exception.Message]" />
                              </ActivityAction>
                            </Catch>
                          </TryCatch.Catches>
                        </TryCatch>
                      </If.Then>
                    </If>
                  </mtbwa:InvokeForReason>
                </If.Then>
              </If>
            </Parallel>
          </Sequence>
        </TryCatch.Try>
      </TryCatch>
      <t:Activity1 ErrorLevel="{x:Null}" BuildDirectory="[BuildDirectory]" Workspace="[Workspace]" DropLocation="[BuildDetail.DropLocation]" DisplayName="Run Post Processing Script" sap:VirtualizedContainerService.HintSize="222,22" ScriptArguments="[ScriptArguments]" ScriptPath="[ServerPathToScript]" />
    </mtbwa:AgentScope>
    <mtbwa:InvokeForReason DisplayName="Check In Gated Changes for CheckInShelveset Builds" sap:VirtualizedContainerService.HintSize="633,146" Reason="CheckInShelveset">
      <mtbwa:CheckInGatedChanges DisplayName="Check In Gated Changes" sap:VirtualizedContainerService.HintSize="200,22" />
    </mtbwa:InvokeForReason>
  </Sequence>
</ Activity>

RunScript.xaml:

<Activity mc:Ignorable="sap" x:Class="BuildActivityPack.Activity1" xmlns="http://schemas.microsoft.com/netfx/2009/xaml/activities" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mtbc="clr-namespace:Microsoft.TeamFoundation.Build.Client;assembly=Microsoft.TeamFoundation.Build.Client, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" xmlns:mtbc1="clr-namespace:Microsoft.TeamFoundation.Build.Client;assembly=Microsoft.TeamFoundation.Build.Client" xmlns:mtbwa="clr-namespace:Microsoft.TeamFoundation.Build.Workflow.Activities;assembly=Microsoft.TeamFoundation.Build.Workflow" 
xmlns:mtvc="clr-namespace:Microsoft.TeamFoundation.VersionControl.Client;assembly=Microsoft.TeamFoundation.VersionControl.Client" xmlns:mv="clr-namespace:Microsoft.VisualBasic;assembly=System" xmlns:mva="clr-namespace:Microsoft.VisualBasic.Activities;assembly=System.Activities" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:s1="clr-namespace:System;assembly=System" xmlns:s2="clr-namespace:System;assembly=System.Xml" xmlns:s3="clr-namespace:System;assembly=System.Core" xmlns:s4="clr-namespace:System;assembly=System.ServiceModel" xmlns:sa="clr-namespace:System.Activities;assembly=System.Activities" xmlns:sad="clr-namespace:System.Activities.Debugger;assembly=System.Activities" xmlns:sap="http://schemas.microsoft.com/netfx/2009/xaml/activities/presentation" xmlns:sc="clr-namespace:System.Collections;assembly=mscorlib" xmlns:scg="clr-namespace:System.Collections.Generic;assembly=mscorlib" xmlns:scg1="clr-namespace:System.Collections.Generic;assembly=System" xmlns:scg2="clr-namespace:System.Collections.Generic;assembly=System.ServiceModel" xmlns:scg3="clr-namespace:System.Collections.Generic;assembly=System.Core" xmlns:sd="clr-namespace:System.Data;assembly=System.Data" xmlns:sl="clr-namespace:System.Linq;assembly=System.Core" xmlns:st="clr-namespace:System.Text;assembly=mscorlib" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <x:Members>
    <x:Property Name="ScriptPath" Type="InArgument(x:String)">
      <x:Property.Attributes>
        <RequiredArgumentAttribute />
      </x:Property.Attributes>
    </x:Property>
    <x:Property Name="ErrorLevel" Type="OutArgument(x:Int32)" />
    <x:Property Name="ScriptArguments" Type="InArgument(x:String)" />
    <x:Property Name="Workspace" Type="InArgument(mtvc:Workspace)">
      <x:Property.Attributes>
        <RequiredArgumentAttribute />
      </x:Property.Attributes>
    </x:Property>
    <x:Property Name="DropLocation" Type="InArgument(x:String)">
      <x:Property.Attributes>
        <RequiredArgumentAttribute />
      </x:Property.Attributes>
    </x:Property>
    <x:Property Name="BuildDirectory" Type="InArgument(x:String)">
      <x:Property.Attributes>
        <RequiredArgumentAttribute />
      </x:Property.Attributes>
    </x:Property>
  </x:Members>
  <sap:VirtualizedContainerService.HintSize>262,368</sap:VirtualizedContainerService.HintSize>
  <mva:VisualBasic.Settings>Assembly references and imported namespaces for internal implementation</mva:VisualBasic.Settings>
  <Sequence DisplayName="Run Script" sad:XamlDebuggerXmlReader.FileName="C:\Enlistments\dustinan2k8\BuildProcessExtensions\BuildActivityPack\BuildActivityPack\RunScript.xaml" sap:VirtualizedContainerService.HintSize="222,328">
    <Sequence.Variables>
      <Variable x:TypeArguments="x:String" Name="localScriptPath" />
      <Variable x:TypeArguments="scg:IDictionary(x:String, x:String)" Default="[New Dictionary(Of String, String) From {{&quot;BuildDirectory&quot;, BuildDirectory}}]" Name="ScriptEnvironmentVariables" />
    </Sequence.Variables>
    <sap:WorkflowViewStateService.ViewState>
      <scg:Dictionary x:TypeArguments="x:String, x:Object">
        <x:Boolean x:Key="IsExpanded">True</x:Boolean>
      </scg:Dictionary>
    </sap:WorkflowViewStateService.ViewState>
    <mtbwa:ConvertWorkspaceItem DisplayName="GetLocalScriptPath" sap:VirtualizedContainerService.HintSize="200,22" Input="[ScriptPath]" Result="[localScriptPath]" Workspace="[Workspace]" />
    <mtbwa:InvokeProcess Arguments="[DropLocation + &quot; &quot; + ScriptArguments]" EnvironmentVariables="[ScriptEnvironmentVariables]" FileName="[localScriptPath]" sap:VirtualizedContainerService.HintSize="200,51" Result="[ErrorLevel]" WorkingDirectory="[BuildDirectory]">
      <mtbwa:InvokeProcess.ErrorDataReceived>
        <ActivityAction x:TypeArguments="x:String">
          <ActivityAction.Argument>
            <DelegateInArgument x:TypeArguments="x:String" Name="errOutput" />
          </ActivityAction.Argument>
          <mtbwa:WriteBuildWarning sap:VirtualizedContainerService.HintSize="200,22" Message="[errOutput]" />
        </ActivityAction>
      </mtbwa:InvokeProcess.ErrorDataReceived>
      <mtbwa:InvokeProcess.OutputDataReceived>
        <ActivityAction x:TypeArguments="x:String">
          <ActivityAction.Argument>
            <DelegateInArgument x:TypeArguments="x:String" Name="stdOutput" />
          </ActivityAction.Argument>
          <mtbwa:WriteBuildMessage sap:VirtualizedContainerService.HintSize="200,22" Importance="[Microsoft.TeamFoundation.Build.Client.BuildMessageImportance.High]" Message="[stdOutput]" mva:VisualBasic.Settings="Assembly references and imported namespaces serialized as XML namespaces" />
        </ActivityAction>
      </mtbwa:InvokeProcess.OutputDataReceived>
      <sap:WorkflowViewStateService.ViewState>
        <scg:Dictionary x:TypeArguments="x:String, x:Object">
          <x:Boolean x:Key="IsExpanded">False</x:Boolean>
          <x:Boolean x:Key="IsPinned">False</x:Boolean>
        </scg:Dictionary>
      </sap:WorkflowViewStateService.ViewState>
    </mtbwa:InvokeProcess>
    <TryCatch sap:VirtualizedContainerService.HintSize="200,51">
      <sap:WorkflowViewStateService.ViewState>
        <scg:Dictionary x:TypeArguments="x:String, x:Object">
          <x:Boolean x:Key="IsExpanded">False</x:Boolean>
          <x:Boolean x:Key="IsPinned">False</x:Boolean>
        </scg:Dictionary>
      </sap:WorkflowViewStateService.ViewState>
      <TryCatch.Try>
        <If Condition="[ErrorLevel &lt;&gt; 0]" DisplayName="if ErrorLevel &lt;&gt; 0" sap:VirtualizedContainerService.HintSize="464,206">
          <If.Then>
            <Throw Exception="[New System.InvalidOperationException(String.Format(&quot;The script returned errorlevel {0}&quot;, ErrorLevel))]" sap:VirtualizedContainerService.HintSize="269,100" />
          </If.Then>
        </If>
      </TryCatch.Try>
      <TryCatch.Catches>
        <Catch x:TypeArguments="s:InvalidOperationException" sap:VirtualizedContainerService.HintSize="468,21">
          <sap:WorkflowViewStateService.ViewState>
            <scg:Dictionary x:TypeArguments="x:String, x:Object">
              <x:Boolean x:Key="IsExpanded">False</x:Boolean>
              <x:Boolean x:Key="IsPinned">False</x:Boolean>
            </scg:Dictionary>
          </sap:WorkflowViewStateService.ViewState>
          <ActivityAction x:TypeArguments="s:InvalidOperationException">
            <ActivityAction.Argument>
              <DelegateInArgument x:TypeArguments="s:InvalidOperationException" Name="exception" />
            </ActivityAction.Argument>
            <mtbwa:WriteBuildError sap:VirtualizedContainerService.HintSize="462,75" Message="[exception.ToString()]" />
          </ActivityAction>
        </Catch>
      </TryCatch.Catches>
    </TryCatch>
  </Sequence>
</Activity>

Comments (3)
  1. ChristopherM1 says:

    Hi SaintD,

    Thanks very much for this post. Unfortunately DefaultTemplateWithPostProcessScripting.xaml wouldn't load for me as-is. "Activity could not be loaded because of errors in the XAML." Any way you could make it available for download or post it again? Thank you.

    Christopher

    temp16 at real-d.com

  2. Dustin Andrews says:

    See blogs.msdn.com/…/how-to-create-a-custom-workflow-activity-for-tfs-build-2010.aspx for more details on creating your own workflows.  You will ge that "Errors In Xaml" message if you don't load the template into a project where you already build the custom activity. The designer and TFS don't play together terribly well in this release.

  3. Yaounde says:

    Your Blog is one of the best top 100 software testing blogs listed in this article:

    http://www.testingminded.com/…/top-100-software-testing-blogs.html

    but for me, it's just one of the best! Keep the great work!

    ——————

    If you plan to go in Cameroon, please visit: <a href="offres-d-emploi-au-cameroun.blogspot.com/">Offres d'emploi au Cameroun</a>

Comments are closed.

Skip to main content