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
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.
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
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.
Create a status check policy. For example,
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.
Result