As it is possible to stop a single step in a Azure DevOps pipeline:
echo "##vso[task.complete result=Succeeded;]DONE"
Is it also possible to check a condition and stop the whole pipeline run or job depending on that?
PS. I know, you can set conditions to jobs, but in my case the whole pipeline is a single job and it does not make sense to split it into multiple jobs, because of other reasons.
You can cancel a build through REST API:
PATCH https://dev.azure.com/atbagga/atbagga/_apis/build/Builds/120
Request content: {'status': 'Cancelling'}
Here you have an example:
steps:
- task: PowerShell@2
name: ConditionalStep
inputs:
targetType: 'inline'
script: |
Write-Host "I'm here"
Write-Host ('$(SomeVariable)' -eq 'Stop')
if ('$(SomeVariable)' -eq 'Stop') {
$uri = "https://dev.azure.com/thecodemanual/DevOps Manual/_apis/build/builds/$(Build.BuildId)?api-version=5.1"
$json = @{status="Cancelling"} | ConvertTo-Json -Compress
$build = Invoke-RestMethod -Uri $uri -Method Patch -Headers @{Authorization = "Bearer $(System.AccessToken)"} -ContentType "application/json" -Body $json
Write-Host $build
}
Write-Host "And now here!"
pwsh: true
- pwsh: Start-Sleep -Seconds 60
- task: PowerShell@2
inputs:
targetType: 'inline'
script: |
$uri = "https://dev.azure.com/thecodemanual/DevOps Manual/_apis/build/builds/$(Build.BuildId)/timeline?api-version=5.1"
Write-Host $uri
# Invoke the REST call
$build = Invoke-RestMethod -Uri $uri -Method Get -Headers @{Authorization = "Bearer $(System.AccessToken)"} -ContentType "application/json"
$taskResult = $build.records | Where-Object {$_.name -eq "ConditionalStep" } | Select-Object result
Write-Host $taskResult.result
pwsh: true
For that you will get that output:
If you get such error:
| {"$id":"1","innerException":null,"message":"Access denied. | DevOps Manual Build Service (thecodemanual) needs Stop builds | permissions for vstfs:///Build/Build/1611 in team project | DevOps Manual to perform the | action.","typeName":"Microsoft.TeamFoundation.Build.WebApi.AccessDeniedException, Microsoft.TeamFoundation.Build2.WebApi","typeKey":"AccessDeniedException","errorCode":0,"eventId":3000}
Please make sure that your build account has permission to stop a build:
You will find this under this section:
Please note
What you can't do is set a build as completed. If you dod this. Whole pipeline will be still executed. So if this isn't what you want, you need to add condition to every step with an output variable set previously in the pipeline and in that way ignore those steps.
steps:
- task: PowerShell@2
name: ConditionalStep
inputs:
targetType: 'inline'
script: |
Write-Host "I'm here"
Write-Host ('$(SomeVariable)' -eq 'Stop')
if ('$(SomeVariable)' -eq 'Stop') {
Write-Host '##vso[task.setvariable variable=shouldStop;isOutput=true]Yes'
}
Write-Host "And now here!"
pwsh: true
- pwsh: Start-Sleep -Seconds 60
condition: ne(variables['ConditionalStep.shouldStop'], 'Yes')
- task: PowerShell@2
condition: ne(variables['ConditionalStep.shouldStop'], 'Yes')
inputs:
targetType: 'inline'
script: |
$uri = "https://dev.azure.com/thecodemanual/DevOps Manual/_apis/build/builds/$(Build.BuildId)/timeline?api-version=5.1"
Write-Host $uri
# Invoke the REST call
$build = Invoke-RestMethod -Uri $uri -Method Get -Headers @{Authorization = "Bearer $(System.AccessToken)"} -ContentType "application/json"
$taskResult = $build.records | Where-Object {$_.name -eq "ConditionalStep" } | Select-Object result
Write-Host $taskResult.result
pwsh: true