How to Use Conditions and Expressions in Azure Pipelines
The condition key gates a stage, job, or step on an expression built from functions like succeeded(), eq(), and and().
Attach condition: with an expression. Expressions combine status functions (succeeded(), failed()) with comparisons over variables and branch refs.
Run a step only on main after success
Combine the implicit success check with a branch comparison explicitly, since a custom condition replaces the default.
azure-pipelines.yml
steps:
- script: ./deploy.sh
condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
- script: ./notify-failure.sh
condition: failed()Gotchas
- Setting a custom
conditionremoves the implicitsucceeded()- add it back or the step runs even after failures. - Runtime conditions use
variables['Name']; compile-time template logic uses${{ if }}instead. - Use
always()for cleanup steps andsucceededOrFailed()to run despite earlier failures.
Verify it actually works
- Trigger the real event rather than a manual run. Manual dispatch populates a different context, so behaviour depending on the event will differ.
- Assert on the outcome, not on the step exiting zero. Many steps report success while producing nothing.
- Check it on a fresh runner with a cold cache once, so you are not testing warm state that will not exist on the next contributor machine.
Frequently asked questions
How do I use Conditions and Expressions in Azure Pipelines?
Attach condition: with an expression. Expressions combine status functions (succeeded(), failed()) with comparisons over variables and branch refs.
Run a step only on main after success?
Combine the implicit success check with a branch comparison explicitly, since a custom condition replaces the default.
Related guides
How to Run a Matrix Build in Azure PipelinesRun a matrix build in Azure Pipelines with strategy:matrix to fan a job across versions, plus maxParallel and
How to Retry a Failing Task in Azure PipelinesRetry a failing task in Azure Pipelines with retryCountOnTaskFailure, plus job-level retries via the