Understanding Azure Pipelines PR Validation for Azure Repos
Many developers encounter a common point of confusion when setting up automated checks for pull requests (PRs) in Azure Pipelines. You meticulously configure a pr: block within your YAML pipeline, expecting it to trigger a build whenever a PR is opened against your main branch. However, you might notice these pipelines never actually run for your pull requests, leading to frustration and wasted effort. The root cause isn't a typo in your YAML, but a fundamental difference in how Azure Pipelines handles PR triggers for different Git repository types.
Microsoft's documentation is explicit on this matter: for repositories hosted in Azure Repos Git, the pr: key in your YAML file is effectively inert. While this directive functions correctly for repositories hosted on GitHub and Bitbucket Cloud, it does not initiate pipeline runs for Azure Repos Git. This is not an error condition; the pipeline will parse the YAML without complaint, but the PR trigger will simply never fire.
The mechanism for enabling PR validation on Azure Repos Git repositories is entirely distinct. Instead of relying on the YAML configuration, it is implemented through branch policies. To enforce build validation on incoming changes, you must configure the Build validation policy directly on the target branch within your Azure Repos Git repository settings. This policy acts as the gatekeeper, ensuring that your pipeline runs and assesses the code *before* it can be merged.

Why the `pr:` Directive Fails for Azure Repos
The existence of the pr: key in the Azure Pipelines YAML schema can be misleading. It is a valid construct and works as expected for integrations with external Git providers like GitHub and Bitbucket Cloud. These integrations allow the pipeline to subscribe to webhook events generated by the Git platform when a PR is created or updated, thereby triggering the pipeline run. However, Azure Repos Git operates on a different internal architecture for PR event handling.
Microsoft's documentation for Azure Repos Git clearly states that PR triggers are managed via branch policies. This means that while you can define a pr: block in your YAML, it will not be processed by the Azure Pipelines service to register a PR trigger for an Azure Repos Git repository. The pipeline definition itself does not have the capability to directly listen for or respond to PR events originating from Azure Repos Git in the same way it does for other platforms. Instead, Azure Pipelines relies on the Azure Repos platform to signal when a PR event occurs, and this signal is managed through the branch policy framework.
When you configure a branch policy for build validation on a target branch (e.g., `main` or `master`), you are essentially instructing Azure Repos to queue a specific build pipeline whenever a PR targets that branch. Azure Repos then communicates with Azure Pipelines, passing the necessary context about the PR, which in turn triggers the designated pipeline. This indirection is the key to understanding why the YAML pr: directive is bypassed.
Configuring Build Validation via Branch Policies
To correctly implement PR validation for Azure Repos Git, developers must navigate to the project settings within Azure DevOps. Specifically, they need to access the Repositories section, select the relevant Git repository, and then go to the Branch policies. On the target branch (e.g., `main`), you would add a new policy and select 'Build validation'.
Within the Build validation policy configuration, you specify the build pipeline that should be triggered. You can set requirements for this validation, such as ensuring that the build must succeed before the PR can be completed. You can also configure the display name for the validation, which will appear in the PR details. Crucially, this setup bypasses the need for a pr: block in your YAML file for triggering purposes. The pipeline still needs to be defined in YAML and include the necessary build steps, but its execution for PRs is orchestrated by the branch policy, not by a direct YAML trigger.
One related detail that often surprises users is that draft pull requests do not automatically trigger a pipeline, even when a branch policy is in place. This is by design, as draft PRs are not intended for formal review or merging. To initiate the build validation, the PR must be published as a standard pull request.
Implications for Developers and CI/CD Workflows
This distinction is critical for maintaining robust CI/CD workflows. Developers working with Azure Repos Git must adopt the branch policy approach for PR validation. Relying solely on the pr: directive in YAML will lead to an incomplete validation process, potentially allowing unverified code to be merged.
The correct workflow involves defining your build steps in a YAML pipeline file (e.g., azure-pipelines.yml). This pipeline should contain the logic for evaluating code quality, running tests, performing security scans, or any other checks you deem necessary for your merge gating strategy. Once this pipeline is defined, you then configure the branch policy in Azure Repos to trigger this specific pipeline for all incoming PRs targeting the protected branch.
This separation of concerns offers a more flexible and robust system. The YAML file focuses purely on the build and evaluation logic, while the branch policy manages the gating and triggering mechanism. This ensures that the integrity of your main branch is maintained by enforcing automated checks before any code can be integrated.
What nobody has addressed yet is the potential for confusion when teams transition between Git hosting platforms or onboard new developers unfamiliar with Azure Repos' specific PR trigger implementation. Clear documentation and team-wide understanding of this branch policy-centric approach are paramount to avoid missed validation steps.
