Trigger Azure DevOps pipeline from another pipeline

Viewed 5051

I was looking at the azure triggers documentation and still not able to find an appropriate solution. How during the execution of pipeline 1 can you trigger pipeline 2, wait for it to successfully finish or fail, and based on pipeline 2 results either continue execution of pipeline 1 or fail?

4 Answers

How during the execution of pipeline 1 can you trigger pipeline 2, wait for it to successfully finish or fail, and based on pipeline 2 results either continue execution of pipeline 1 or fail?

Trigger one pipeline after another, it will run your pipeline upon the successful completion of the triggering pipeline. We cannot use it to trigger pipeline 1 in the execution of pipeline 1.

As a workaround:

a. We can add task power shell and add script to call the REST API to queue the build.

$connectionToken="PAT"
$base64AuthInfo= [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($connectionToken)"))
$PipelineUrl = "https://dev.azure.com/{Org name}/{project name}/_apis/pipelines/{Pipeline ID}/runs?api-version=6.0-preview.1" 

$body ="{ 
 `"resources`":{
        `"repositories`":{
            `"self`":{`"refName`":`"refs/heads/master`"
            }
         }
    }
}"
$Pipelines = Invoke-RestMethod -Uri $PipelineUrl -ContentType "application/json" -Body $body -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)} -Method POST

b. Add task power shell and enter the code Start-Sleep -Seconds 1000 to sleep the pipeline 1

c. Add the task power shell in the pipeline 1 to get the pipeline 2 build result via the REST API, and set the result as env variable.

d. Configure the condition in the next task to check the env variable value. If the value is succeeded, continue run the pipeline 1

You are probably looking for something like this.

# this is being defined in app-ci pipeline
resources:
  pipelines:
  - pipeline: securitylib   # Name of the pipeline resource
    source: security-lib-ci # Name of the pipeline referenced by the pipeline resource
    trigger: 
      branches:
      - releases/*
      - master

its right there in the link, you have linked, but in the sibling section of the docs. I am surprised you missed it.

https://docs.microsoft.com/en-us/azure/devops/pipelines/process/pipeline-triggers?view=azure-devops&tabs=yaml

So here is my solution based on the suggestion above:

- task: PowerShell@2
  displayName: Running second pipeline
  inputs:
       targetType: 'inline'
       script: |
        Write-Host "Triggering pipeline..."
        $connectionToken= "$(PAT)"

        $base64AuthInfo= [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($connectionToken)"))
        $PipelineUrl = "https://dev.azure.com/YourOrganization/yourProject/_apis/pipelines/${{ parameters.pipelineId }}/runs?api-version=6.0-preview.1" 
        Write-Host "Pipeline url: $PipelineUrl"
        $body ="{ 
         `"resources`":{
                `"repositories`":{
                    `"self`":{`"refName`":`"refs/heads/${{ parameters.branch }}`"
                    }
                 }
            }
        }"       
        $response = Invoke-RestMethod -Uri $PipelineUrl -ContentType "application/json" -Body $body -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)} -Method POST
        Write-Host "Response: $response"
        $BuildUrl = "https://dev.azure.com/YourOrganization/yourProject/_apis/build/builds/$($response.Id)?api-version=6.1-preview.6"
        Write-Host  $BuildUrl
        
        $TimeoutAfter = New-TimeSpan -Minutes 15
        $WaitBetweenPolling = New-TimeSpan -Seconds 10
        $Timeout = (Get-Date).Add($TimeoutAfter)
        do
        {
        $Response = Invoke-RestMethod -Uri $BuildUrl -ContentType "application/json" -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)}
        Write-Host $Response.status
        Start-Sleep -Seconds $WaitBetweenPolling.Seconds
        }
        while ((($Response.status -eq "notStarted") -or ($Response.status -eq "inProgress")) -and ((Get-Date) -lt $Timeout))
        
        if ($Response.result -ne "succeeded")
        {
            Write-Host $Response.result
            exit 1
        }

parameter for pipeline id: pipelineId: $(resources.pipeline.resource.pipelineId)

If you're ok with using extensions, the Trigger Build Task you can get in the marketplace should support all of your requirements.

It lets you trigger another pipeline, with an option to wait for it, and options about how to treat failures of that pipeline if you do wait. So you can use that to trigger a build, wait for it, and succeed / fail based on if the build succeeds / fails.

Related