1

In an Azure DevOps pipeline, what is the value of Agent.JobStatus before any stages have been run? Is it initialized to 'Succeeded' or is it initially undefined or set to null or something like that, only to be set to 'Succeeded' after the first successful execution?

In other words:

  • If I include succeeded() (which is the same thing as, in(variables['Agent.JobStatus'], 'Succeeded', 'SucceededWithIssues')) in a condition for running the first stage, is it going to return true even though there have been no previous stages to return a successful result?
  • If I include succeeded() in a conditional for running the second stage, where the first stage has a condition that evaluated to false so the first stage was skipped, will it be true even though no previous stages have been executed returning a successful result?

The way I'd like to think it works is such that succeeded will return true in both places where I use it in the following code, where I want the first stage to run if the original triggering repo branch was 'main' and the second stage to run if the original branch was 'release/*'. (This is a slightly simplified version of the actual logic.) Am I correct?

stages:
  - template: my-template.yml
    condition: and(succeeded(), eq(variables['resources.pipeline.previousPipeline.SourceBranch'], 'refs/heads/main'))
    parameters:
      ...
  - template: my-template.yml
    condition: and(succeeded(), startsWith(variables['resources.pipeline.previousPipeline.SourceBranch'], 'refs/heads/release/'))
    parameters:
      ...

Alternatively, if succeeded() doesn't work in this manner, would I get what I need if, instead, I were to use not(failed())?

1 Answer 1

1

Five minutes later I found this dealt with at https://github.com/MicrosoftDocs/azure-devops-docs/issues/7738. Indeed, it appears that the Succeed outcome is not set until a stage has actually been executed. One respondent in the discussion indicates that this has worked for them:

As a work-around, our team has had success (no pun intended) using:

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

This works because the previous stage being skipped does not set a failed status.

2
  • @Nikola Malešević I rejected your edit proposal because the indentation is intentional, demarcating a quoted passage from the other discussion. Commented Jul 11 at 16:20
  • Slight syntax error in your work-around. Missing closing parenthesis for not. The corrected line is thus condition: not(or(failed(), cancelled()))
    – teh4x
    Commented Aug 3 at 19:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.