Source Server for TFS Builds

October 23, 2008

This is not yet a widely known practice in the field, but setting up a Source Server for TFS Builds in an enterprise development environment can be extremely valuable.

My friend and ex-colleague Jelle Druyts wrote a few months ago an excellent blog post about how to set up a Source Server for TFS Builds.

Anyone who will reference assemblies that are built with a source server enabled TFS Build will be able to debug those assemblies in the original source code … great for framework code for instance!

When an assembly is “source server-enabled”, the pdb file will contain the full path and the exact version of the file in source control that was used to build that assembly. If the debugger then enters a method, Visual Studio automatically downloads that correct file, places it in a local cache, and opens it for debugging. This is super sweet!

If you follow the guidelines of Jelle, you need to add the custom target RunSourceServerIndexing somewhere in your Team Build script, but he doesn’t specify exactly where you need to include this.

Well, you have two options : you can do this in your TFSBuild.proj file or you can also put this custom target in an underlying .targets file to make it more reusable. The TFSBuild.proj file is the easiest option, but I would recommend an underlying .targets file. In fact it’s always a good practice to make an underlying .targets file for all your common Team Builds. The idea is to make your .proj file as clean as possible and put all the logic and commands in an underlying .targets file.

In the image above you can see that I’ve created a specific target for all Compuware Team Builds on the Build Server. This .targets file must be imported in all TFSBuild.proj files and to enable source server for my Team Builds, I’ll just need to create a boolean variable in my TFSBuild.proj and pass it to the Compuware.targets file.

The Compuware.targets file will do all the required steps in the background. Note that the default is set to false for the variable SourceServerIndexing.

If you follow this pattern for other build tasks, you will end up with a clean TFSBuild.proj file and you will only need to pass booleans (and/or other variables) to the underlying .targets file that will contain all the reusable build tasks. Note that automatically all TFSBuild.proj files will import the default Microsoft.TeamFoundation.Build.targets file. Make sure that you never edit this master file, because it may jeopardize the working of your Team Builds when you need to migrate to another version of MSBuild.

Another small issue I came across when following the guidelines : the location where to drop the TFIndex.cmd file may be different than pointed out in the document (due to a different default location of the Debugging Tools). If that’s the case you must also check the location of this file when you set the custom target RunSourceServerIndexing.

If you haven’t taken the time to explore the possibilites of a Source Server for your TFS Builds, please do so now! You won’t regret!