Question

Is it possible to determine which stages of a multi-stage YAML pipeline were queued?

When manually queuing a multi-stage YAML pipeline, you can specify which stages to include/exclude by deselecting them in Stages. Similarly, the Azure DevOps REST API allows you to accomplish the same thing by specifying the stagesToSkip in the post BODY..

POST https://dev.azure.com/{organization}/{project}/_apis/pipelines/{pipelineId}/runs?api-version=7.2-preview.1

Body:

{
  "stagesToSkip": [
     "test",
     "uat",
     "prod"
  ]
}

Is there any endpoint that can be used to query which stages were intended for the pipeline run?

Scenarios:

  • Suppose I want to programmatically locate all builds that were queued manually but excluded a specific environment?
  • Execute a script in the pipeline to determine which future actions will be taken. For example, if I have deselected the Performance-Test stage, i can alter the compilation step. I know I can do this via pipeline variables or parameter inputs, but the "Stages to Run" is an equivalent of user-intent.
 3  67  3
1 Jan 1970

Solution

 2

You can use the Timeline - Get to get the details for a build.

However, if you need to get the stage status, you can only get the results of the completed stages, and the results of the pending and inProgress stages are empty.

For example, I have three stages build, performanceTest and deploy in the following yaml sample.

trigger:
- none

pool:
  vmImage: ubuntu-latest

stages:
  - stage: build
    jobs:
      - job: AA
        steps:
          - task: PowerShell@2
            inputs:
              targetType: 'inline'
              script: |
                # Define parameters
                $organization = "$(System.CollectionUri)"
                $project = "$(System.TeamProject)"
                $buildId = $(Build.BuildId)
                                
                # Define the URL for the Timeline API
                $url = "$organization$project/_apis/build/builds/$buildId/timeline/?api-version=7.1-preview.2"
                
                # Make the API request
                $response = Invoke-RestMethod -Uri $url -Method Get -ContentType "application/json" -Headers @{Authorization = "Bearer $(System.AccessToken)"} 
                
                # Parse the response to get the stages
                $stages = $response.records | Where-Object { $_.type -eq "Stage" }
                
                # Output the stages
                $stages | ForEach-Object {
                    Write-Output ("Stage: " + $_.name + ", State: " + $_.state + ", Result: " + $_.result  )
                }
                
  - stage: performanceTest
    jobs:
      - job: BB
        steps:
          - bash: echo "hello Performance-Test"

  - stage: deploy
    jobs:
      - job: CC
        steps:
          - task: PowerShell@2
            inputs:
              targetType: 'inline'
              script: |
                # Define parameters
                $organization = "$(System.CollectionUri)"
                $project = "$(System.TeamProject)"
                $buildId = $(Build.BuildId)
                                
                # Define the URL for the Timeline API
                $url = "$organization$project/_apis/build/builds/$buildId/timeline/?api-version=7.1-preview.2"
                
                # Make the API request
                $response = Invoke-RestMethod -Uri $url -Method Get -ContentType "application/json" -Headers @{Authorization = "Bearer $(System.AccessToken)"} 
                
                # Parse the response to get the stages
                $stages = $response.records | Where-Object { $_.type -eq "Stage" }
                
                # Output the stages
                $stages | ForEach-Object {
                    Write-Output ("Stage: " + $_.name + ", State: " + $_.state + ", Result: " + $_.result  )
                }

If I deselect the performanceTest stage and use the same script to get the status of the stages in the build and deploy stage, the result:

result

In this case, if you want to deselect the performanceTest stage and alter the compilation step based on it, you should add the script in the stage after the performanceTest stage where you can get the performanceTest stage Result: skipped.

2024-07-05
Miao Tian-MSFT