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:
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):
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:
Similarly, with the teraVis-App-CI build definition:
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. /
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:
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.