Wednesday 22 May 2019

Controlling Pull Request Source Branches for Given Target Branch in Azure Git Repos

Generally you can create pull request from any given source branch to a any given target branch in Azure Git repos. You can setup a pull request validation build which evaluates the repo state, by performing a pre merge in the build server to ensure, your repo build succeeds after the pull request is merged to the target branch. You can set the branch policies so that the pull request cannot be merged to a given target branch if the validation build fails or if the approvers not approve the pull request. However, you might want to follow a branching strategy, which requires you to control from which branches a pull request can be created and merged to a targeting branch. The purpose of controlling the pull request source and target would be to assure your team is adhering to a defined branching and merge strategy. Let’s look at using a task in pull request validation build to ensure the request is coming from an allowed/valid branch, and make the build to fail if it is coming from an invalid branch.

Let’s take an example branching strategy shown below and assume only pull requests (PR) should be done following the rules specified below.

  • Any feature branch can only create a PR targeting dev branch.
  • Any branch can be merged with a PR coming from a hotfix branch.
  • qa branch can be merged with a PR coming from dev branch or any hot fix branch only.
  • master branch can be merged with a PR coming from qa branch or any hot fix branch or any release branch only.
  • Any release branch can be merged with a PR from any hotfix branch.

Let’s implement PR source branch validation mechanism for each target branch, using pull request validation build which is used in the target branch policies.
For the above conditions we can define branch validate pattern as a PowerShell hashtable as shown below.
@{"dev" = "feature/*;hotfix/*" ; "qa" = "dev;hotfix/*" ; "master" = "qa;hotfix/*;release/*" ; "release/*" = "hotfix/*"}
Each hash table entry has target branch defined to the left of the = mark and the right side of = mark contains the possible branch pattern,each source branch separated by a semicolon. For Example, "dev" = "feature/*;hotfix/*"  defines feature/*;hotfix/* (any feature or any hotfix) branch as source for dev branch.
You can use the PowerShell script made available here in a PowerShell task and create a task group so that it can be used in any PR validation build. Let’s understand the actions performed in the script.
The script is performing steps described below.
Read pull request source and target branch details from the build variables and print them in build log. Read the branch control pattern variable content as hashtabe.

Strip the refs/heads portion of source and target branch of the PR and create source and target branch fitters.

Set /* for if required to the source and the target branch filters. For example, feature/somefeature  is made feature/*. Print the branch filters in build log.

Retrieve the possible source branch patterns for the target branch of the PR, from the branch control patterns and print the possible source branch pattern in the build log.

Output error and fail the build if the possible source branch pattern not found for the target branch of the PR. If possible source branch pattern contains the current source branch of the PR allow build to proceed as it is a valid PR, considering source and target branches. If the source branch is not available in possible branch patterns fail the build preventing the PR from merge to target branch.

In a build definition the above described script can be added as a task (you can create a task group and use it in multiple build definitions). make sure to add below custom control condition so that this step is only get executed in pull request validations.
and(succeeded(), eq(variables['Build.Reason'], 'PullRequest'))

Add a variable to the build definition or use via a variable group a variable named BranchControlPattern with the desired pattern hastable.

Set the build definition as a pull request validation build for each of the branches using branch policy settings.

Once you make a pull request to a branch from a invalid source the validation step will prevent the build from passing blocking the pull request from merging. For example, an attempt of a pull request from a feature branch to qa is blocked as below.

A pull request from a feature branch to dev branch is allowed to be merged as it is adhering to branch pattern.

No comments:

Popular Posts