Links
Definitions
Term
|
Definition
|
Artifact |
item from a git repository or a build pipeline
|
Stages |
steps to deploy and validate a software a stage contains jobs
|
Job |
subparts of a stage, contains tasks to execute listed as steps a job runs on a agent or can be manually ran
|
Tasks / Steps |
subparts of a job, those are the concreate action to execute
|
Release pipeline definition |
steps to execute to get the artefacts, install and validate the software template to run a release
|
Release agent |
the one who execute the tasks defined in the release pipeline definition it is the same agent as the one used for the build
|
Steps of a release
- Build the software with a pipeline
- validate product quality (unit tests, SonarCloud)
- Deploy the software
- validate runtime stability (compare telemetry with previous version)
- Release the feature
Name
|
Value
|
System.DefaultWorkingDirectory |
E:\Agent\Release_INT_2\_work\24\s
|
System.ArtifactsDirectory |
E:\Agent\Release_INT_2\_work\24\a
|
Pipeline.Workspace |
E:\Agent\Release_INT_2\_work\24
|
Trigger pipeline for PR
- Azure DevOps → MyProject → Project Settings (bottom left gear)
- Repos → Repositories → MyRepo
- Policies → Branch Policies → master
- Build Validation → +
YAML
Create a new pipeline
- Pipelines → New pipeline
- Azure Repo Git YAML → Select your repo → Existing Azure pipelines YAML file
Exemple
|
trigger: none
parameters:
- name: myStepList
type: stepList
default:
- bash: echo "We are on $(MyVar)"
stages:
- stage: CI
displayName: CI stage
dependsOn: []
jobs:
- job: ci_job
pool: MyPool
steps:
- powershell: Write-Host "We are on CI"
enabled: false
- stage: PROD
displayName: PROD stage
dependsOn: []
jobs:
- deployment: prod_job
environment: PROD
strategy:
runOnce:
deploy:
steps: ${{ parameters.myStepList }}
|
 |
If you specify no push trigger, pushes to any branch trigger a build. |
|
trigger:
batch: true
branches:
include:
- master
- release/*
exclude: temp
paths:
include: MyProject/*
exclude: temp
trigger: none
|
|
stages:
- stage: stage_name
displayName: 'Stage name'
variables:
condition:
jobs: [ job | templateReference]
|
|
jobs:
- job: job_name
displayName: 'Job name'
variables:
pool: PoolName
dependsOn: job1
dependsOn:
- job1
- job2
condition:
workspace:
clean: outputs | resources | all
steps: [ script | bash | pwsh | powershell | checkout | task | templateReference ]
|
|
jobs:
- deployment: job_name
environment: CI
CI.MyResource
pool: PoolName
strategy:
runOnce:
preDeploy:
steps:
deploy:
steps:
routeTraffic:
steps:
postRouteTraffic:
steps:
on:
failure:
steps:
success:
steps:
|
|
steps:
- task: TaskToCall@Version
name: StepName
displayName: 'My Step'
timeoutInMinutes: 120
inputs:
key: 'value'
enabled: boolean
- bash: |
which bash
echo Hello $(whoami)
displayName: Multiline Bash script
- pwsh: Write-Host Hello $(name)
- powershell: Write-Host Hello $(name)
- checkout: self | none | repo name
clean: boolean
fetchDepth: number
|
|
- powershell: 'cmd'
- powershell: |
cmd1
cmd2
- pwsh: 'cmd'
- task: PowerShell@2
displayName: 'PowerShell Script'
inputs:
targetType: filePath
filePath: 'MyScript.ps1'
arguments: '-Arg1 "Arg1"'
- task: PowerShell@2
displayName: 'PowerShell Script'
inputs:
targetType: inline
script: |
cmd1
cmd2
|
|
steps:
- publish: MyProject\bin\Release
artifact: MyProject
- task: PublishPipelineArtifact@1
inputs:
targetPath: MyProject\bin\Release
artifactName: MyProject
parallel: true
parallelCount: 8
|
|
steps:
- download: none
- download: current
artifact: ArtifactName
- task: DownloadPipelineArtifact@2
inputs:
artifact: ArtifactName
- task: DownloadPipelineArtifact@2
inputs:
buildType: 'specific'
project: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
pipeline: '0000'
buildVersionToDownload: 'specific'
buildId: '000000'
artifact: ArtifactName
downloadPath: $(System.DefaultWorkingDirectory)
|
- The Download Pipeline Artifact task can download both build artifacts (published with the Publish Build Artifacts task) and pipeline artifacts.
- By default, files are downloaded to $(Pipeline.Workspace)/{artifact name} (E:\Agent\Release_INT_2\_work\1\ArtefactName)
- Downloading artifacts
- Get project GUID: https://dev.azure.com/{organization}/_apis/projects
- Get the pipeline definition ID: https://dev.azure.com/{organization}/{project}/_apis/build/definitions?name={pipeline name}
- Get the build ID: https://dev.azure.com/{organization}/{project}/_apis/build/builds?definitions={pipeline definition ID}&buildNumber=x.x.xxxx.xxxxx
- Get Artifact name: https://dev.azure.com/{organization}/{project}/_apis/build/builds/{buildId}/artifacts
- Publish and download artifacts in Azure Pipelines
|
- task: DownloadBuildArtifacts@0
inputs:
buildType: 'specific'
project: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
pipeline: '0000'
buildVersionToDownload: 'specific'
buildId: '000000'
artifactName: ArtifactName
downloadPath: '$(System.ArtifactsDirectory)'
|
- By default, files are downloaded to $(System.ArtifactsDirectory)/{artifact}
|
- task: WindowsMachineFileCopy@2
displayName: 'Copy Files'
inputs:
sourcePath: '$(sourcePath)'
machineNames: '$(machineNames='
adminUserName: '$(adminUserName)'
adminPassword: '$(adminPassword)'
targetPath: '$(targetPath)'
additionalArguments: '/r:1 /w:10'
cleanTargetBeforeCopy: true
|
|
- task: PowerShellOnTargetMachines@3
inputs:
machines: '$(machines)'
userName: '$(userName)'
userPassword: '$(userPassword)'
scriptType: 'filePath'
scriptPath: '$(scriptPath)'
scriptArguments: '-Arg1 $(Arg1Value)'
communicationProtocol: http
- task: PowerShellOnTargetMachines@3
inputs:
machines: '$(machines)'
userName: '$(userName)'
userPassword: '$(userPassword)'
scriptType: 'inline'
inlineScript: |
echo 'Hello !'
communicationProtocol: http
|
|
- task: NuGetCommand@2
inputs:
command: restore
restoreSolution: MySolution.sln
|
|
- task: VSBuild@1
inputs:
solution: MyProject\MyProject.csproj
platform: AnyCPU
configuration: release
clean: false
msbuildArchitecture: x64
|
Replace tokens with variable values in XML or JSON configuration files.
|
- job:
variables:
Name1: Value1
- task: FileTransform@1
inputs:
folderPath: $(Pipeline.Workspace)\MyArtefact
fileType: xml
targetFiles: MyProject.exe.config
|
Modify a XML, JSON or YAML file.
|
- task: MagicChunks@2
inputs:
sourcePath: $(System.DefaultWorkingDirectory)\Folder\App.config
transformations: |
{
"root/node[@attribute1='value']/@attribute2": "true"
}
- task: MagicChunks@2
inputs:
sourcePath: $(System.DefaultWorkingDirectory)\Folder\App.config
transformationType: file
transformationsFile: $(System.DefaultWorkingDirectory)\Folder\Transformations.json
|
Transformations.json
|
{
"root/node[@attribute1='value']/@attribute2": "true"
}
|
|
pool: PoolName
pool:
name: PoolName
demands:
- myCustomCapability
- agent.os -equals Darwin
|
|
variables:
name1: 'value1'
name2: '${{ variables.name1 }} - value2'
variables:
- name: variable_name
value: 'value'
- group: group_name
steps:
- powershell: 'echo $(variable_name)'
- powershell: 'echo $(System.StageName)'
- powershell: 'echo $(group_variable_name)'
- powershell: 'echo $env:VARIABLE_NAME'
- powershell: 'echo $(variable_name)'
- powershell: 'echo ${{ variables.variable_name }}'
- powershell: 'echo $[variables.variable_name]'
- powershell: echo "##vso[task.setvariable variable=variable_name]variable value"
- powershell: echo $(variable_name)
jobs:
- job: A
steps:
- powershell: echo "##vso[task.setvariable variable=variable_name;isOutput=true]variable value"
name: task_name
- powershell: echo $(task_name.variable_name)
- job: B
dependsOn: A
variables:
var_from_job_A: $[ dependencies.A.outputs['task_name.variable_name'] ]
stages:
- stage: A
jobs:
- job: A1
steps:
- powershell: echo "##vso[task.setvariable variable=variable_name;isOutput=true]variable value"
name: task_name
- stage: B
dependsOn: A
variables:
var_from_stage_A: $[ stageDependencies.A.A1.outputs['task_name.variable_name'] ]
|
Ces paramètres sont sélectionnable à chaque lancement de la pipeline.
|
parameters:
- name: my_parameter
displayName: My parameter
type: string
default: Value1
values:
- Value1
- Value2
|
Repositories
 |
By default current pipeline repo is checked out. |
|
resources:
repositories:
- repository: RepoId
name: ProjectName/RepoName
type: git
ref: master
steps:
- checkout: self
- checkout: RepoId
|
 |
- Single repository: If you have a single checkout step in your job, (or no checkout step which is equivalent to checkout: self), your source code is checked out into $(Build.SourcesDirectory).
Ex: (C:\agent\_work\1\s)
- Multiple repositories: If you have multiple checkout steps in your job, your source code is checked out into directories named after the repositories as a subfolder of $(Build.SourcesDirectory).
Ex: C:\agent\_work\1\s\MyRepo
|
 |
It's as if you specified condition: succeeded() |
Condition
|
Description
|
succeeded() |
Only when all previous dependencies have succeeded. This is the default if there is not a condition set in the YAML.
|
succeededOrFailed() |
Even if a previous dependency has failed, unless the run was canceled.
|
always() |
Even if a previous dependency has failed, even if the run was canceled.
|
failed() |
Only when a previous dependency has failed.
|
|
condition: eq(variables.Var1, 'Value1')
condition: eq('${{ parameters.Param1 }}', 'Value1')
condition: or(eq(variables.Var1, 'Value1'), ne(variables.Var2, 'Value2'))
condition: in(variables['Build.Reason'], 'IndividualCI', 'BatchedCI')
dependsOn:
- Job1
- Job2
condition: and(succeeded(), eq(variables.Var1, 'Value1'))
condition: and(succeeded('Job2'), eq(variables.Var1, 'Value1'))
condition: |
and
(
in(dependencies.Job1.result, 'Succeeded', 'SucceededWithIssues', 'Skipped'),
in(dependencies.Job2.result, 'Succeeded', 'SucceededWithIssues', 'Skipped')
)
- stage: Stage2
condition: in(dependencies.Stage1.result, 'Succeeded', 'SucceededWithIssues', 'Skipped')
condition: eq(dependencies.Stage1.result, '')
condition: and(succeeded(), eq(dependencies.Stage1.outputs['Job1.Task1.Var1'], 'true'))
jobs:
- job: Job2
condition: in(stageDependencies.Stage1.Job1.result, 'Succeeded', 'SucceededWithIssues', 'Skipped')
condition: eq(stageDependencies.Stage1.Job1.outputs['Task1.Var1'], 'true')
condition: in(dependencies.Job3.result, 'Succeeded', 'SucceededWithIssues', 'Skipped')
condition: eq(dependencies.Job3.outputs['Task1.Var1'], 'true')
|
 |
You can specify conditions under which a step, job, or stage will run. |
 |
By default, each stage in a pipeline depends on the one just before it in the YAML file. |
|
variables:
${{ if eq(variables['Build.SourceBranchName'], 'master') }}:
var_name: value
steps:
- ${{ if eq(parameters.param_name, 'value') }}:
- task:
- task:
inputs:
${{ if eq(variables['Build.SourceBranchName'], 'master') }}:
input_name: 'value'
|
Reuse stages, jobs ans tasks.
stages-template.yml
|
stages:
- stage: Stage1
jobs:
- job: Job1
steps:
- script: echo 'stages template'
|
jobs-template.yml
|
jobs:
- job: Job1
steps:
- script: echo 'jobs template'
|
tasks-template.yml
|
steps:
- script: echo 'tasks template'
|
my-pipeline.yml
|
stages:
- template: stages-template.yml
- stage: Stage2
jobs:
- template: jobs-template.yml
- stage: Stage3
jobs:
- job: ExcecuteTasks
steps:
- template: tasks-template.yml
|
Copy the template in the pipeline.
my-template.yml
|
resources:
repositories:
- repository: MyRepo
type: git
name: MyProject/MyRepo
steps:
- script: echo "My template"
|
my-pipepline.yml
|
extends:
template: my-template.yml
|
tasks-template.yml
|
parameters:
parameterName: 'parameter value'
steps:
- script: echo ${{ parameters.parameterName}}
|
my-pipepline.yml
|
variables:
var: 'value'
steps:
- template: tasks-template.yml
parameters:
parameterName: 'value'
parameterName: ${{ variables.var }}
|
Condition on a template
 |
It is not possible to set a condition on a template. |
Solution 1: pass a parameter to the template.
steps-template.yml
|
parameters:
enabled: true
steps:
- script: echo 'Task 1'
condition: ${{ parameters.enabled }}
|
my-pipepline.yml
|
steps:
- template: steps-template.yml
parameters:
enabled: false
|
Solution 2: use if.
my-pipepline.yml
|
steps:
- ${{ if eq($(MyVar), 'value') }}:
- template: steps-template.yml
|
Errors
- Pipelines → Environments → Select the env xxx → 3 dots button on top right → Security
- Add the user with User role