gitazureazure-pipelinescicd

How to Monitor a Triggered Build After PR CI Completes in Azure DevOps?


I have an Azure DevOps YAML pipeline that is triggered when my PR CI build completes successfully. This pipeline is responsible for deploying PR artifacts to a test environment for further validation.

While I managed to correctly trigger this deployment pipeline after my CI pipeline completes, I now need a way to monitor the status of this triggered build within the PR checks to ensure it is completed before the PR is merged.

Pipeline YAML (Triggering Pipeline - ProjectName-Deploy.yml)

trigger: none

parameters:
- name: TestTarget
  displayName: Test Target
  type: string
  default: Team2
  values:
  - DevMain
  - Main
  - Team1
  - Team2

resources:
  repositories:
    - repository: templates
      type: git
      name: BuildScripts/PipelineTemplate
  pipelines:
    - pipeline: BuildPipeline   
      source: MyProjectName (CI)  
      trigger: true

extends:
  template: TestEnvironmentDeploy.yml@templates
  parameters:
    ProjectName: $(System.TeamProject)
    TestTarget: ${{ parameters.TestTarget }}

What I Expect

Current Behavior:

MyProjectName (CI) runs as part of a PR validation build (triggered by branch policies). When MyProjectName (CI) completes, ProjectName-Deploy correctly triggers automatically as expected. However, the PR status check does not wait for ProjectName-Deploy to complete. Desired Behavior:

The PR should block merging until ProjectName-Deploy is fully completed (like it does for MyProjectName (CI)). ProjectName-Deploy should be included in the PR status check list, and its result should reflect in the PR.

What I Tried

  1. Adding ProjectName-Deploy to Build Validation (Branch Policies)

The issue with this approach is that setting it to Automatic runs it as soon as the PR is created, which means it runs with an outdated CI artifact. Setting it to Manual requires it to be run manually however the completion of the CI triggers another unmonitored run automatically.

  1. Adding ProjectName-Deploy as a Status Check NOTE: My azure pipeline is defined under a GIT sub repository

I manually added ProjectName-Deploy to Branch Policies → Status Checks. I tried using similar naming convention as for the Classic Release (which can be added to Status Checks)

I tried: pipelines/ProjectName-Deploy pipelines/GIT/ProjectName-Deploy buildpipelines/ProjectName-Deploy buildpipelines/GIT/ProjectName-Deploy

However, it remains stuck in "Waiting" since it does not seem to report its status back to Azure DevOps.

Im guessing that i would not be the first to need this type of CI/CD logic, so im guessing there must be something that im missing somewhere?

Thank you


Solution

  • Adding ProjectName-Deploy to Build Validation will indeed cause the problem you mentioned. The CD pipeline needs to be manually triggered again to reflect its status to the PR.

    For the status checks policy, according to doc Status checks,

    External services can use the PR Status API to post detailed status to your PRs. The branch policy for additional services enables those external services to participate in the PR workflow and establish policy requirements.

    You should use the REST API PR Status API to post detailed status to your PR. Refer to the steps below.

    1. Create a status check policy. For example,

      enter image description here

    2. Run REST API Pull Request Statuses - Create in the last step of your CD pipeline to create status to your PR.

      • In the request URL, you need to provide the ID of PR. This value can be retrieved from pipeline resource variable resources.pipeline.{pipelineidentifier}.sourceBranch .

      • In your request body.

        • state of PR is based on the Agent.JobStatus , which is the state of the agent job.

        • context.name and context.genre should be the same as what you defined in your status policy.

        YAML file:

        trigger: none
        
        pool:
          vmImage: ubuntu-latest
        
        resources:
          pipelines:
            - pipeline: TestBuildStatus-PR-CI  
              source: TestBuildStatus-PR-CI
              trigger: true
        
        steps:
        
        #  ... your steps
        
        - task: PowerShell@2
          displayName: 'Create PR status'
          condition: always()
          inputs:
            targetType: 'inline'
            script: |
              $header = @{'Authorization' = 'Bearer ' + "$(System.AccessToken)"}
        
              # Extract PRId from pipeline resource variables 
              $sourceBranch = "$(resources.pipeline.TestBuildStatus-PR-CI.sourceBranch)"
              $prId = $sourceBranch -replace 'refs/pull/(\d+)/merge', '$1'
        
              $url="https://dev.azure.com/{OrgName}/_apis/git/repositories/{RepoID}/pullRequests/$($prId)/statuses?api-version=4.1-preview.1"
        
              # Set PR status based on the status of the job
              if ($env:Agent_JobStatus -eq "Succeeded") {
                  $state = "succeeded"
              } else {
                  $state = "failed"
              }
        
              $body = @"
              {
                "state": "$state",
                "description": "CD pipeline status",
                "context": {
                  "name": "buildstatus",
                  "genre": "testbuildstatus-pr-cd"
                },
                "targetUrl": "https://dev.azure.com/{OrgName}/{ProjectName}/_build?definitionId={DefinitionIdOfYourCD}"
              }
              "@
              $head = @{ Authorization =" Basic $token" }
              Invoke-RestMethod -Uri $url -Method Post -Headers $header -Body $body -ContentType application/json
          env:
            Agent_JobStatus: $(Agent.JobStatus)
        

        Note:

        • Replace {} with your actual value.

        • The above script works only when CI is trigger by PR, because the Id of the PR is retrieved from pipeline resource variable resources.pipeline.{pipelineidentifier}.sourceBranch. You can adjust it according to your actual needs if you want it to apply to more situations.

    3. Result

      • When CD is succeeded.

        enter image description here

      • When CD is failed.

        enter image description here