Search code examples
azure-devopsazure-pipelinesazure-devops-rest-api

Azure Pipeline - Skip Stages


I have a main pipeline where I choose which stages should be triggered. This main pipeline calls other pipelines. From these pipelines there should also just be triggered the stage from the main one. I found that there is a stagesToSkip parameter. But it doesn't matter what I choose there. There will all be triggered all stages in the called pipeline. What is the error?

$targetEnvironment = 'dev'

$stages = @("dev", "staging", "prod") | Where-Object { $_ -ne $targetEnvironment } | ConvertTo-Json
$body = "{
    `"stagesToSkip`" : $(ConvertTo-Json($stages))
}"
Invoke-RestMethod -Uri $url -Headers @{Authorization = "Basic $token"} -Method Post -Body $body -ContentType application/json

Solution

  • I have done it like in the link. I could find my mistake. $stages is already an Array. So the snippet has just to be "stagesToSkip" : $stages

    Yes, you need to fix the stagesToSkip value. I added the sample below, which will only trigger the target environment dev stage, and skip staging, prod stages.

    pool:
      vmImage: Windows-latest
    
    steps:
    - checkout: none
    - powershell: |
        $url="https://dev.azure.com/{org}/{project}/_apis/pipelines/{pipelineid}/runs?api-version=6.0-preview.1"
        $targetEnvironment = 'dev'
    
        $stages = @("dev", "staging", "prod") | Where-Object { $_ -ne $targetEnvironment } | ConvertTo-Json
        $body = "{
            `"stagesToSkip`" : $stages
        }"
        Invoke-RestMethod -Uri $url -Headers @{Authorization = "Bearer $(System.AccessToken)"} -Method Post -Body $body -ContentType application/json
    

    Only run the target dev stage:

    enter image description here

    I used system.acccesstoken instead of pat, just need to grant queue builds permission for the build service account on target pipeline.

    enter image description here

    Regarding your new query:

    It would be better if it's possible to say which stages should be runned and not which ones has to be skipped.

    You can use rest api Runs - Run Pipeline to trigger the target pipeline, meanwhile transfer the parameter which contains the target stages. On the target pipeline, run the stages with conditions.

    sample as below, main yaml, please replace target pipeline definition id with yours.

    pool:
      vmImage: Windows-latest
    
    parameters:
    - name: stages
      type: string
      default: dev, staging, prod
    
    steps:
    - checkout: none
    
    - task: PowerShell@2
      inputs:
        targetType: 'inline'
        script: |
          $body = '
          { 
                  "definition": {
                      "id": 401         
                  },
                  "templateParameters": {
                    "stages": "${{ parameters.stages}}"
                 }
          }
          '
    
          $Uri = "https://dev.azure.com/{org}/{project}/_apis/build/builds?api-version=7.1-preview.7"
          $buildresponse = Invoke-RestMethod -Method Post -ContentType "application/json" -Uri $Uri -Body $body -Headers @{Authorization = "Bearer $(System.AccessToken)"}
          write-host $buildresponse
    

    Target pipeline:

    parameters:
    - name: stages
      type: string
    
    pool:
      vmImage: ubuntu-latest
    
    variables:
      stageList: ${{parameters.stages}}
    
    stages:
    - stage: dev
      condition: contains(variables.stageList, 'dev')
      jobs:
      - job: A
        steps:
        - bash: echo "A"
    
    - stage: staging
      condition: contains(variables.stageList, 'staging')
      jobs:
      - job: B
        steps:
        - bash: echo "B"
    
    - stage: prod
      condition: contains(variables.stageList, 'prod')
      jobs:
      - job: C
        steps:
        - bash: echo "C"
    

    When i run the main pipeline, can specify the stages to run: enter image description here

    Target pipeline triggered, without staging stage.

    enter image description here