DevOps Peach

DevOps & CI/CD · CI/CD with Azure DevOps · Lesson 2 of 4

Azure Repos and YAML Pipelines

Branch policies protect main with pull requests and build validation; azure-pipelines.yml lives in the repo with trigger, pool, variables and stages → jobs → steps; secrets must be mapped through env.

Practice interactively →

Azure Repos: unlimited private Git. Branch policies on main: require pull requests, a minimum number of reviewers, linked work items and build validation (the pipeline must pass before merging). With Azure Repos, PR builds come from build validation, not from the pr: key.

Pipeline as code: azure-pipelines.yml lives in the repo and is reviewed through PRs. The classic (drag-and-drop) editor is the old way.

trigger:
  branches:
    include: [main]
pool:
  vmImage: ubuntu-latest
variables:
  nodeVersion: '22.x'
steps:
  - task: UseNode@1
    inputs:
      version: $(nodeVersion)
  - script: npm ci && npm test
    displayName: Install and test
    env:
      DB_PASSWORD: $(DB_PASSWORD)   # secrets must be mapped explicitly
flowchart TB
  PIPE["azure-pipelines.yml"] --> ST["stage: Build"]
  ST --> J["job: build (pool ubuntu-latest)"]
  J --> S1["task: UseNode@1"]
  J --> S2["script: npm ci && npm test"]
  J --> S3["publish: dist (artifact web)"]
Block Meaning
trigger Which branch pushes run CI (trigger: none = CI off)
pool The agent running the job (vmImage: ubuntu-latest)
variables YAML variables, used as $(name)
stages → jobs → steps A single-job pipeline may have only steps
task: Name@major Prebuilt, versioned steps: UseNode@1, Docker@2, AzureCLI@2
template: Reuse steps/jobs from another file

Traps: tab indentation or wrong nesting; forgetting env: for secrets; ubuntu-latest changes over time.

Command Meaning
az repos create --name my-app Create a repo
az repos pr create --repository my-app --source-branch feature/login --target-branch main --title "Add login" Create a PR
az pipelines create --name my-app-ci --repository my-app --repository-type tfsgit --branch main --yml-path azure-pipelines.yml Create a pipeline
az pipelines variable create --pipeline-name my-app-ci --name DB_PASSWORD --value changeme-example --secret true Secret variable
az pipelines variable-group create --name app-settings --variables LOG_LEVEL=info Variable group

Triggers in more detail

trigger:
  branches: { include: [main, release/*] }
  paths: { include: [src/*], exclude: [docs/*] }
pr:
  branches: { include: [main] }
schedules:
- cron: "0 2 * * *"
  displayName: Nightly build
  branches: { include: [main] }
  always: false

Path filters avoid running the whole pipeline when only documentation changes. The pr: key applies to GitHub and Bitbucket repositories; for Azure Repos, PR validation comes from branch policies. Scheduled runs with always: false skip when nothing changed.

Variables and expressions

Syntax Evaluated Typical use
$(name) At runtime, just before a task runs Most task inputs and scripts
${{ variables.name }} At compile time, when YAML is expanded Conditions, template parameters, inserting whole blocks
$[ variables.name ] At runtime, for conditions and variable values condition: and output variables

Predefined variables such as Build.BuildId, Build.SourceBranch, and Build.SourceVersion (the commit SHA) are available in every run.

Templates

# templates/build-node.yml
parameters:
- name: nodeVersion
  default: '22.x'
steps:
- task: UseNode@1
  inputs: { version: ${{ parameters.nodeVersion }} }
- script: npm ci && npm test

A pipeline uses it with - template: templates/build-node.yml and parameters: { nodeVersion: '20.x' }. Templates can live in another repository through resources: repositories:, letting a platform team publish standard building blocks. extends: templates go further and force pipelines into an approved structure.

Speeding up runs

The Cache@2 task restores dependency folders such as ~/.npm keyed by a lock file, cutting install time on Microsoft-hosted agents. Splitting work into parallel jobs and publishing test results with PublishTestResults@2 makes failures visible in the run's Tests tab.

Other ways to work with Git

Azure Pipelines builds code from Azure Repos, GitHub, GitHub Enterprise, Bitbucket Cloud, and generic Git. GitHub repositories integrate through the Azure Pipelines GitHub App, which also reports status checks on pull requests.

Practice interactively →