1
votes

We're upgrading our TFS farm to TFS 2012. In doing so, we've set up a new build server using the upgrade path in TFS Setup. However our new build controller has the name TFS2012Build, whereas the old one was TFSBuild.

Now I have many hundreds of build definitions that have an invalid build controller. Is there a way to update the build controller automatically or by script?

2

2 Answers

2
votes

I am unaware of any "automatic" methodology to do this. It is easy enough to get to the build definitions via the API, and the BuildController is available.

in the absence of decent TFS API documentation, there are many that have examples available for use of the API. A simple google search will reveal these.

A few suggestions to help kick start your effort: http://msdn.microsoft.com/en-us/library/microsoft.teamfoundation.build.client.ibuilddefinition.aspx

A good sample app is here: http://blogs.microsoft.co.il/blogs/shair/archive/2011/01/11/tfs-api-part-33-get-build-definitions-and-build-details.aspx

Finally, there is good code here that edits build definitions, and may be a better starting point for you: http://geekswithblogs.net/jakob/archive/2009/12/08/tfs-2010-ndash-managing-build-agents-using-the-api.aspx

Good luck.

0
votes

JamieMeyer had the right idea. There's not much good TFS documentation in MSDN, but there are a lot of good blogger resources. Here's a slightly obfuscated version of the script I created to do this over the course of a very educational weekend. We updated one project's build controllers by hand and then programmatically updated all of the other projects depending on the name of the build. call it like BuildControllerChangeUtil http://tfsserver:8080/tfs/defaultcollection ProjectName where the projectname is a project whose builds have updated build servers.

using Microsoft.TeamFoundation.Build.Client;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using System;
using System.Collections.Generic;
using System.Linq;

namespace BuildControllerChangeUtil
{
    class Program
    {
        static void Main(string[] args)
        {
            string tfsDefaultcollection = args[0];
            string knownGoodProject = args[1];

            var tfs = new TfsTeamProjectCollection(new Uri(tfsDefaultcollection)); 
            var buildServer = tfs.GetService<IBuildServer>();
            var knownGoodDefs = buildServer.QueryBuildDefinitions(knownGoodProject);
            var testController = knownGoodDefs.First(bd => bd.Name.Equals("Test")).BuildController ;
            var releaseController = knownGoodDefs.First(bd => bd.Name.Equals("Release")).BuildController ;


            foreach (var teamProject in GetTfsProjects( tfsDefaultcollection ))
            {
                var buildDetails = buildServer.QueryBuildDefinitions(teamProject);
                if (!buildDetails.Any())
                {
                    Console.WriteLine("{0} has no build defintions. ", teamProject);
                }
                foreach (var thisBuild in buildDetails)
                { 
                    if (thisBuild.Name.ToUpperInvariant().Contains("TEST"))
                    {
                        SetBuildController(teamProject, thisBuild, testController);
                    }  
                    else if (thisBuild.Name.ToUpperInvariant().Contains("PRODUCTION"))
                    {
                        SetBuildController(teamProject, thisBuild, releaseController);
                    }  
                    else
                    {
                        Console.Error.WriteLine( "Team project {0} had an unknown build name {1}",teamProject , thisBuild.Name);
                    }
                } 
            }

        }

        private static void SetBuildController(string teamProject, IBuildDefinition thisBuild, IBuildController bc)
        {
            Console.WriteLine("setting {0} build {1} build controller to {2}", teamProject , thisBuild.Name, bc.Name );
            thisBuild.BuildController = bc;
            thisBuild.Save();
        }

        private static IEnumerable<string> GetTfsProjects(string tfsAddress)
        {
            var tpcAddress = new Uri(tfsAddress);
            var tpc = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(tpcAddress);

            tpc.Authenticate();

            var workItemStore = new WorkItemStore(tpc);
            var projectList = (from Project pr in workItemStore.Projects select pr.Name).ToList();

            return projectList;
        }
    }


}