Using Path filters in Build definition in Azure DevOps / VSTS

Sometimes it happens that for the organization and maintenance purpose, you would like to keep all code related to one component of a product in one place only. Now that component may be complex component having multiple sub parts like API, UI, Database etc. Again, for the purpose of easy maintenance, you would like it all under one repository, which is not an bad idea. Now, imagine if you have different builds configured for different sub-components which are using this source code as their base and are configured to trigger on some event, say commit. Then for each small and big commit, it will trigger build in each of the configured builds. Ideally, if the change was related to only one sub-component say API, then you would need to trigger only API specific build and not the ones for the UI and/or Database. 

What are Path filters

In Azure DevOps (formerly known as VSTS, a ALM tool from Microsoft)  server, we can achieve above goal using what is known as Path filters.  Path filters allow the build definition creator the convenience to decide whether to trigger a build based on paths of modified files in any given commit. Consequently, if the path does not match a specific path, it also prevents the build from trigger.

Define Path filters

In Azure DevOps build definition, Path filters are specified as part of a continuous integration trigger. By default, there are no path filters explicitly configured, however there is an implicit include of all files in the repository.

For the purpose of demo, we have created a git repo named teraVis. It contains code for both the ASP.NET core and associated SQL Schema:

source code repo for teraVis

Also we have created two separated build definitions for this repo. One is named as teraVis-App-CI (for .NET core code) and other is teraVis-Db-CI (for Sql Schema code):

build definitions for the teraVis repo

Both builds are set to trigger continuously on the master branch on the default path i.e. /.

Define Inclusion Paths

Inclusion Paths are defined as path which should be included in the change for build to be triggered.

Configuring builds to start from their path only, we need to go to the respective build definition and define the inclusion path. For example, in the teraVis-Db-CI build definition, we need to specify path as below:

Specifying inclusion path in the build definition

Similarly, with the teraVis-App-CI build definition:

Specifying inclusion path in the build definition - 2

Do note that when entering a path you need to provide a leading forward slash (e.g. /teraVis). Backslash notation would not work. Also note that as soon as you specify an explicit path filter (include or exclude) the implicit include of the entire repository no longer applies to the trigger.

You can include as many inclusion Paths you need to include.

Define Exclusion Paths

Exclusion Paths are defined as path which should not be included in the change for build to be triggered. This can be useful to defining paths exclusions like /docs.

Defining a exclusion path is a little tricky than the inclusion paths because as soon as you specify an explicit path filter (include or exclude) the implicit include of the entire repository no longer applies to the trigger. So let’s say we go to teraVis-App-CI and define path exclusion as /docs and no other inclusion paths. In this case, if one makes any commit to repo, it would not trigger build because the default path i.e. /, is removed. Therefore, this build has no path to include.

To properly specify an exclusion path, we need to also define an inclusion path. It may be something specific like /teraVis (in our case) or just root i.e. /

Define both inclusion and exclusion paths in build definition

Further Rules

The order of the rules are not significant. So if you are defining a trailing include of the root directory, it will not override excludes added higher in the list. However, rules with a more specific path override less specific rules. For example, consider below rules:

Exclude /docs/READMe.md
Exclude /docs
Include /
Include /teraVis-Db

Above rules allow build to be triggered only if the change is in the /teraVis-Db directory and not in the other paths specified.

Path filters are such a useful feature, especially if you have a single repository containing source files for multiple components that build separately, or where you simply want to change files that don’t require a rebuild.

 

12 thoughts on “Using Path filters in Build definition in Azure DevOps / VSTS

  1. Hi Josh.. Thanks for stopping by. Can you try going to your user account in Azure DevOps and then select “Preview Features” and turn the features on. Then refresh and see path filters. If this does not work, there is a possibility that it might not have been rolled out for your organization.

    Like

  2. Thanks for this article! The key information here was the front / on the folder path! I tried using a variable with my folder path, something like jsonpath with /myfolder1/jsonfiles assigned to it and put it into the field as $(jsonpath) but it failed to trigger. I’m guessing for some bizzare reason that variables aren’t supported in this box. I found this which suggests its been requested since 2016!! https://visualstudio.uservoice.com/forums/330519-visual-studio-team-services/suggestions/14131002-allow-variables-in-repository-variables-and-trigg

    Like

  3. It seems the implicit include does exist so long as no other includes are mentioned; for example i only have excludes, yet a project that is in a folder which is not excluded does trigger a build.
    What is the precedence; say if i Exclude “/subfolder/” but include “/subfolder/project/” will a change in “subfolder/project” trigger a build? And a change in “/subfolder/otherproject/” will not?

    Like

  4. It seems the implicit include does exist so long as no other includes are mentioned; for example i only have excludes, yet a project that is in a folder which is not excluded does trigger a build.
    What is the precedence; say if i Exclude “/subfolder/” but include “/subfolder/project/” will a change in “subfolder/project” trigger a build? And a change in “/subfolder/otherproject/” will not?

    Like

  5. Any idea how can i refer path as a variable in my scripts. For example if i want to refer branch name in a variable i will do like this in powershell – $BuildBranch = $ENV:BUILD_SOURCEBRANCHNAME

    Like

      • Hi,
        this is working for me in powershell script:
        $url = “$($env:SYSTEM_TEAMFOUNDATIONCOLLECTIONURI)$env:SYSTEM_TEAMPROJECTID/_apis/distributedtask/variablegroups/1?api-version=5.0-preview.1”
        Write-Host $url

        Like

Leave a comment