EdH
EdH

Reputation: 601

Azure multistage pipelines: conditionally skip one stage but not the next

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

Upvotes: 24

Views: 20887

Answers (4)

Tully
Tully

Reputation: 411

Credit to https://github.com/MicrosoftDocs/azure-devops-docs/issues/7738#issuecomment-611815486

@EdH

condition: not(or(failed(), canceled()))

Works with multiple previous stages and works like you need. Run the stage if all previous stages are succeeded or skipped, but not if they are failed or cancelled.

enter image description here

Notes:

  • Skipping does not cause failed() or cancelled() to be true.
  • Skipping does cause succeeded() to be false.

Upvotes: 28

JesusIsMyDriver.dll
JesusIsMyDriver.dll

Reputation: 869

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')
    )

Upvotes: 8

Levi Lu-MSFT
Levi Lu-MSFT

Reputation: 30313

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

Upvotes: 22

Josh Gust
Josh Gust

Reputation: 4445

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.

Upvotes: 2

Related Questions