Adding external build data to TFS

Wendell Phillips brings us today’s post about adding external build data to TFS.

-Trev

 

I recently found a need to add build data to Team Foundation Server 2008 from an external build process.  TFS ordinarily only maintains and processes build information from Team Build processes linked to the TF Server. If you use any build process that does not use Team Build and you want to use TFS to track your software lifecycle you might need to know and report on the builds where issues were found and where they were fixed.  Just entering a value in the “Found in” or “Integrated in” fields does not work as values must exist as a known build to TFS in order to be reportable.  Values not present in the dropdown list are ignored.  So the code below adds data to the TFS Builds database so that your external build appears in the dropdown and can be reported on.

I found an interesting blog from Jason Prickett and a forum post from Martin Woodward that, when combined and massaged a little gave me the code I needed to add Build Data to a TF 2008 Server.  The code is an “interesting” combination of parameters and hard-coded values.  The hard-coded values could also be passed in as arguments with a little modification.  Oh yeah, I am not a programmer so any comments on the elegance of the code will not be understood <g>.  I hope you find this useful.

-Wendell

 using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.TeamFoundation.Build.Proxy;
using Microsoft.TeamFoundation.Client;
using Common = Microsoft.TeamFoundation.Build.Common;
using Microsoft.TeamFoundation.Build.Client;

namespace AddFakeBuild
{
    class Program
    {
       
        static void Main(string[] args)
        {
            AddBuild("2008on2008:8080", "BuildTest", "BuildAgent1", "BuildDef1", "wpBuild002");
            if (args.Length != 5)
            {
                Console.WriteLine("Incorrect number of parameters, expecting 5");
            }

        }
        static void AddBuild(String serverName, String teamProject, String buildAgentName, String definitionName, String buildNumber)
        {
            // Get the TeamFoundation Server
             TeamFoundationServer tfs;
            tfs = new TeamFoundationServer(serverName);

            // Get the Build Server
            IBuildServer buildServer = (IBuildServer)tfs.GetService(typeof(IBuildServer));

            //Check the Build Agent Name, get the agent if it exists or create it if it does not exist;
          
             IBuildAgent buildAgent = GetBuildAgent(teamProject, buildAgentName,tfs);
            
            // Create a fake definition
             IBuildDefinition definition = AddDefinition(buildServer, teamProject, definitionName, buildAgent);

            // Create the build detail object
             IBuildDetail buildDetail;
            try
             {
                 buildDetail = definition.CreateManualBuild(buildNumber);
             }
             catch
            {
                Console.WriteLine("Build Number already exists");
                return;
             }

            
            // Create platform/flavor information against which test 
            // results can be published
            IConfigurationSummary confSummary = InformationNodeConverters.AddConfigurationSummary(buildDetail, "Debug", "x86", "");
            ICompilationSummary compSummary = confSummary.AddCompilationSummary();
            compSummary.ProjectFile = "Dummy.sln";
            compSummary.Save();

            // Complete the build by setting the status to succeeded and setting the drop location.
            buildDetail.Status = BuildStatus.Succeeded;
            // The drop location is not copied properly from the definition so we have to copy it manually.
            buildDetail.DropLocation = definition.DefaultDropLocation;
            buildDetail.Save();
        }
        static IBuildAgent GetBuildAgent(String teamProject, String buildAgentName,TeamFoundationServer tfs) 
            {
            IBuildAgent agent;
            // Get the Build Server
            IBuildServer buildServer = (IBuildServer)tfs.GetService(typeof(IBuildServer));
            
            IBuildAgentQueryResult queryResult = buildServer.QueryBuildAgents(buildServer.CreateBuildAgentSpec(teamProject, buildAgentName));
             
            if (queryResult.Failures.Length > 0 || queryResult.Agents.Length != 1)
            {

                 agent = AddAgent(buildServer, teamProject, buildAgentName);
                return agent;
                

            }
            
            agent = queryResult.Agents[0];
            return agent;
          

          }


        private static IBuildDefinition AddDefinition(IBuildServer buildServer, string teamProject, string definitionName, IBuildAgent agent)
        {
            IBuildDefinition definition;
            try
            {
                // See if it already exists, if so return it
                definition = buildServer.GetBuildDefinition(teamProject, definitionName);
                return definition;
            }
            catch (BuildDefinitionNotFoundException)
            {
                // no definition was found so continue on and try to create one
            }

            definition = buildServer.CreateBuildDefinition(teamProject);
            definition.Name = definitionName;
            definition.ConfigurationFolderPath = "$/";
            definition.ContinuousIntegrationType = ContinuousIntegrationType.None;
            definition.DefaultBuildAgent = agent;
            definition.DefaultDropLocation = @"\\MySharedMachine\drops\";
            definition.Description = "Fake build definition used to create fake builds.";
            definition.Enabled = false;
            definition.Workspace.AddMapping("$/", "c:\\fake", WorkspaceMappingType.Map);
            definition.Save();

            return definition;
        }

        private static IBuildAgent AddAgent(IBuildServer buildServer, String teamProject, String agentName)
        {
            IBuildAgent agent = buildServer.CreateBuildAgent(teamProject);
            agent.Name = agentName;
            agent.BuildDirectory = "c:\\nobuilddir";
            agent.Description = "Fake build agent used to create fake builds.";
            agent.MachineName = "NoBuildMachine";
            agent.Port = 9191;
            agent.Status = AgentStatus.Disabled;
            //try
            //{
            agent.Save();
            
           // }
            //catch (BuildAgentAlreadyExistsException)
            //{
                
            //}
            return agent;
        }
    }
}