Branch policies in Azure DevOps repositories are a great way to enforce the team’s code quality. With right branch policies you can ensure all the developer commits meet the required conditions. However, as you add more repositories managing or revisiting these policies becomes a pain especially because you need to view repo by repo. In this post we will see how we can use Azure DevOps extension for Azure CLI to quickly view all the policies applied to the repo via command line and also see ways to create/update existing repos.

Installing Azure DevOps extension for Azure CLI

I am assuming you already have Azure CLI installed on your machine. If you have not installed it already, please do it by following steps mentioned here

Now to install azure devops extension for the CLI, run the following command

az extension add --name azure-devops

You can also see installed extensions using following command. You should see Azure DevOps extension installed.

az extension list
List installed extensions

Login to Azure

Now that you have extension installed, it is time to login. Login using the below command.

az login

You should see details of all the subscriptions you have access to.

Set defaults for Azure DevOps CLI

Azure DevOps extension supports setting defaults. You do that using following command

az devops configure -d organization=https://dev.azure.com/myorg project=contoso

You can see configured defaults using az devops configure -l command

List defaults

For full list of commands supported by Azure DevOps extension, refer the documentation

Check branch policies applied to the repository

The first step we need is the repository for which we would like to check branch policies for. We get the list of repositories (specifically repository id) using az repos list --output table command.

The argument --output table outputs the result in table format

List repositories

Looking for a specific repository

If you are looking for a specific repository you could use query argument using JMESPATH expression as below

az repos list --query "[?name=='Infrastructure'].{Id:id,Name:name,DefaultBranch:defaultBranch}"

The output will look as below

Search a repository with name

Listing the branch policies

To list all the branch policies you can use az repos policy list -o json command, which will dump a big json as below

[
  {
    "createdBy": {
      "_links": {
        "avatar": {
          "href": "https://myorg.visualstudio.com/_apis/GraphProfile/MemberAvatars/aad.xxxxxxxx"
        }
      },
      "descriptor": "aad.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
      "directoryAlias": null,
      "displayName": "John Smith",
      "id": "xxxxxxxxxx-xxxxxx-6a2b-b93c-xxxxxxxxx",
      "imageUrl": "https://myorg.visualstudio.com/_api/_common/identityImage?id=xxxxxxx-xxxxxx-6a2b-b93c-xxxxxxxxxxxx",
      "inactive": null,
      "isAadIdentity": null,
      "isContainer": null,
      "profileUrl": null,
      "uniqueName": "[email protected]",
      "url": "https://spsprodweu3.vssps.visualstudio.com/xxxxxxxx-2176-4a35-945d-de4eaf30bd01/_apis/Identities/xxxxxxxx-xxxx-6a2b-b93c-xxxxxxxxxx"
    },
    "createdDate": "2018-06-13T07:47:53.336927+00:00",
    "id": 1,
    "isBlocking": true,
    "isDeleted": false,
    "isEnabled": true,
    "revision": 1,
    "settings": {
      "requiredReviewerIds": [
        "xxxxxx-xxxxxx-xxxxxxxxx-xxxxxxxxxxxxx",
        "xxxxxx-xxxxxx-xxxxxxxxx-xxxxxxxxxxxxx"
      ],
      "scope": [
        {
          "matchKind": "Exact",
          "refName": "refs/heads/develop",
          "repositoryId": "xxxxxx-xxxxxx-xxxxxxxxx-xxxxxxxxxxxxx"
        }
      ]
    },
    "type": {
      "displayName": "Required reviewers",
      "id": "xxxxxx-xxxxxx-xxxxxxxxx-xxxxxxxxxxxxx",
      "url": "https://myorg.visualstudio.com/xxxxxx-xxxxxx-xxxxxxxxx-xxxxxxxxxxxxx/_apis/policy/types/xxxxxx-xxxxxx-xxxxxxxxx-xxxxxxxxxxxxx"
    },
    "url": "https://myorg.visualstudio.com/xxxxxx-xxxxxx-xxxxxxxxx-xxxxxxxxxxxxx/_apis/policy/configurations/1"
  }
  ....
]

This lists all the policies in the project. But as you can see, it is hard to read through this big json. We are however interested in seeing policy only for a particular repository. From the JSON we can see that the repositoryId is present under scope element (line #36).

We can now query all the branch policies for the given repository by passing the repository id as below.

az repos policy list -o table --query "[?settings.scope[0].repositoryId=='xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx']"

This outputs the value in the following format

List azure repos policies

As you can see this output does not list the name of the policy.

Getting the branch policy name

From the JSON above, we can see that name of the policy is under type element (line #41)

We can update our command as below to get the required fields from JSON and output as table.

az repos policy list -o table --query "[?settings.scope[0].repositoryId=='xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx'].{PolicyId:id,PolicyType:type.displayName,Mandatory:isBlocking,Enabled:isEnabled,CreatedBy:createdBy.displayName}"

The output is much cleaner and we see output as below

Show the required columns

I can now change any git repository’s id in the command and see all the policies for that repository.

Simplifying our command using Alias extension

The above command is way too long to remember and to type to see the branch policies. Wouldn’t it be nice if we could have a shorter command? May be it is easier to use command az repo-polices 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx', where xxxx... is the repository ID.

We can make our command shorter and exactly as we want using alias Azure CLI extension. You can install this extension using steps mentioned in the documentation.

Create an alias

Once you have the alias extension installed, you can create alias for our command as below

az alias create --name "repo-policies {{ repoid }}" --command "repos policy list -o table --query [?settings.scope[0].repositoryId=='{{ repoid }}'].{PolicyId:id,PolicyType:type.displayName,Mandatory:isBlocking,Enabled:isEnabled,CreatedBy:createdBy.displayName}"

Notice our alias command takes argument repository id, which we are setting as {{ repoid }}

If the creating alias is successful you should see output as below

Create alias for the command

Using the new shorter command to get branch policies of the repository

With alias set, we will be able to use our alias as below

az repo-policies 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx'
Running the alias command

We can now pass any repository id to our command to see the branch policies. Cool right?

BTW, if you ever forget the alias you set, you can view all the aliases by using az alias list

List the alias

Below section was updated on 4th Apr

Displaying the branch name in the table

The above command will work fine when the repository has only one branch as you get one version of each policy type. Say if you repository has develop and master branches, and both the branches have policies applied, these will appear twice and it will be confusing. We will try to modify the command such that we also display the branch name.

From the json above we see that branch name is under scope array and is value for key refName. We will get that by adding additional property branch:settings.scope[].refName. The complete command is as below

az repos policy list -o table --query "[?settings.scope[?repositoryId=='xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx']].{policyId:id,policyType:type.displayName,branch:settings.scope[].refName,mandatory:isBlocking,enabled:isEnabled,createdBy:createdBy.displayName}"

But when we run this command, the output does not display any branch information. Let us change the output format to json (using -o json) and check the output again.

[
  {
    "branch": [
      "refs/heads/master"
    ],
    "createdBy": "Utkarsh Shigihalli",
    "enabled": true,
    "mandatory": true,
    "policyId": 132,
    "policyType": "Work item linking"
  },
  {
    "branch": [
      "refs/heads/master"
    ],
    "createdBy": "Utkarsh Shigihalli",
    "enabled": true,
    "mandatory": true,
    "policyId": 133,
    "policyType": "Require a merge strategy"
  }
]

As you can see the branch details is under array now and we need bit more work to show it in the table.

To get the branch information we could again use [] and then re-apply the expression as below

az repos policy list -o json --query "[?settings.scope[?repositoryId=='xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxxxxx']].{policyTypeId:type.id,policy:type.displayName,branch:settings.scope[].refName,isMandatory:isBlocking,isEnabled:isEnabled,createdBy:createdBy.displayName,createdDate:createdDate}[].{Branch:branch[0],Policy:policy,Mandatory:isMandatory,Enabled:isEnabled,CreatedBy:createdBy,CreatedDate:createdDate}"

This will output the json as below now

[
  {
    "Branch": "refs/heads/develop",
    "CreatedBy": "Utkarsh Shigihalli",
    "CreatedDate": "2018-12-12T12:26:06.900042+00:00",
    "Enabled": true,
    "Mandatory": true,
    "Policy": "Build"
  },
  {
    "Branch": "refs/heads/master",
    "CreatedBy": "Utkarsh Shigihalli",
    "CreatedDate": "2018-12-12T12:26:40.087316+00:00",
    "Enabled": true,
    "Mandatory": true,
    "Policy": "Build"
  }
]

Now you can see the branch information as well. Only thing remaining now is to turn this in to a table information, we can do that using -o table argument and we see nice output as below

Show branch information

Conclusion

In this post we saw how we can view the branch policies for selected repository. In my future post we will see how we can create/update branch policies using Azure CLI.

If you are a command line person and use Azure DevOps regularly, azure-devops extension for Azure CLI is a great extension to get the information you need quickly.


About author
Utkarsh Shigihalli
Utkarsh Shigihalli
Utkarsh is passionate about software development and has experience in the areas of Azure, Azure DevOps, C# and TypeScript. Over the years he has worked as an architect, independent consultant and manager in many countries including India, United States, Netherlands and United Kingdom. He is a Microsoft MVP and has developed numerous extensions for Visual Studio, Visual Studio Code and Azure DevOps.
We Are
  • onlyutkarsh
    Utkarsh Shigihalli
    Microsoft MVP, Technologist & DevOps Coach


  • arora_tarun
    Tarun Arora
    Microsoft MVP, Author & DevOps Coach at Avanade

Do you like our posts? Subscribe to our newsletter!
Our Book