Team Build: Modify template that creates TFSBuild.proj file

A question came up recently about a common problem in organizations that utilize Team Build.  The problem was that there are some common Properties or Targets that must be added to every build.  They want to make it as easy as possible to ensure that these Properties/Targets are added.  As is usual, there were some constraints.  The first is that the Microsoft.TeamFoundation.Build.targets is off-limits to modification.  This is a generally accepted “best practice” as Microsoft does not guarantee that this file will remain the same between versions, and in fact has changed between TeamBuild 2005 and TeamBuild 2008.  The second constraint was that they wanted a way to add these “common elements” without having to go and manually check-out and modify each and every TFSBuild.proj file.

A solution that meets these constraints and solves the problem is to modify the Visual Studio template that is used to create the TFSBuild.proj files when you create a new team build type. 

IMPORTANT:  This template is in the PrivateAssemblies folder for Visual Studio.  As such, it can and likely will be overwritten during Visual Studio maintenance (e.g. Service Packs or KB updates).  As such, any changes you make here may be lost so it is important to check the resulting TFSBuild.proj file after the wizard ends.  Just like the Microsoft.TeamFoundation.Build.targets file, it is not a best practice to modify these files.

The template can be found in: 

[VS2005] C:Program FilesMicrosoft Visual Studio 8Common7IDEPrivateAssemblies1033tfsbuild.proj
[VS2008] C:Program FilesMicrosoft Visual Studio 9.0Common7IDEPrivateAssemblies1033tfsbuild.proj

Below are the (heavily edited) contents of the VS 2005 template.  As you can see, some of the values are static and some contain replaceable parameters (like Description) which are updated after the New Team Build Type wizard closes. 

To add your common Targets and Properties all you have to do is edit this file and then install it on each machine that will be creating Team Build Types. So if you always need to override the BeforeGet target, all you have to do is put your override target into a custom target file (say MyCustomBuild.targets) and then Import it after the Microsoft.TeamFoundation.Build.targets Import (like below).  To add custom Properties or ItemGroups, just add them right into the Template file at the appropriate location.

xml version="1.0" encoding="utf-8"?><Project>
 

 
 <Import Project="$(MSBuildExtensionsPath)MicrosoftVisualStudiov8.0
TeamBuildMicrosoft.TeamFoundation.Build.targets
" />
  
 <Import Project="$(MSBuildExtensionsPath)MyCompanyMyCustomBuild.targets" />
 <PropertyGroup>

<
MyCustomProperty>ACustomPropertyValueMyCustomProperty>
PropertyGroup>

 <ProjectExtensions>
 
 <Description>$description$Description>

 
 <BuildMachine>$build machine name$BuildMachine>
 ProjectExtensions>

 <PropertyGroup>
 
 <TeamProject>$Team Project name$TeamProject>

 
 <BuildDirectoryPath>$Build Directory (c:build)$BuildDirectoryPath>

 
 <DropLocation>$drop location (e.g. \Servershare)$DropLocation>

 
 <RunTest>$true/false$RunTest>

 
 <WorkItemFieldValues>Symptom=build break;Steps To Reproduce=Start the build using Team BuildWorkItemFieldValues>

 
PropertyGroup>
 

Project>

Just remeber that you have to install the updated Template tfsbuild.proj file to each machine that will create new Team Build types.  Also note that this will not do anything for Team Build types that have already been created, just new ones.

Many thanks to Team System MVPs Neno Loje and Marcel De Vries for the question and the answer, respectively.

 

Edited:  Added Caveat section warning about use of this technique.