Defining Export / Import from / to JSon File (TFS 2013)
I am trying to export and import build definitions from tfs2013 following this link and this , but none of them work for me. I know there are some tfs plugins that do this, but I cannot use them due to company policy restrictions.
The GetDefinitionAsync and GetFullDefinitionsAsync methods are fine, but they don't retrieve the ProcessParameters property, so I can't export the complete assembly definition that includes this important information. I tried to get this property calling IBuildServer.QueryBuildDefinitions, but when I try to create a new assembly definition I can't because the datatype is Microsoft.TeamFoundation.Build.Client.IBuildDefinition and I can't create a new instance of Microsoft.TeamFoundation .Build.Client.BuildDefinition because of this private class. how can I copy ProcessParameters and other information to import the complete assembly definition?
thank
source to share
Ok finally after deep research I found a way to export / import
Export to JSon:
public static void ExportBuildDef(Microsoft.TeamFoundation.Build.Client.IBuildDefinition buildDefinition, string project, string filePath)
{
Console.WriteLine($"Exporting build definition '{buildDefinition.Name}' from '{project}' project.");
var json = JsonConvert.SerializeObject(
buildDefinition,
Newtonsoft.Json.Formatting.Indented,
new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore });
json = removePasswords(json);
File.WriteAllText(filePath, json);
Console.WriteLine($"Build definition '{buildDefinition.Name}' succesfully exported to '{filePath}'.");
}
private static string removePasswords(string json)
{
string res = json;
var searchFor = "\"Password\":";
var startIndex = json.IndexOf(searchFor);
if (startIndex >= 0)
{
var endIndex = json.IndexOf(",", startIndex);
var pwd = json.Substring(startIndex, endIndex - startIndex);
if (pwd.IndexOf(":") > 0)
{
pwd = json.Substring(startIndex, endIndex - startIndex).Split(':')[1].Trim();
res = json.Replace(pwd, "\"{hidden}\"");
}
}
return res;
}
Import from JSon
Note. The BuildDefinitionModel class is a collection of "POCO" classes (does not include the long file) which can be obtained by navigating to the C # classes from the exported JSon file from here
public static void ImportBuildDefinition(IBuildServer buildServer, string projectName, string filePath, string newBuildName, string sourceProvider)
{
if (!File.Exists(filePath))
throw new FileNotFoundException("File does not exist!", filePath);
Console.WriteLine($"Importing build definition from file '{filePath}' to '{projectName}' project.");
var json = File.ReadAllText(filePath);
var buildDef = JsonConvert.DeserializeObject<BuildDefinitionModel>(json);
var newBuildDefinition = CloneBuildDefinition(buildServer, buildDef, newBuildName, projectName, sourceProvider);
Console.WriteLine($"Build definition '{buildDef.Name}' succesfully imported to '{projectName}' project.");
}
static IBuildDefinition CloneBuildDefinition(IBuildServer buildServer, BuildDefinitionModel buildDefinitionSource, string newBuildName, string projectName, string sourceProvider)
{
var buildDefinitionClone = buildServer.CreateBuildDefinition(projectName);
buildDefinitionClone.BuildController = GetBuildController(buildServer, "");
buildDefinitionClone.Process = buildServer.QueryProcessTemplates(buildDefinitionSource.TeamProject).FirstOrDefault(c=> c.Id == buildDefinitionSource.Process.Id);
buildDefinitionClone.ProcessParameters = buildDefinitionSource.ProcessParameters;
buildDefinitionClone.TriggerType = buildDefinitionSource.TriggerType;
buildDefinitionClone.ContinuousIntegrationQuietPeriod = buildDefinitionSource.ContinuousIntegrationQuietPeriod;
buildDefinitionClone.DefaultDropLocation = buildDefinitionSource.DefaultDropLocation;
buildDefinitionClone.Description = buildDefinitionSource.Description;
buildDefinitionClone.QueueStatus = Microsoft.TeamFoundation.Build.Client.DefinitionQueueStatus.Enabled;
buildDefinitionClone.BatchSize = buildDefinitionSource.BatchSize;
buildDefinitionClone.Name = newBuildName;
foreach (var schedule in buildDefinitionSource.Schedules)
{
var newSchedule = buildDefinitionClone.AddSchedule();
newSchedule.DaysToBuild = schedule.DaysToBuild;
newSchedule.StartTime = schedule.StartTime;
newSchedule.TimeZone = schedule.TimeZone;
}
foreach (var mapping in buildDefinitionSource.Workspace.Mappings)
{
buildDefinitionClone.Workspace.AddMapping(
mapping.ServerItem, mapping.LocalItem, mapping.MappingType, mapping.Depth);
}
buildDefinitionClone.RetentionPolicyList.Clear();
foreach (var policy in buildDefinitionSource.RetentionPolicyList)
{
buildDefinitionClone.AddRetentionPolicy(
policy.BuildReason, policy.BuildStatus, policy.NumberToKeep, policy.DeleteOptions);
}
//Source Provider
IBuildDefinitionSourceProvider provider = buildDefinitionClone.CreateInitialSourceProvider(sourceProvider);
if (sourceProvider == VersionControlType.TFGIT.ToString())
{
provider.Fields["RepositoryName"] = "Git";
}
buildDefinitionClone.SetSourceProvider(provider);
buildDefinitionClone.Save();
return buildDefinitionClone;
}
private static IBuildController GetBuildController(IBuildServer buildServer, string buildController)
{
if (string.IsNullOrEmpty(buildController))
return buildServer.QueryBuildControllers(false).Where(c=> c.Status == ControllerStatus.Available).First();
return buildServer.GetBuildController(buildController);
}
source to share
To build the XAML you need to use the IBuildServer.GetBuildDefinition method to get the build definition first and then make a copy.
First, start by getting a reference to the build server by calling a method GetService
on the instance TfsTeamProjectCollection
. After you get the link to the build server, you can download the build definition you make.
If you want to copy assembly definitions with process parameters, you must first copy the template. Sinnp example code
// Copy Process parameters
newBuildDefinition.Process = buildDefinitionToCopy.Process;
var processParams = WorkflowHelpers.DeserializeProcessParameters(buildDefinitionToCopy.ProcessParameters);
var copyProcessParams = WorkflowHelpers.DeserializeProcessParameters(newBuildDefinition.ProcessParameters);
foreach (KeyValuePair<string, object> entry in processParams)
{
copyProcessParams.Add(entry.Key.ToString(), entry.Value);
}
newBuildDefinition.ProcessParameters = WorkflowHelpers.SerializeProcessParameters(copyProcessParams);
For more details on how to get a copy via the API, you can refer to this blog - Copying the TFS Build Definition
source to share