![]() |
Azure DevOps pipeline flow |
Azure DevOps YAML pipelines provide a powerful and flexible way to automate your CI/CD workflows. Understanding the hierarchy, variable passing, triggers, and conditions is essential for building efficient pipelines.
YAML Pipeline Hierarchy
A YAML pipeline is structured in a hierarchical manner:
Stages – The top-level division in a pipeline (e.g., "Build," "Test," "Deploy").
Jobs – A sequence of steps that run sequentially or in parallel within a stage.
Steps – The smallest executable unit, which can be a script or a predefined task.
1. Stages
Below are examples of stages:
- Build App
- Run Tests
- Deploy to Production
Example:
stages:
- stage: Build App
jobs:
- job: BuildJob
steps:
- script: echo "Building the app..."
2. Jobs
A job is a set of steps that run together. Jobs can:
- Run sequentially or in parallel.
- Have dependencies (e.g.,
Job2
depends onJob1
). - Read more about job here
Example:
jobs:
- job: JobA
steps:
- script: echo "Running Job A"
- job: JobB
dependsOn: JobA
steps:
- script: echo "Running Job B after Job A"
3. Steps (Tasks)
Steps are the smallest executable units in a pipeline. They can be:
- Scripts (Bash, PowerShell, etc.)
- Predefined tasks (e.g.,
npm install
,dotnet build
)
Example:
steps:
- script: echo "Restoring dependencies..."
- task: DotNetCoreCLI@2
inputs:
command: 'build'
Passing Variables Across Tasks, Jobs, and Stages
1. Across Tasks in the Same Job
Use task.setvariable
to pass values between tasks.
Example:
steps:
- powershell: |
Write-Host "##vso[task.setvariable variable=MYVAR]abc"
- script: echo $(MYVAR) # Output: abc
2. Across Different Jobs
Use isOutput=true
and reference the variable via dependencies.
Example:
jobs:
- job: Job1
steps:
- bash: |
echo "##vso[task.setvariable variable=MYVAR;isOutput=true]abc"
name: SetVarStep
- job: Job2
dependsOn: Job1
variables:
MYVAR: $[ dependencies.Job1.outputs['SetVarStep.MYVAR'] ]
steps:
- script: echo $(MYVAR) # Output: abc
3. Across Different Stages
Use stageDependencies
to pass variables between stages.
Example:
stages:
- stage: StageA
jobs:
- job: JobA
steps:
- bash: |
echo "##vso[task.setvariable variable=MYVAR;isOutput=true]abc"
name: SetVarStep
- stage: StageB
dependsOn: StageA
variables:
MYVAR: $[ stageDependencies.StageA.JobA.outputs['SetVarStep.MYVAR'] ]
jobs:
- job: JobB
steps:
- script: echo $(MYVAR) # Output: abc
Triggers in YAML Pipelines
Triggers automate pipeline execution based on events like code commits or pull requests.
1. CI Trigger (Continuous Integration)
Runs when changes are pushed to specified branches/paths.
Example:
trigger:
branches:
include:
- main
paths:
include:
- src/**
exclude:
- src/docs/**
2. PR Trigger (Pull Request Validation)
Runs when a PR is created or updated.
Example:
pr:
branches:
include:
- main
paths:
include:
- src/**
🔹 Best Practices for Triggers:
- Use
batch: true
to optimize CI runs. - Path filters are case-sensitive.
- Wildcards (
*
) are not supported in path filters.
Conditions in Pipelines
Control when jobs, steps, or stages run using conditions.
Common Conditions:
Condition | Description |
---|---|
succeeded() | Runs only if previous steps succeeded (default). |
always() | Runs regardless of previous failures. |
failed() | Runs only if previous steps failed. |
eq(variables['var'], 'value') | Runs if a variable matches a value. |
Example:
steps:
- script: echo "This runs only on main branch"
condition: eq(variables['Build.SourceBranch'], 'refs/heads/main')