Sync TeamCity build configurations with Git branches
using System; | |
using System.Collections.Generic; | |
using System.Collections.Specialized; | |
using System.Net; | |
using System.Text; | |
using System.Xml.Linq; | |
using System.Xml.XPath; | |
using LibGit2Sharp; | |
namespace TCBuildConfigSync | |
{ | |
/// <summary> | |
/// Syncs TeamCity build configurations with Git branches. | |
/// | |
/// Uses libgit2sharp to read the list of branches from Git, the TeamCity REST API and HTTP POSTs to the TeamCity dashboard URLs. | |
/// | |
/// libgit2sharp: https://github.com/libgit2/libgit2sharp | |
/// </summary> | |
class Program | |
{ | |
private const string TeamCityUrl = "http://bob/httpAuth"; | |
static void Main(string[] args) | |
{ | |
using (var repo = new Repository(args[0])) | |
{ | |
// Collect all the TeamCity build configurations | |
Dictionary<string, string> tcBranches = new Dictionary<string, string>(); // Name to Id map | |
List<string> tcBranchesToDelete = new List<string>(); | |
using (WebClient webClient = GetWebClient()) | |
{ | |
XDocument doc = XDocument.Parse(webClient.DownloadString(TeamCityUrl + "/app/rest/projects/id:project9")); | |
foreach (XElement buildTypeEl in doc.Root.XPathSelectElements("buildTypes/buildType")) | |
{ | |
string id = buildTypeEl.Attribute("id").Value; | |
string name = buildTypeEl.Attribute("name").Value; | |
tcBranches.Add(name, id); | |
tcBranchesToDelete.Add(name); | |
} | |
} | |
// Collect all the branches in this repo | |
foreach (Branch branch in repo.Branches) | |
{ | |
// Only look at remote branches | |
if (!branch.IsRemote) continue; | |
// Only look at private branches | |
if (!branch.Name.StartsWith("origin/private/")) continue; | |
string gitBranchName = branch.Name.Substring("origin/".Length); | |
string tcConfigName = branch.Name.Substring("origin/private/".Length).Replace('/', '-'); | |
if (!tcBranches.ContainsKey(tcConfigName)) | |
{ | |
Console.ForegroundColor = ConsoleColor.Yellow; | |
Console.WriteLine("+" + tcConfigName); | |
Console.ResetColor(); | |
// Create a new configuration for this branch | |
using (WebClient webClient = GetWebClient()) | |
{ | |
NameValueCollection parameters = new NameValueCollection(); | |
parameters.Add("buildTypeName", tcConfigName); | |
parameters.Add("createFromTemplate", "Create"); | |
parameters.Add("templateId", "btTemplate6"); | |
parameters.Add("param:BRANCH_NAME", gitBranchName); | |
byte[] responseArray = webClient.UploadValues(TeamCityUrl + "/admin/action.html", "POST", parameters); | |
string response = Encoding.ASCII.GetString(responseArray); | |
Console.WriteLine(" ->" + response); | |
} | |
} | |
else | |
{ | |
Console.ForegroundColor = ConsoleColor.Green; | |
Console.WriteLine(" " + tcConfigName); | |
Console.ResetColor(); | |
// Remove branch from deletion list, there is a matching Git branch | |
tcBranchesToDelete.Remove(tcConfigName); | |
} | |
} | |
// Delete build configurations without Git branches | |
foreach (string tcConfigName in tcBranchesToDelete) | |
{ | |
Console.ForegroundColor = ConsoleColor.Red; | |
Console.WriteLine("-" + tcConfigName); | |
Console.ResetColor(); | |
// Delete this dead configuration | |
using (WebClient webClient = GetWebClient()) | |
{ | |
NameValueCollection parameters = new NameValueCollection(); | |
parameters.Add("buildTypeId", tcBranches[tcConfigName]); | |
parameters.Add("removeBuildType", "1"); | |
byte[] responseArray = webClient.UploadValues(TeamCityUrl + "/admin/action.html", "POST", parameters); | |
string response = Encoding.ASCII.GetString(responseArray); | |
Console.WriteLine(" -> " + response); | |
} | |
} | |
} | |
} | |
private static WebClient GetWebClient() | |
{ | |
WebClient webClient = new WebClient(); | |
webClient.Credentials = new NetworkCredential("user", "password"); | |
return webClient; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment