๐ Mijn CICD pipelines
Ik heb 3 afzonderlijke pipelines om het overzihtelijk te houden
- azure-pipe-pr.yml
- azure-pipelines-merge.yml
- azure-pipe-tag.yml
๐ง Info
Alleen op de PR pipeline zetten we een Branch Policy Dit is nodig zodat op een PR de pipeline automatisch gestart gaat worden.
Projects Settings -> Repositories ->
Select by Build pipeline
Geef een display name in ....
๐งจ trigger / pr selectie
je selecteer met trigger en/of pr waarop je pipeline reageert !! ( zie de onderstaande voorbeelden )
โก Pull Request pipe
azure-pipe-pr.yml gestart op een PR
name: PR-Only-$(Date:yyyyMMdd)$(Rev:.r)
# โ
EXPLICIET geen CI triggers
trigger: none
# โ
ALLEEN PR triggers
pr:
branches:
include:
- '*' # Alle branches
paths:
exclude:
- README.md # Optioneel: exclude bepaalde paths
stages:
- stage: PR_Validation
displayName: '๐ PR Validation'
# โ
Condition is optioneel maar extra veilig
condition: eq(variables['Build.Reason'], 'PullRequest')
jobs:
- job: Validate_PR
steps:
- script: |
echo "โ
Dit is een PR build"
echo "PR Source: $(System.PullRequest.SourceBranch)"
echo "PR Target: $(System.PullRequest.TargetBranch)"
displayName: 'PR Info'
๐ ๏ธ Merge pipe
azure-pipelines-merge.yml gestart op een MERGE
trigger:
- main
stages:
- stage: PA
displayName: "PA Flow"
pool:
vmImage: 'ubuntu-latest'
jobs:
- job: Detect
steps:
- checkout: self
fetchDepth: 0
- bash: |
echo "Detecting changes..."
# git fetch origin main
# git diff --name-only HEAD^ HEAD
# CHANGED=$(git diff --name-only origin/main...HEAD)
CHANGED=$(git diff --name-only HEAD^ HEAD)
echo "$CHANGED"
if echo "$CHANGED" | grep -q "recover.yml"; then
echo "##vso[task.setvariable variable=RecoverChanged;isOutput=true]true"
echo "recover.yaml changed !!"
else
echo "##vso[task.setvariable variable=RecoverChanged;isOutput=true]false"
echo "recover.yml did not change"
fi
if echo "$CHANGED" | grep -q "site.yml"; then
echo "##vso[task.setvariable variable=SiteChanged;isOutput=true]true"
echo "site.yaml changed !!"
else
echo "##vso[task.setvariable variable=SiteChanged;isOutput=true]false"
echo "site.yml did not change"
fi
if echo "$CHANGED" | grep -q "vars"; then
echo "##vso[task.setvariable variable=VarsChanged;isOutput=true]true"
echo "vars changed !!"
else
echo "##vso[task.setvariable variable=VarsChanged;isOutput=true]false"
echo "vars did not change"
fi
name: detect_step
๐๏ธ Tag pipe
azure-pipe-tag.yml gestart op pushen van een tag
name: Release-$(Build.SourceBranchName)-$(Date:yyyyMMdd)$(Rev:.r)
trigger:
tags:
include: ['v*']
branches:
exclude: ['*']
pool:
vmImage: 'ubuntu-latest'
variables:
tagName: $(Build.SourceBranchName)
version: $[replace(variables['tagName'], 'v', '')]
steps:
- script: |
echo "๐ฏ Release triggered by tag: $(tagName)"
echo "๐ฆ Version: $(version)"
echo "๐ Git tag: $(Build.SourceBranch)"
echo "๐ Commit: $(Build.SourceVersion)"
displayName: 'Release info'
- task: PowerShell@2
inputs:
targetType: 'inline'
script: |
# Semantische versioning validatie
if ($env:VERSION -notmatch '^v\d+\.\d+\.\d+$') {
Write-Error "Version format must be MAJOR.MINOR.PATCH"
exit 1
}
Write-Host "โ
Valid version format: $env:VERSION"
env:
VERSION: $(version)
displayName: 'Validate version format'
- script: |
# Build je project met release configuratie
echo Do some building Version=$(version)
displayName: 'Build release'
condition: succeeded()
๐ Using Vars
Azure DevOps automatically exposes variables as environment variables.
The naming convention converts variables to uppercase and replaces . with _.
Env Vars (Recommended)
Use vars used in pipeline definition.
steps:
- script: |
echo "Build ID: $BUILD_BUILDID"
echo "Build number: $BUILD_BUILDNUMBER"
echo "Repository name: $BUILD_REPOSITORY_NAME"
displayName: 'Use predefined variables'
- script: |
echo "Custom variable: $MY_CUSTOM_VAR"
displayName: 'Use custom variable'
env:
MY_CUSTOM_VAR: $(myCustomVariable)
$(variable) Syntax
You can directly reference variables in your script content:
variables:
appName: 'my-app'
environment: 'dev'
steps:
- script: |
echo "Application name: $(appName)"
echo "Environment: $(environment)"
echo "Build reason: $(Build.Reason)"
displayName: 'Use variables directly'
Passing Script Args
variables:
deploymentRegion: 'eastus'
steps:
- script: |
echo "Region: $1"
echo "Build ID: $2"
displayName: 'Use variables as arguments'
arguments: '$(deploymentRegion) $(Build.BuildId)'
Vars in Script Output
You can also set variables from bash script output:
steps:
- script: |
current_time=$(date +%Y%m%d%H%M%S)
echo "##vso[task.setvariable variable=timestamp]$current_time"
displayName: 'Set variable from script'
- script: |
echo "Generated timestamp: $(timestamp)"
displayName: 'Use the set variable'
๐ Using Secret Variables
variables:
mySecret: $(secretPassword) # Defined in variable group or pipeline settings
steps:
- script: |
echo "Secret value is set (but won't be printed)"
# Use the secret in your script
export PASSWORD="$MY_SECRET"
displayName: 'Use secret variable'
env:
MY_SECRET: $(mySecret)
Example Diff Vars Types
variables:
- name: appName
value: 'my-application'
- name: environment
value: 'production'
- group: 'my-variable-group' # Reference to variable group
stages:
- stage: Build
jobs:
- job: BuildJob
steps:
- script: |
echo "Build Information:"
echo "Build ID: $BUILD_BUILDID"
echo "Build Number: $BUILD_BUILDNUMBER"
echo "Source Branch: $BUILD_SOURCEBRANCH"
echo ""
echo "Custom Variables:"
echo "App Name: $(appName)"
echo "Environment: $(environment)"
echo "Database URL: $(databaseUrl)" # From variable group
# Using variables in commands
docker build -t $(appName):$(Build.BuildNumber) .
# Set output variable
echo "##vso[task.setvariable variable=buildStatus;isOutput=true]success"
displayName: 'Build and set variables'
name: buildStep
env:
DOCKER_PASSWORD: $(dockerPassword) # Secret variable
- script: |
echo "Build status from previous step: $(buildStep.buildStatus)"
displayName: 'Use output variable'
Conditional Variable Usage
variables:
${{ if eq(variables['Build.SourceBranch'], 'refs/heads/main') }}:
environment: 'prod'
deployUrl: 'https://prod.example.com'
${{ else }}:
environment: 'dev'
deployUrl: 'https://dev.example.com'
steps:
- script: |
echo "Deploying to $(environment) environment"
echo "Target URL: $(deployUrl)"
# Use variables in conditional logic
if [ "$(environment)" = "prod" ]; then
echo "Running production deployment checks..."
fi
displayName: 'Conditional deployment'
Key Points to Remember
Predefined variables are automatically available as environment variables
Custom variables need to be mapped or used with $(variableName) syntax
Secret variables should only be passed through env mapping for security
Variable names are converted to uppercase with . replaced by _ in environment variables
Use ##vso[task.setvariable] syntax to set variables from script output
Output variables from one step can be referenced in subsequent steps using $(stepName.variableName)
๐ท๏ธ Spec. Vars
Build Vars
Variable Description Example
Build.BuildId Unique identifier for the build 12345
Build.BuildNumber Build number format 20240115.1
Build.SourceBranch Source branch name refs/heads/main
Build.SourceBranchName Short branch name main, feature-branch
Build.SourceVersion Commit ID a1b2c3d4e5f67890
Build.Repository.Name Repository name my-app
Build.Repository.Provider Repository type GitHub, TfsGit
Build.DefinitionName Pipeline definition name my-app-ci
Build.DefinitionVersion Pipeline version 1
Build.QueuedBy Who triggered the build John Doe
Build.RequestedFor For whom build was requested johndoe@example.com
Build.Reason Reason for build Manual, IndividualCI, PullRequest
System Vars
Variable Description Example
System.JobId Unique ID for the job a1b2c3d4-e5f6-7890-abcd-ef1234567890
System.StageName Current stage name build
System.JobName Current job name build_job
System.JobAttempt Job attempt number 1
System.PhaseId Phase ID 12345678-1234-1234-1234-123456789012
System.PhaseDisplayName Phase display name Job
System.StageAttempt Stage attempt number 1
PR Vars
Variable Description Example
System.PullRequest.PullRequestId PR ID 789
System.PullRequest.PullRequestNumber PR number 42
System.PullRequest.SourceBranch PR source branch refs/heads/feature-branch
System.PullRequest.TargetBranch PR target branch refs/heads/main
System.PullRequest.SourceRepositoryURI Source repo URI https://github.com/org/repo.git
There are much more e.g. Agent Variables, Pipeline Variables, ** Release Variables (For Release Pipelines)**
Env Vars
# Build information
echo "Build ID: $BUILD_BUILDID"
echo "Build Number: $BUILD_BUILDNUMBER"
echo "Source Branch: $BUILD_SOURCEBRANCH"
echo "Source Branch Name: $BUILD_SOURCEBRANCHNAME"
echo "Commit ID: $BUILD_SOURCEVERSION"
echo "Repository: $BUILD_REPOSITORY_NAME"
# System information
echo "Job ID: $SYSTEM_JOBID"
echo "Stage: $SYSTEM_STAGENAME"
echo "Job: $SYSTEM_JOBNAME"
# Agent information
echo "Agent OS: $AGENT_OS"
echo "Agent Name: $AGENT_NAME"
echo "Work Folder: $AGENT_WORKFOLDER"
# Pipeline information
echo "Workspace: $PIPELINE_WORKSPACE"
Example
steps:
- script: |
echo "=== BUILD INFORMATION ==="
echo "Build ID: $BUILD_BUILDID"
echo "Build Number: $BUILD_BUILDNUMBER"
echo "Branch: $BUILD_SOURCEBRANCHNAME"
echo "Commit: $BUILD_SOURCEVERSION"
echo "Repository: $BUILD_REPOSITORY_NAME"
echo "=== SYSTEM INFORMATION ==="
echo "OS: $AGENT_OS"
echo "Agent: $AGENT_NAME"
echo "Workspace: $PIPELINE_WORKSPACE"
echo "=== BUILD REASON ==="
echo "Reason: $BUILD_REASON"
echo "Requested by: $BUILD_REQUESTEDFOR"
# Conditional logic based on branch
if [ "$BUILD_SOURCEBRANCHNAME" = "main" ]; then
echo "This is a production build"
elif [ "$BUILD_SOURCEBRANCHNAME" = "develop" ]; then
echo "This is a development build"
fi
# Check if it's a PR build
if [ "$BUILD_REASON" = "PullRequest" ]; then
echo "PR ID: $SYSTEM_PULLREQUEST_PULLREQUESTID"
echo "Target Branch: $SYSTEM_PULLREQUEST_TARGETBRANCH"
fi
displayName: 'Display build information'
Most Useful
* Branch-specific: Build.SourceBranchName, Build.SourceBranch
* Versioning: Build.BuildNumber, Build.BuildId
* Repository: Build.Repository.Name, Build.SourceVersion
* Environment detection: Agent.OS, Build.Reason
* Path references: Agent.WorkFolder, Pipeline.Workspace
* Audit info: Build.QueuedBy, Build.RequestedFor