views:

429

answers:

2
+1  Q: 

Modular TeamBuilds

I have 3 TFS Builds (2 Dev and 1 Cert).

I would like to modularize the builds so I don't have to edit 3 files each time I make a change to the common items.

The problem I have is that Only the items in the build folder (under TeamBuildTypes) are automatically retrieved by the Team Build. I can put in code in my build process to get other files, but by then it is too late.

Here is the scenario that I have. I make a "Common" location for common tasks. I then went and made changes to that file. Because the file does not down load until my build process tells it to down load it is retrieved too late (the import has already happened and the MSBuild process has constructed the build targets in memory).

I thought about adding it to the build's workspace, but then it will be retrieved in the Get Sources target (which is also too late).

I can't see a solution that will not have me duplicating the file or not using source control...

Any Ideas?

+3  A: 

There's no "ideal" solution to this problem in Team Build 2008, your best option is to put the common things on the build machine in $(MSBuildExtensionsPath) which resolves to C:\Program Files\MSBuild and then reference them from there.

If your build configurations are very similar you could:

  1. Point all of your build definitions to a single configuration folder.
  2. Put the common build logic in TFSBuild.proj.
  3. At the bottom of TFSBuild.proj add .
  4. Add the configuration that varies between build definitions in TFSBuild..proj.
William D. Bartholomew
+3  A: 

your best option is to put the common things on the build machine in $(MSBuildExtensionsPath) which resolves to C:\Program Files\MSBuild

I dislike the idea of taking a dependency on "magic" locations. You end up needing a 2nd deployment + QA process just to keep your build scripts in sync...

Only the items in the build folder (under TeamBuildTypes) are automatically retrieved by the Team Build.

Kinda lame, admittedly, but I haven't found it to be a major limitation in practice. Here's a simplified look at my TeamBuild folder:

$/TeamProject
   |- Dev
       |- Module1
       |- Module2
       ...
       Solution1.sln
       Solution2.sln
       |- TeamBuild
            |- 3rdparty
                MSBuild.Community.Tasks.dll
                MSBuild.Community.Tasks.targets
                RandomScriptOffTheWeb1.targets
                ...
            |- SrcSrv                
                srcsrv.ini
                ...
            |- SymStor
                dbghelp.dll
                ...
            Common.targets
            TFSBuild.proj
            TFSBuild.Common.targets
            TFSBuild.Config1.targets
            ...
            UtilityScript1.ps1
            ...
   |- Main           
       ...
       |- TeamBuild
       ...
   |- Release
       ...

Common.targets is imported by all *.csproj (etc) files. It imports all of my 3rd party tasks, initializes various global properties/items, and sets up reference paths.

TFSBuild.proj imports Common.targets, then TFSBuild.proj, then one of the config files by conditioning on $(BuildDefinition). That way the more specific always override tasks/properties/etc from less specific files as needed. Still, this short file is the one place where I do feel limited: it would be much nicer to programmatically map build names to filenames, but MSBuild won't let me make [declarative] imports depend on properties set in [runtime] targets like .

TFSBuild.Config*.targets files only set properties, for the most part; no "real" work. These encompass Team Build properties that I want to parametrize, plus others that control how my custom targets (implemented elsewhere) will work.

TFSBuild.Common.targets is the longest file by an order of magnitude. Here I configure all of the Team Build properties with good defaults, override targets like AfterDropBuild, and define lots of my own custom targets which execute conditionally based on what's set in the Config* files.

Note: I obviously have the recursive download option on, but it's not strictly required. Separating build depedencies into subfolders is more for aesthetics than anything.

Richard Berg