Using Azure DevOps Branch Policy To Restrict PR Source Branch

1 minute read

Today I had a requirement to protect a Git branch in an Azure DevOps repo that only allow merging from a specific source branch. i.e. An archive branch must only be updated from the default main branch.

When I looked into the Branch Policies in Azure DevOps, it doesn’t look like there is a native way to achieve this. So I created a simple build validation pipeline that checks the PR source branch and configured it to be triggered automatically in the Branch Policies for the branch that I want to protect.

01

The pipeline uses a reusable YAML pipeline template so it’s easy to create such pipelines for multiple branches if required.

Pipeline Template

#template-branch-policy-validation.yml
parameters:
- name: agentPoolName
  displayName: "Agent Pool Name"
  type: string
  default: "windows-latest"
- name: allowedSourceBranchName
  displayName: Allowed Source branch name
  type: string
  default: "refs/heads/main"

stages:
- stage: branch_policy_build_validation
  displayName: "Branch Policy Build Validation"
  jobs:
  - job: source_branch_validation
    displayName: Source Branch Validation
    pool:
      vmImage: "$"
    steps:
      - pwsh: |
          if ('$(System.PullRequest.SourceBranch)' -ieq '$' -or '$(System.PullRequest.SourceBranch)' -ieq 'refs/heads/$') {
            Write-Host "Source branch '$(System.PullRequest.SourceBranch)' is allowed"
          } else {
            Throw "Source branch '$(System.PullRequest.SourceBranch)' is not allowed. Only the '$' branch is allowed."
            exit 1
          }
        displayName: "Check Build Source Branch"
        errorActionPreference: Stop
      

Build Validation Pipeline

NOTE: In this example, the YAML pipeline template folder is placed in the templates/ sub-folder of where the YAML pipeline is located.

#azure-pipelines-archive-branch-build-validation.yml
name: $(BuildDefinitionName)_$(SourceBranchName)_$(Date:yyyyMMdd)$(Rev:.r)
trigger: none

stages:
  - template: templates/template-branch-policy-validation.yml
    parameters:
      allowedSourceBranchName: "main"

Once this is setup, I can only merge into this archive branch from main branch:

02 03

If I create a PR from a branch other than main, the validation will fail and I am not able to complete the PR and merge the code:

04 05

The YAML pipeline and pipeline template can also be found from my BlogPost GitHub repo HERE.

Leave a comment