In Azure pipelines, i'm trying to use previous stage results for the following:-
#main.yml
stages:
- stage: Stage1
dependsOn: []
jobs:
- template: PipelineTemplates/first.yml
- stage: Stage2
dependsOn: []
jobs:
- template: PipelineTemplates/second.yml
- stage: Stage3
dependsOn: []
jobs:
- template: PipelineTemplates/third.yml
- stage: Stage4
dependsOn:
- Stage1
- Stage2
- Stage3
condition: or(succeeded('Stage1'),succeeded('Stage2'),succeeded('Stage3'))
jobs:
- template: PipelineTemplates/fourth.yml
#fourth.yml
jobs:
- job:
pool:
vmImage: 'windows-latest'
variables:
Friendly_Stage1_Name: 'Stage1'
Friendly_Stage2_Name: 'Stage2'
Friendly_Stage3_Name: 'Stage3'
Stage1_IsSuccess: $[eq(stageDependencies.variables['Friendly_Stage1_Name'].result,'Succeeded')]
Stage2_IsSuccess: $[eq(stageDependencies.variables['Friendly_Stage2_Name'].result,'Succeeded')]
Stage3_IsSuccess: $[eq(stageDependencies.variables['Friendly_Stage3_Name'].result,'Succeeded')]
steps:
- task: PowerShell@2
inputs:
targetType: 'inline'
script: |
$Stage1_status = if ($env:Stage1_IsSuccess) {"✔"} else {"❌"}
$Stage2_status = if ($env:Stage2_IsSuccess) {"✔"} else {"❌"}
$Stage3_status = if ($env:Stage3_IsSuccess) {"✔"} else {"❌"}
$Stages_Status = "{0}:{1} | {2}:{3} | {4}:{5}" -f
$env:Friendly_Stage1_Name, $Stage1_status, `
$env:Friendly_Stage2_Name, $Stage2_status, `
$env:Friendly_Stage3_Name, $Stage3_status
Write-Host "##vso[task.setvariable variable=Stages_Status]$Stages_Status"
- script: echo "$Stages_Status"
- task: SomeTask@1
condition: eq($(Stage1_IsSuccess),true) # should run only if stage 1 succeeds
- task: SomeTask@1
condition: eq($(Stage2_IsSuccess),true) # should run only if stage 2 succeeds
- task: SomeTask@1
condition: eq($(Stage3_IsSuccess),true) # should run only if stage 3 succeeds
When I run the pipeline with stage 1-2 passing and stage3 failing the PowerShell task in fourth.yml file just outputs Stage1:✔ | Stage2:✔ | Stage3:✔
for Stages_Status
, which means they're all true even when I run the stages with some failing.
All the SomeTask@1
's are skipped because they haven't met the conditions. Which means they're all false.
I've tried things like using dependencies instead, trying to pass down stageDependencies.result as a parameter from the main.yml file. Using stageDependencies.result on the task condition. None of that seems to work.
Based on your description, I generated the YAML pipeline below and reproduced the same issue. I had tested to use several different expressions like Stage1_Result: $[eq(dependencies.Stage1.result, 'Succeeded')]
, Stage1_IsSuccess: $[eq(stageDependencies.Stage1.result,'Succeeded')]
, Stage1_In: $[in(dependencies.Stage1.result, 'Succeeded')]
and Stage1_S: $[succeeded('Stage1')]
, but all in vain. It seems that such expressions only work in condition
but cannot be used to define variables, as discussed in this issue. Interestingly, the expression Stage1_Succeeded: $[eq(stageDependencies.Stage1.job1.result, 'Succeeded')]
to check a job result works. I understand this may not be what you would expect.
You may consider report the behavior in Developer Community and see if the Product Group have a plan to fix this behavior.
As of now, you can test with this API in a PowerShell script from Stage4
to check the results of previous stages as a workaround. Here is a sample for your reference.
GET $(System.CollectionUri)/$(System.TeamProject)/_apis/build/builds/$(Build.BuildId)/Timeline?api-version=7.1-preview.2
stages:
- stage: Stage1
dependsOn: []
jobs:
- job: Job1
steps:
- checkout: none
- task: PowerShell@2
inputs:
targetType: 'inline'
script: |
Write-Host Stage - $(System.StageName)
- stage: Stage2
dependsOn: []
jobs:
- job: Job2
steps:
- checkout: none
- task: PowerShell@2
inputs:
targetType: 'inline'
script: |
Write-Host Stage - $(System.StageName)
- stage: Stage3
dependsOn: []
jobs:
- job: Job3
steps:
- checkout: none
- task: PowerShell@2
inputs:
targetType: 'inline'
script: |
Write-Host Stage - $(System.StageName)
Write-Host "##vso[task.logissue type=error]log an error message of the task failure"
Write-Host "##vso[task.complete result=Failed;]"
- stage: Stage4
variables:
Stage1_Result: $[eq(dependencies.Stage1.result, 'Succeeded')]
Stage1_In: $[in(dependencies.Stage1.result, 'Succeeded')]
# Stage1_S: $[succeeded('Stage1')]
dependsOn:
- Stage1
- Stage2
- Stage3
condition: or(succeeded('Stage1'),succeeded('Stage2'),succeeded('Stage3'))
# condition: in(dependencies.Stage1.result, 'Succeeded')
# condition: eq(dependencies.Stage1.result, 'Succeeded')
jobs:
- job:
pool:
vmImage: 'windows-latest'
variables:
Stage1_Succeeded: $[eq(stageDependencies.Stage1.job1.result, 'Succeeded')]
Stage1_IsSuccess: $[eq(stageDependencies.Stage1.result,'Succeeded')]
steps:
- checkout: none
- powershell: |
# URL for the Azure DevOps REST API
$Url = "$(System.CollectionUri)/$(System.TeamProject)/_apis/build/builds/$(Build.BuildId)/Timeline?api-version=7.1-preview.2"
# Use System.AccessToken of pipeline for authentication
$headers = @{
'Authorization' = "bearer " + "$(System.AccessToken)"
'Content-Type' = 'application/json'
}
# Make the API request
$response = Invoke-RestMethod -Uri $Url -Headers $headers -Method Get
# Check if the request was successful
if ($response -ne $null) {
# Iterate over each timeline record
foreach ($record in $response.records) {
# Check if the record type is "Stage"
if ($record.type -eq "Stage") {
# Dynamically create variables for stage results
$variableName = $record.identifier + "_Result"
New-Variable -Name $variableName -Value $record.result -Force
# Print the created variable's name and value
# Write-Host "$variableName is $($record.result)"
}
}
}
else {
Write-Host "Failed to retrieve timeline records."
}
# Print the result of each previous stage
Write-Host Stage1_Result - $Stage1_Result
Write-Host Stage2_Result - $Stage2_Result
Write-Host Stage3_Result - $Stage3_Result
$Stage1_status = if ($Stage1_Result -eq 'Succeeded') {"✔"} else {"❌"}
$Stage2_status = if ($Stage2_Result -eq 'Succeeded') {"✔"} else {"❌"}
$Stage3_status = if ($Stage3_Result -eq 'Succeeded') {"✔"} else {"❌"}
Write-Host Stage1_status - $Stage1_status
Write-Host Stage2_status - $Stage2_status
Write-Host Stage3_status - $Stage3_status