Binding Dynamic Build Definitions To GitHub Repos

How to make sure that you maintain flexibility of your builds when working with GitHub repositories.

By Den Delimarsky in Hackery

November 4, 2016

As part of the project that I am working on, I need to make sure that I allow the user to specify what GitHub repository they want to bind to their Visual Studio Team Services build definitions. As part of the project that I am working on, I need to make sure that I allow the user to specify what GitHub repository they want to bind to their Visual Studio Team Services build definitions. I am using the library for that, but no matter what I tried, the repository just did not show up.

VSTS Logo

For the process, I was using a typical BuildHttpClient instance. All seemed smooth, but I always ended up with a failed repository binding in the VSTS UI:

VSTS Dependency Fail

And while I got the red exclamation mark there, I got the correct repository binding in the build definition preview:

Build Definition Preview

So what’s the deal? You’d likely use a code snippet like this:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
BuildDefinition definition = new BuildDefinition();
definition.Name = configCarrier.Id.ToString();
definition.Project = new Microsoft.TeamFoundation.Core.WebApi.TeamProjectReference()
{
    Name = customParameters["project"],
    Id = new Guid(customParameters["projectId"])
};
definition.Repository = new BuildRepository()
{
    Id = $"{configCarrier.Repo.Url}.git",
    Type = "GitHub"
};

definition.Repository.Properties.Add("connectedServiceId", serviceEndpointId);
definition.Repository.Properties.Add("apiUrl", $"https://api.github.com/repos/{repoOwner}/{repoName}");
definition.Repository.Properties.Add("branchesUrl",
    $"https://api.github.com/repos/{repoOwner}/{repoName}/branches");
definition.Repository.Properties.Add("cloneUrl", $"https://github.com/{repoOwner}/{repoName}.git");
definition.Repository.Properties.Add("refsUrl",
    $"https://api.github.com/repos/{repoOwner}/{repoName}/git/refs");

Number one – make sure to add the .git prefix to the repository ID when you are creating a new BuildRepository. But that still won’t be enough. Take a look at the second part of the above code snippet:

1
2
3
4
5
6
7
8
definition.Repository.Properties.Add("gitLfsSupport", "false");
definition.Repository.Properties.Add("fetchDepth","0");

definition.Repository.Name = $"{repoOwner}/{repoName}";
definition.Repository.Url = new Uri($"https://github.com/{repoOwner}/{repoName}.git");
definition.Repository.DefaultBranch = "master";
definition.Repository.Clean = "null";
definition.Repository.CheckoutSubmodules = true;

Notice that you need to specify values for gitLfsSupport and fetchDepth. Without those properties in place the binding will not happen, so be careful!

Once these tweaks were made, I could successfully bind my repository to the definition.

Subscribe to The Den:

A monthly newsletter about technology, machine learning, security, and just tinkering with code.

Feedback

Have any thoughts? Let me know on Twitter!