4
votes

I have an Azure multi-stage CI/CD pipeline. It has stages for Test and UAT deployment.

I want the UAT release to run if Test succeeds or is skipped, but not if it fails.

I can't. Whatever I try, if Test is skipped, UAT is also skipped. Unless I use always(), but then UAT will run even if Test fails.

  ...
  - stage: Test
    condition: and(succeeded(), ne(variables['build.sourceBranchName'], 'DoUAT')) # Skip for UAT deployment tests
    ...

  - stage: UAT
    condition: and(succeeded(), in(variables['build.sourceBranchName'], 'master', 'DoUAT')) # Only deploy off master branch and branch to test UAT deploys.
    ...

How do I skip one stage but not the next one?

What I get vs what I want

3

3 Answers

8
votes

You can use not(failed('Test')) condition, please try below condition.

- stage: UAT
    condition: and(not(failed('Test')), in(variables['build.sourceBranchName'], 'master', DoUAT')) # Only deploy off master branch and branch to test UAT deploys.
    ...

I tested and it worked, check below screenshot.

enter image description here

3
votes

I was looking for similar information, and found that you can do an "IN" clause on dependency result. Found this in the Microsoft Docs about expressions

- job: c
  dependsOn:
  - a
  - b
  condition: |
    and
    (
      in(dependencies.a.result, 'Succeeded', 'SucceededWithIssues', 'Skipped'),
      in(dependencies.b.result, 'Succeeded', 'SucceededWithIssues', 'Skipped')
    )
1
votes

I think it's because the stage doesn't run that it doesn't get a status (eg succeeded, failed, canceled etc.). There is no status function for skipped.

With that, I think you will need to add a dependency on the stage before Test so that this evaluation can be made. Let's say that stage is called Build.

I think this condition should work: (line breaks are for readability only)

# run the stage if build is successful 
# and test succeeded or skipped 
# AND the branch is correct
and(
  and(succeeded('Build'), not(failed('Test'))), 
  in(variables['build.sourceBranchName'], 'master', 'DoUAT')
)

failed

  • For a job:
    • With no arguments, evaluates to True only if any previous job in the dependency graph failed.
    • With job names as arguments, evaluates to True only if any of those jobs failed.

Because of this documentation, I think it's necessary to add the Test parameter to target that stage specifically. However, I'm not sure if this necessitates that the Test name be added to the dependencies section of the UAT stage.