Build Azure Repos Git or TFS Git repositories
TFS 2018
Note
Microsoft Visual Studio Team Foundation Server 2018 and earlier versions have the following differences in naming:
- Pipelines for build and release are called definitions
- Runs are called builds
- Service connections are called service endpoints
- Stages are called environments
- Jobs are called phases
Azure Pipelines can automatically build and validate every pull request and commit to your Azure Repos Git repository.
Choose a repository to build
Azure Pipelines must be granted access to your repositories to trigger their builds and fetch their code during builds. Normally, a pipeline has access to repositories in the same project. But, if you wish to access repositories in a different project, then you need to update the permissions granted to job access tokens.
CI triggers
Continuous integration (CI) triggers cause a pipeline to run whenever you push an update to the specified branches or you push specified tags.
- Paths are always specified relative to the root of the repository.
- If you don't set path filters, then the root folder of the repo is implicitly included by default.
- If you exclude a path, you cannot also include it unless you qualify it to a deeper folder. For example if you exclude /tools then you could include /tools/trigger-runs-on-these
- The order of path filters doesn't matter.
- Paths in Git are case-sensitive. Be sure to use the same case as the real folders.
- You cannot use variables in paths, as variables are evaluated at runtime (after the trigger has fired).
YAML pipelines aren't available in TFS.
Skipping CI for individual pushes
You can also tell Azure Pipelines to skip running a pipeline that a push would normally trigger. Just include ***NO_CI***
in the message of any of the commits that are part of a push, and Azure Pipelines will skip running CI for this push.
Using the trigger type in conditions
It is a common scenario to run different steps, jobs, or stages in your pipeline depending on the type of trigger that started the run. You can do this using the system variable Build.Reason
. For example, add the following condition to your step, job, or stage to exclude it from PR validations.
condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest'))
Behavior of triggers when new branches are created
It is common to configure multiple pipelines for the same repository. For instance, you may have one pipeline to build the docs for your app and another to build the source code. You may configure CI triggers with appropriate branch filters and path filters in each of these pipelines. For instance, you may want one pipeline to trigger when you push an update to the docs
folder, and another one to trigger when you push an update to your application code. In these cases, you need to understand how the pipelines are triggered when a new branch is created.
Here is the behavior when you push a new branch (that matches the branch filters) to your repository:
- If your pipeline has path filters, it will be triggered only if the new branch has changes to files that match that path filter.
- If your pipeline does not have path filters, it will be triggered even if there are no changes in the new branch.
Wildcards
When specifying a branch, tag, or path, you may use an exact name or a wildcard.
Wildcards patterns allow *
to match zero or more characters and ?
to match a single character.
- If you start your pattern with
*
in a YAML pipeline, you must wrap the pattern in quotes, like"*-releases"
. - For branches and tags:
- A wildcard may appear anywhere in the pattern.
- For paths:
- In Azure DevOps Server 2022 and higher, including Azure DevOps Services, a wildcard may appear anywhere within a path pattern and you may use
*
or?
. - In Azure DevOps Server 2020 and lower, you may include
*
as the final character, but it doesn't do anything differently from specifying the directory name by itself. You may not include*
in the middle of a path filter, and you may not use?
.
- In Azure DevOps Server 2022 and higher, including Azure DevOps Services, a wildcard may appear anywhere within a path pattern and you may use
trigger:
branches:
include:
- main
- releases/*
- feature/*
exclude:
- releases/old*
- feature/*-working
paths:
include:
- docs/*.md
PR triggers
Pull request (PR) triggers cause a pipeline to run whenever you open a pull request, or when you push changes to it. In Azure Repos Git, this functionality is implemented using branch policies. To enable PR validation, navigate to the branch policies for the desired branch, and configure the Build validation policy for that branch. For more information, see Configure branch policies.
If you have an open PR and you push changes to its source branch, multiple pipelines may run:
- The pipelines specified by the target branch's build validation policy will run on the merge commit (the merged code between the source and target branches of the pull request), regardless if there exist pushed commits whose messages or descriptions contain
[skip ci]
(or any of its variants). - The pipelines triggered by changes to the PR's source branch, if there are no pushed commits whose messages or descriptions contain
[skip ci]
(or any of its variants). If at least one pushed commit contains[skip ci]
, the pipelines will not run.
Finally, after you merge the PR, Azure Pipelines will run the CI pipelines triggered by pushes to the target branch, even if some of the merged commits' messages or descriptions contain [skip ci]
(or any of its variants).
Note
To configure validation builds for an Azure Repos Git repository, you must be a project administrator of its project.
Note
Draft pull requests do not trigger a pipeline even if you configure a branch policy.
FAQ
Problems related to Azure Repos integration fall into three categories:
- Failing triggers: My pipeline is not being triggered when I push an update to the repo.
- Failing checkout: My pipeline is being triggered, but it fails in the checkout step.
- Wrong version: My pipeline runs, but it is using an unexpected version of the source/YAML.
Failing triggers
I just created a new YAML pipeline with CI/PR triggers, but the pipeline isn't being triggered.
Follow each of these steps to troubleshoot your failing triggers:
Are your YAML CI or PR triggers overridden by pipeline settings in the UI? While editing your pipeline, choose ... and then Triggers.
Check the Override the YAML trigger from here setting for the types of trigger (Continuous integration or Pull request validation) available for your repo.
- Are you configuring the PR trigger in the YAML file or in branch policies for the repo? For an Azure Repos Git repo, you cannot configure a PR trigger in the YAML file. You need to use branch policies.
Is your pipeline paused or disabled? Open the editor for the pipeline, and then select Settings to check. If your pipeline is paused or disabled, then triggers do not work.
Have you updated the YAML file in the correct branch? If you push an update to a branch, then the YAML file in that same branch governs the CI behavior. If you push an update to a source branch, then the YAML file resulting from merging the source branch with the target branch governs the PR behavior. Make sure that the YAML file in the correct branch has the necessary CI or PR configuration.
Have you configured the trigger correctly? When you define a YAML trigger, you can specify both include and exclude clauses for branches, tags, and paths. Ensure that the include clause matches the details of your commit and that the exclude clause doesn't exclude them. Check the syntax for the triggers and make sure that it is accurate.
Have you used variables in defining the trigger or the paths? That is not supported.
Did you use templates for your YAML file? If so, make sure that your triggers are defined in the main YAML file. Triggers defined inside template files are not supported.
Have you excluded the branches or paths to which you pushed your changes? Test by pushing a change to an included path in an included branch. Note that paths in triggers are case-sensitive. Make sure that you use the same case as those of real folders when specifying the paths in triggers.
Did you just push a new branch? If so, the new branch may not start a new run. See the section "Behavior of triggers when new branches are created".
My CI or PR triggers have been working fine. But, they stopped working now.
First go through the troubleshooting steps in the previous question. Then, follow these additional steps:
Do you have merge conflicts in your PR? For a PR that did not trigger a pipeline, open it and check whether it has a merge conflict. Resolve the merge conflict.
Are you experiencing a delay in the processing of push or PR events? You can usually verify this by seeing if the issue is specific to a single pipeline or is common to all pipelines or repos in your project. If a push or a PR update to any of the repos exhibits this symptom, we might be experiencing delays in processing the update events. Check if we are experiencing a service outage on our status page. If the status page shows an issue, then our team must have already started working on it. Check the page frequently for updates on the issue.
I do not want users to override the list of branches for triggers when they update the YAML file. How can I do this?
Users with permissions to contribute code can update the YAML file and include/exclude additional branches. As a result, users can include their own feature or user branch in their YAML file and push that update to a feature or user branch. This may cause the pipeline to be triggered for all updates to that branch. If you want to prevent this behavior, then you can:
- Edit the pipeline in the Azure Pipelines UI.
- Navigate to the Triggers menu.
- Select Override the YAML continuous Integration trigger from here.
- Specify the branches to include or exclude for the trigger.
When you follow these steps, any CI triggers specified in the YAML file are ignored.
I have multiple repositories in my YAML pipeline. How do I set up triggers for each repository?
See triggers in Using multiple repositories.
Failing checkout
I see the following error in the log file during checkout step. How do I fix it?
remote: TF401019: The Git repository with name or identifier XYZ does not exist or you do not have permissions for the operation you are attempting.
fatal: repository 'XYZ' not found
##[error] Git fetch failed with exit code: 128
Follow each of these steps to troubleshoot your failing checkout:
Does the repository still exist? First, make sure it does by opening it in the Repos page.
Are you accessing the repository using a script? If so, check the Limit job authorization scope to referenced Azure DevOps repositories setting. When Limit job authorization scope to referenced Azure DevOps repositories is enabled, you won't be able to check out Azure Repos Git repositories using a script unless they are explicitly referenced first in the pipeline.
What is the job authorization scope of the pipeline?
If the scope is collection:
- This may be an intermittent error. Re-run the pipeline.
- Someone may have removed the access to Project Collection Build Service account.
- Go to Project settings for the project in which the repository exists. Select Repos > Repositories > specific repository, and then Security.
- Check if Project Collection Build Service (your-collection-name) exists in the list of users.
- Check if that account has Create tag and Read access.
If the scope is project:
- Is the repo in the same project as the pipeline?
- Yes:
- This may be an intermittent error. Re-run the pipeline.
- Someone may have removed the access to Project Build Service account.
- Go to Project settings for the project in which the repository exists. Select Repos > Repositories > specific repository, and then Security.
- Check if your-project-name Build Service (your-collection-name) exists in the list of users.
- Check if that account has Create tag and Read access.
- No:
- Is your pipeline in a public project?
- Yes: You cannot access resources outside of your public project. Make the project private.
- No: You need to configure permissions to access another repo in the same project collection.
- Is your pipeline in a public project?
- Yes:
- Is the repo in the same project as the pipeline?
Wrong version
A wrong version of the YAML file is being used in the pipeline. Why is that?
- For CI triggers, the YAML file that is in the branch you are pushing is evaluated to see if a CI build should be run.
- For PR triggers, the YAML file resulting from merging the source and target branches of the PR is evaluated to see if a PR build should be run.