Reputation: 317
I need to run a publish task in my build definition but only if a certain task before it has failed. If the other task passes I want this to be ignored and not run.
Is there a way of doing this?
I was hoping that I could set an output variable based on the task success and then use that variable in a custom condition to run the task if it's failed.
I can't see how to set an output variable if the task fails. Is this possible?
Upvotes: 7
Views: 7253
Reputation: 1017
Based on @Merivale's answer this was the code that worked for me;
$targetTaskName = "SomeTaskName"
$pat = ":$(System.AccessToken)"
$b = [System.Text.Encoding]::ASCII.GetBytes($pat)
$token = [System.Convert]::ToBase64String($b)
$releaseURL="$(System.TeamFoundationServerUri)"
$releaseId= $(Release.ReleaseId)
$environmentId = $(Release.EnvironmentId)
$releaseAttemptNumber = $(Release.AttemptNumber)
$releaseREST_p1="$releaseURL"
$releaseREST=$releaseREST_p1+"$(System.TeamProject)/_apis/release/releases/$releaseId/environments/$environmentId/?api-version=5.1-preview.6"
Write-Host "GET request to Azure Pipelines with URL: $releaseREST"
$result= Invoke-RestMethod -Method GET -Uri $releaseREST -ContentType "application/json" -Headers @{'Authorization' = "Basic $token"}
$targetReleaseAttempt = $result.deploySteps | where { $_.attempt -eq $releaseAttemptNumber}
$targetTask = $targetReleaseAttempt.releaseDeployPhases.deploymentJobs.tasks | where { $_.name -eq $targetTaskName }
$targetTask
$targetTaskStatus = $targetTask.status
Write-Host "Setting variable releaseStatus to $targetTaskStatus"
Write-Host "##vso[task.setvariable variable=releaseStatus;]$targetTaskStatus"
Upvotes: 0
Reputation: 11
Further to starian chen-MSFT's code, which will work for build pipelines, below is what I pulled together for release pipelines (in case it is useful for anyone). This will output a pipeline variable "deploymentStatus" that equals the status of the task (as defined by Azure DevOps: https://learn.microsoft.com/en-us/rest/api/azure/devops/release/releases/get%20release?view=azure-devops-rest-5.1#taskstatus):
$targetTaskName = "Some Task Name"
$token = $env:System_AccessToken
$releaseURL = $env:System_TeamFoundationServerUri
$projectName = $env:System_TeamProject
$releaseId= $env:Release_ReleaseId
$environmentId = $env:Release_EnvironmentId
$releaseAttemptNumber = $env:Release_AttemptNumber
$releaseREST="$releaseURL$projectName/_apis/release/releases/$releaseId/environments/$environmentId/?api-version=5.1-preview.6"
Write-Host "GET request to Azure Pipelines with URL: $releaseREST"
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f "test",$token)))
$result= Invoke-RestMethod -Method GET -Uri $releaseREST -ContentType "application/json" -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)}
$targetReleaseAttempt = $result.deploySteps | where { $_.attempt -eq $releaseAttemptNumber}
$targetTask = $targetReleaseAttempt.releaseDeployPhases.deploymentJobs.tasks | where { $_.name -eq $targetTaskName }
$targetTask
$targetTaskStatus = $targetTask.status
Write-Host "Setting variable deploymentStatus to $targetTaskStatus"
Write-Host "##vso[task.setvariable variable=deploymentStatus;]$targetTaskStatus"
Upvotes: 1
Reputation: 41765
Only when a previous task has failed
.If you want to run the task only if last/specific task failed:
Suppose your specific task (the one you examine in regards to its status) is called A
. The goal is to call another build task (let's say B
) only in case A
fails.
task.A.status
and set to success
C
and schedule it right after A
; condition it to only run if A
fails - there's a standard condition for thatC
should only do one thing - set task.A.status
build variable to 'failure' (like this, if we are talking PowerShell: Write-Host "##vso[task.setvariable variable=task.A.status]failure"
)B
is scheduled sometime after C
and is conditioned to run in case task.A.status
equals failure
, like this: eq(variables['task.A.status'], 'failure')
Upvotes: 5
Reputation: 33738
You can check previous tasks through PowerShell with build REST API, for example to check taskA (display name) and run taskB if taskA failed:
Allow scripts to access the OAuth token
option in the PhaseOnly when a previous task has failed
; Arguments: -targetTaskName "taskA" -collectionURL $(Build.Repository.Uri) -projectName $(System.TeamProject) -buildId $(Build.BuildId) -token $(System.AccessToken)
)Code:
param(
[string]$token,
[string]$targetTaskName,
[string]$collectionURL,
[string]$projectName,
[string]$buildId
)
$buildTimelineREST="$collectionURL$projectName/_apis/build/builds/$buildId/Timeline?api-version=4.1"
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f "test",$token)))
$result= Invoke-RestMethod -Method GET -Uri $buildTimelineREST -ContentType "application/json" -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)}
$targetTask=$result.records | where { $_.Name -eq $targetTaskName }
Write-Host $targetTask.result
if($targetTask.result -eq "failed"){
Write-Host "##vso[task.setvariable variable=isTaskAFailed;]true"
}
Custom conditions
; Custom condition: eq(variables['isTaskAFailed'],'true'
)Upvotes: 4