Although the question is old, I had the same problem and I think I have a good solution. The challenge is to ensure that the solution works even if multiple commits are pushed simultaneously, or if a build fails (and therefore doesn't deploy) or on PR merges where deployments only happen on the main branch.
I've described my solution in full in this gist: https://gist.github.com/Myrddraal/f5a84cf3242e3b3804fa727005ed2786
It takes advantage of the pipelines API, which can provide a list of all commits since the last successful pipeline execution. This ensures that it works even when multiple commits are pushed at once, or when the build with the infrastructure change failed. The pipelines API does the hard work of working out which commits need checking.
The logic is in this powershell:
[CmdletBinding()]
param (
$authorisation,
$pathFilter,
$collectionUri,
$project,
$buildId
)
$changesUrl = "$collectionUri/$project/_apis/build/builds/$buildId/changes?api-version=6.0"
$changesResponse = Invoke-RestMethod -Uri $changesUrl -Headers @{Authorization = $authorisation } -Method Get
$commits = @($changesResponse.value | ForEach-Object { $_.id })
Write-Host "##vso[task.setvariable variable=filesUpdated;isOutput=true]False"
Write-Host "Checking $($commits.Length) commits for changes matching path $pathFilter"
for ($j = 0; $j -lt $commits.Length; $j++) {
Write-Host "Checking commit: $($commits[$j]) with its parent"
$files = $(git diff "$($commits[$j])~" $commits[$j] --name-only)
Write-Host $files
if ($files -like "*$pathFilter/*") {
Write-Host "Found file matching path filter in commit $($commits[$j])"
Write-Host "##vso[task.setvariable variable=filesUpdated;isOutput=true]True"
break
}
}
Invoke it with the following YAML (in a build job after pulling the repository):
- task: PowerShell@2
inputs:
filePath: "azure-pipelines/Test-ChangesMadeInPath.ps1"
arguments: >-
-authorisation "Bearer $(system.accesstoken)"
-pathFilter "azure-pipelines/deployment"
-buildId $(Build.BuildId)'
-collectionUri $(System.CollectionUri)
-project $(System.TeamProject)
name: DetermineChangesMadeInDeploymentFolder
env:
SYSTEM_ACCESSTOKEN: $(system.accesstoken)
Then add the following condition to your deployment job:
- deployment: DeployInfrastructure
condition: eq(stageDependencies.Build.BuildJob.outputs['DetermineChangesMadeInDeploymentFolder.filesUpdated'], 'True')
displayName: Deploy infrastructure
environment: "prod"
strategy:
runOnce:
deploy:
steps:
- template: deployment/YAML/deploy-infrastructure.yml
parameters:
environment: $(Environment.Name)
Should run docker?
and set a variable there, then use that variable on the jobBuilding docker container
, that way it's clear whether docker was built or not. – Vastah