0
votes

I'm working with an existing TFS Build and Release Management setup and know little about the (now deprecated) XAML build system it uses.

In this snippet from the build template below my project is built, tests are ran and then a sequence is started which hands the compiled project over to TFS Release Management for deployment.

<Sequence DisplayName="Overall build process">
<mtbac:SetBuildNumber DisplayName="Update build number" BuildNumberFormat="[BuildNumberFormat]" />
<mtbwa:AgentScope DisplayName="Run on agent" MaxExecutionTime="[AgentSettings.GetValue(Of TimeSpan)(&quot;MaxExecutionTime&quot;, new System.TimeSpan(0,0,0))]" MaxWaitTime="[AgentSettings.GetValue(Of TimeSpan)(&quot;MaxWaitTime&quot;, new System.TimeSpan(4,0,0))]" ReservationSpec="[AgentSettings.CreateAgentReservationSpec()]">
  <mtbac:InitializeEnvironment DisplayName="Initialize environment" />
  <mtbat:TfGetSources DisplayName="Get sources from Team Foundation Version Control" CleanWorkspace="[CleanWorkspace]" CreateLabel="[CreateLabel]" VersionOverride="[GetVersion]" />
  <mtba:AssociateChanges DisplayName="Associate the changesets that occurred since the last good build" UpdateWorkItems="[UpdateAssociatedWorkItems]" />
  <TryCatch DisplayName="Try" mtbwt:BuildTrackingParticipant.Importance="Low">
    <TryCatch.Try>
      <Sequence DisplayName="Compile, Test and Publish">
        <mtba:RunScript DisplayName="Run optional script before MSBuild" FilePath="[AdvancedBuildSettings.GetValue(Of String)(&quot;PreActionScriptPath&quot;, String.Empty)]" Arguments="[AdvancedBuildSettings.GetValue(Of String)(&quot;PreActionScriptArguments&quot;, String.Empty)]" />
        <mtba:RunMSBuild DisplayName="Run MSBuild" OutputLocation="[OutputLocation]" CleanBuild="[CleanBuild]" CommandLineArguments="[String.Format(&quot;/p:SkipInvalidConfigurations=true {0}&quot;, AdvancedBuildSettings.GetValue(Of String)(&quot;MSBuildArguments&quot;, String.Empty))]" ConfigurationsToBuild="[ConfigurationsToBuild]" ProjectsToBuild="[ProjectsToBuild]" ToolPlatform="[AdvancedBuildSettings.GetValue(Of String)(&quot;MSBuildPlatform&quot;, &quot;Auto&quot;)]" RunCodeAnalysis="[AdvancedBuildSettings.GetValue(Of String)(&quot;RunCodeAnalysis&quot;, &quot;AsConfigured&quot;)]" />
        <mtba:RunScript DisplayName="Run optional script after MSBuild" FilePath="[AdvancedBuildSettings.GetValue(Of String)(&quot;PostActionScriptPath&quot;, String.Empty)]" Arguments="[AdvancedBuildSettings.GetValue(Of String)(&quot;PostActionScriptArguments&quot;, String.Empty)]" />
        <mtba:RunScript DisplayName="Run optional script before Test Runner" FilePath="[AdvancedTestSettings.GetValue(Of String)(&quot;PreActionScriptPath&quot;, String.Empty)]" Arguments="[AdvancedTestSettings.GetValue(Of String)(&quot;PreActionScriptArguments&quot;, String.Empty)]" />
        <mtba:RunAgileTestRunner DisplayName="Run VS Test Runner" Enabled="[Not AdvancedTestSettings.GetValue(Of Boolean)(&quot;DisableTests&quot;, false)]" TestSpecs="[AutomatedTests]" ConfigurationsToTest="[ConfigurationsToBuild]" />
        <mtba:RunScript DisplayName="Run optional script after Test Runner" FilePath="[AdvancedTestSettings.GetValue(Of String)(&quot;PostActionScriptPath&quot;, String.Empty)]" Arguments="[AdvancedTestSettings.GetValue(Of String)(&quot;PostActionScriptArguments&quot;, String.Empty)]" />
        <mtba:RunTestImpact DisplayName="Get Impacted Tests" Enabled="[AdvancedTestSettings.GetValue(Of Boolean)(&quot;AnalyzeTestImpact&quot;, true)]" />
        <Sequence DisplayName="Process the release">
          <Sequence.Variables>
            <Variable x:TypeArguments="x:String" Name="buildDirectory" />
          </Sequence.Variables>
          <mtbwa:GetBuildDirectory DisplayName="Get the Build Directory" Result="[buildDirectory]" />
          <If Condition="[ProcessReleaseTokens]" DisplayName="If ProcessReleaseTokens is set">
            <If.Then>
              <Sequence DisplayName="Initialize tokens">

Currently in the event of a test failure the sequence step still executes and the broken build is deployed. I have the "Fail build on test failure" option enabled.

I need to prevent deployments when there are test failures, either by stopping the release step from running or amending the process in release management (I was leaning towards not touching release management at all in the event of a build failure).

2
Are you using the release management which is integrated into the TFS? - Eddie Chen - MSFT
@Eddie-MSFT it's the previous version with the Visual Studio 2015 client. We plan to upgrade to the new TFS Build vnext in the future but was hoping for a workaround for this in the meantime. - James Antrobus

2 Answers

0
votes

You can have your build simply spit out the WebDeploy package (e.g. DeployTarget=Package), then have an InvokeProcess at the end of the workflow that runs a powershell script to do the actual deployment.

0
votes

You can update the XAML definition template to achieve this. Refer to the answer in this question for details: Release management releasing failed builds also - Triggering release from failed builds

Quote it here in case of the link does not work:

  1. Moved "If ReleaseBuild is Set" activity below "If Not DisableTests".
  2. Changed Condition of "If ReleaseBuild is Set" to: ReleaseBuild And (treatTestFailureAsBuildFailure = False Or (treatTestFailureAsBuildFailure And (BuildDetail.TestStatus <> Microsoft.TeamFoundation.Build.Client.BuildPhaseStatus.Failed))) And BuildDetail.CompilationStatus <> Microsoft.TeamFoundation.Build.Client.BuildPhaseStatus.Failed
  3. Inside "If ReleaseBuild is Set" activity's Else part, changed WriteBuildMessage's message to: "Skipped execution because either the ReleaseBuild is not set or some tests have failed or compilation has failed"
  4. Finally check-in the template and that's it, failed builds wont get deployed.