VSTS using multiple build definitions for branch policy

Introduction

Branch policies are a great feature in VSTS to safeguard the quality of your repositories. You can enforce a pull request to be reviewed and approved by a set number of reviewers. The merge can only take place when all policies are complying. The policy we are interested in for this how-to is the build definition policy.

Our libraries are cross-platform. To build the whole solution we have two different machines. A NUC that builds the UWP and Android projects and their Xamarin Forms counterparts and a Mac which builds the iOS projects and their Xamarin Forms iOS counterparts.

To be able to build all projects as part of the Pull Request flow we need two separate definitions, because there is no single build host that support both iOS and the other platforms.

And there we have our pitfall, the VSTS interface only supports selecting a single build definition. This how-to shows you how to get multiple definitions working for a Pull Request.

Visual Studio Team Service - Branch policies

VSTS has many options to guard the quality of your branches. This how-to is based on information from the official documentation, which can be found here.

Configure

Configure

When your account has the appropriate rights, you will have the ability to administer the project and setup branch policies. Using the gear icon (1) you can select Version Control (2) to set security settings and other options for your repositories and branches within the repositories. We selected our master branch (3) and then clicked branch policies (4) then we checked Automatically build pull request (5) and selected our build definition (6).

This is the default way to setup builds for a Pull Request and as you can see it limits you to a single definition. But no despair VSTS is capable of more than it shows from its UI. To setup multiple definitions we will use the API.

VSTS API

VSTS has an api which you can use to query information and to administer your VSTS environment. We will focus on the branch policies. The official documentation can be found here.

Getting your token

The important first step is to create and convert the token. To get your Personal Access Token (PAT) follow these steps to create the access token. This token cannot directly be set as the Authorization: Basic BASE64PATSTRING. You will need to add your user name and then convert it to a Base64 encoded string. There are multiple online tools to encode string, but because this contains security sensitive information we strongly recommend to use the shell.

Powershell Script for Base64 encoding

Converting the PAT to the BASE64PATSTRING as needed for the authorization header can be quite easily done with Powershell.

$text = "<username>:<token>"
$bytes = [System.Text.Encoding]::Ascii.GetBytes($text)
$encoded = [Convert]::ToBase64String($bytes)
$encoded

Make sure to replace <username> and <token> with your own username, ours included our domain, and the token gathered in the previous section. After executing the code the shell will display your BASE64PATSTRING.

Using the API to set multiple build definitions

Now we have all the ingredients needed we can start calling the API. You can use any API tool you like, but we will be using Postman in this how-to. The official documentation for the policy call can be found here.

Postman

Postman popular tool which you can get here. It provides an easy way to perform HTTP requests. Beneficial features are the saving and replaying of requests.

The policy call - GET

To get a general idea of how the data is structured in the VSTS API we will first get the list of policies. This also gives us a change to properly setup Postman first without making any unwanted modifications already.

The picture below shows how the headers should be set and at what endpoint url the policies can be found.

Postman

Replace the {account} in the url with your own VSTS account name and replace <BASE64PATSTRING> with your own string. When pressing the Send button it will execute the request and the response will look similar to this:

Postman

If you have configured a build definition as a branch policy, you will see it appear in the response. In our response this is displayed in the lines between 87 and 128, some information is collapsed because it is less relevant. The important properties are buildDefinitionId and the scope > refName and the repositoryId. We will use these in our post request to add more build definitions.

The policy call - POST

The POST call is used to add new policies. This can be any type, see policy types, but we are currently only interested in the build definition type.

Build definition id

To add a new build definition we need its id. The id can be retrieved from the url. When you navigate to your build definition it will be part of the url. E.g.:

https://{account}.visualstudio.com/Libraries/_build/index?context=Mine&path=%5C&definitionId=42&_a=completed

Here you can see the definition we navigated to has id 42.

The body

We can use the same endpoint but we should change the method type to POST and add a body. The documentation lets us know that it should be in this format:

{
   "isEnabled": {bool},
   "isBlocking": {bool},
   "type": {
      "id": {guid}
   },
   "settings": {object}
}

With this information we can created our own body to add build defintion with id 42.

body

When the Send button is pressed, this will add the definition to the API and you will get a Status: 200 ok when the execution was successful.

Result

If everything has been setup successfully you will notice that it is no longer possible to manage the branch policies regarding the automatic builds, it is now grayed out.

grayed out

And more important, when a new Pull Request is created you will see that it will start building multiple definitions. And the result is a beautiful Pull Request overview screen.

result

Comments