Go to content Go to navigation Go to search

Brokenwire.NET::Programming

How to Copy TFS Build Definitions
· 2010-06-29 16:17 by Thijs Kroesbergen for Brokenwire.NET

First of all a question: Where is the copy option?

The answer: there is no copy option.

So because the Team Explorer doesn’t allow you to copy Build Definitions without manually copying all the fields I had to write a small tool to do so. In this post I’ll show you how that works.

First of all, the user-friendly designed-by-a-developer user interface:

First you connect to the TFS server then you select the Build Definition that you’d like to copy. Optionally you can add some find/replace values and finally you hit the button. As easy as 1-2-3. The interesting bit is of course how this is done.

The tree view at the left hand side is populated by this little piece of code:

TeamFoundationServer tfs = TeamFoundationServerFactory.GetServer("http://xxx:8080");
buildDefTreeview.BeginUpdate();
buildDefTreeview.Nodes.Clear();
ICommonStructureService common = (ICommonStructureService)tfs.GetService(typeof(ICommonStructureService));
var projects = common.ListAllProjects();
IBuildServer buildServer = (IBuildServer)tfs.GetService(typeof(IBuildServer));
foreach (var project in projects.OrderBy(p => p.Name))
{
    var currentNode = buildDefTreeview.Nodes.Add(project.Name, project.Name);
    var buildDefinitions = buildServer.QueryBuildDefinitions(project.Name);
    foreach (var buildDef in buildDefinitions.OrderBy(b => b.Name))
    {
        var newNode = currentNode.Nodes.Add(buildDef.Name, buildDef.Name);
        newNode.Tag = buildDef;
    }
}
buildDefTreeview.EndUpdate();

Basically it connects to the TFS server and iterates through the projects. For each project the Build Definitions are queried and the results are added as child nodes to the tree.
Behind the the copy button this piece of code does the real super-time-saver magic:

IBuildDefinition original = (IBuildDefinition)buildDefTreeview.SelectedNode.Tag;
IBuildDefinition copy = original.BuildServer.CreateBuildDefinition(original.TeamProject);
copy.Name = FindReplace(original.Name);
if (copy.Name == original.Name)
{
    copy.Name = "Copy of " + original.Name;
}
copy.ConfigurationFolderPath = FindReplace(original.ConfigurationFolderPath);
copy.ContinuousIntegrationQuietPeriod = original.ContinuousIntegrationQuietPeriod;
copy.ContinuousIntegrationType = original.ContinuousIntegrationType;
copy.DefaultBuildAgent = original.DefaultBuildAgent;
copy.DefaultDropLocation = original.DefaultDropLocation;
copy.Description = original.Description;
copy.Enabled = original.Enabled;
copy.Schedules.AddRange(original.Schedules);
copy.Workspace.Mappings.AddRange(original.Workspace.Mappings);
foreach (var mapping in copy.Workspace.Mappings)
{
    mapping.ServerItem = FindReplace(mapping.ServerItem);
}
foreach (var retp in original.RetentionPolicies)
{
    copy.RetentionPolicies[retp.Key] = retp.Value;
}
copy.Save();

The FindReplace function takes care of replacing the values from the find/replace list. The copying of most properties is rather straightforward. Of the the things to take into account is that the paths to the workspace and the Build Script (ConfigurationFolderPath) have to exist before you copy (create) the build definition.

I use this tool on TFS2008, but converting this to TFS2010 shouldn’t be hard. Of course it would be nice to see this kind of functionality in the next version of the Team Explorer. Until then, you can save a lot of typing and mouse clicks (and $$$) by using a tool like this.

Permalink -