If you have a bunch of TFS builds that get a new home, it is always nice to let TFS know those files have been moved. But sadly, in the documentation there’s not much to find about this, nor is there any UI interface that lets you make this kind of change.
So I asked a question on the build forums, and Hongye Sun of Microsoft told me the best way to go at this, is use the Team Build APIs.
I’ve created a simple MoveBuild command line tool that allows you to move all the known builds from an old drop location to a new one, across all TFS projects.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Diagnostics; using Microsoft.TeamFoundation.Build.Client; using Microsoft.TeamFoundation.Client; using Microsoft.TeamFoundation.Server; namespace MoveBuild { class Program { static void Main(string[] args) { if (args.Length < 3) { ShowUsage(); return; } try { string tfsServer = args[0]; string sourceDir = args[1]; string targetDir = args[2]; bool commit = args.Length == 4 && String.Equals(args[3], "/Commit", StringComparison.InvariantCultureIgnoreCase); TeamFoundationServer tfs = TeamFoundationServerFactory.GetServer(tfsServer); ICommonStructureService css = (ICommonStructureService)tfs.GetService(typeof(ICommonStructureService)); foreach (ProjectInfo item in css.ListAllProjects()) { MoveBuilds(tfs, item.Name, sourceDir, targetDir, commit); } } catch (Exception ex) { if (!Debugger.IsAttached) Console.WriteLine(ex.ToString()); else throw; } } private static void MoveBuilds(TeamFoundationServer server, string teamProject, string sourceDir, string targetDir, bool commit) { int recordCount = 0; IBuildServer buildServer = (IBuildServer)server.GetService(typeof(IBuildServer)); foreach (IBuildDetail item in buildServer.QueryBuilds(teamProject)) { bool isMatch = item.DropLocation.StartsWith(sourceDir, StringComparison.InvariantCultureIgnoreCase); if (!isMatch) continue; recordCount++; //Console.ForegroundColor = isMatch ? ConsoleColor.Green: ConsoleColor.Red; //if (!isMatch) // Console.Write("SKIPPED: "); Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine(item.BuildNumber); Console.ForegroundColor = ConsoleColor.Gray; StringBuilder newDropLocation = new StringBuilder(); newDropLocation.Append(targetDir); if (item.DropLocation.Length > sourceDir.Length) newDropLocation.Append(item.DropLocation.Substring(sourceDir.Length)); StringBuilder newLogLocation = new StringBuilder(); newLogLocation.Append(targetDir); if (item.LogLocation.Length > sourceDir.Length) newLogLocation.Append(item.LogLocation.Substring(sourceDir.Length)); Console.WriteLine("Old location: {0}", item.DropLocation); Console.WriteLine("New Location: {0}", newDropLocation); Console.WriteLine("Old log location: {0}", item.LogLocation); Console.WriteLine("New log location: {0}", newLogLocation); if (commit) { item.LogLocation = newLogLocation.ToString(); item.DropLocation = newDropLocation.ToString(); item.Save(); } } Console.ForegroundColor = ConsoleColor.Gray; } private static void ShowUsage() { Console.WriteLine("MoveBuild - Usage"); Console.WriteLine("MoveBuild <TFS URL> <SourceFolderPattern> <DestinationFolder> [/Commit]"); Console.WriteLine(); Console.WriteLine(@"Example: MoveBuild http://mytfsserver:port \\OldServer\OldShare \\NewServer\NewShare"); Console.WriteLine(@"This will move all builds which have a drop location starting with \\OldServer\OldShare to \\NewServer\NewShare"); Console.WriteLine(); Console.WriteLine("If you specify /Commit the changes will be made to the database, if not, you only see a list of builds that would have been changed by this program"); } } }
To get this to build you need to:
© Copyright 2010 Jeroen Landheer Theme Design by Bryan Bell newtelligence dasBlog 2.3.9074.18820 | Page rendered at Saturday, September 04, 2010 7:16:31 AM (Pacific SA Standard Time, UTC-04:00)