views:

564

answers:

1

I'm in the process of developing several custom build scripts for TFS and I'd like to know if there are any best practices for developing, testing and deploying TFS build scripts.

Do you setup development and QC environments that are seperate from the production build server? Are there other ways to isolate the process of developing the scripts from the rest of the build process so that builds scripts under development don't interfere with "production" builds?

Team Build likes to create work items, update work items and add labels as part of the build process which I'd rather not have happen for a "test" build.

jMM

+1  A: 

Check out my answer here: http://stackoverflow.com/questions/977881/modular-teambuilds

You can keep core functionality factored out into a common MSBuild file that's included across all builds. Furthermore, all of these files are part of your broader branch structure, so they participate directly in your preexisting SDLC without any extra work. Thus:

  1. If you're making risky changes to your build scripts, make them in a "dev" or "private" branch, just as you would with any other risky changes.
  2. If you want a build definition that's just for quick validation, set properties like SkipLabel, SkipWorkItemCreation, etc to False in the *.targets file imported by that build definition.

To expand on #2 a bit, let's take your example of "production" vs "test" builds. You only want to turn on features like labeling in production builds. So you would remove the SkipLabel property from TFSBuild.proj (and also TFSBuild.Common.targets if it's defined there) and instead set it in TFSBuild.Production.targets and TFSBuild.Test.targets -- using two different values, of course.

As mentioned in the earlier question, TFSBuild.proj is the master msbuild file that controls how the rest of the build will operate. Here's what mine looks like:

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

<!-- DO NOT EDIT the project element - the ToolsVersion specified here does not prevent the solutions 
     and projects in the SolutionToBuild item group from targeting other versions of the .NET framework. 
     -->
<Project DefaultTargets="DesktopBuild" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">

    <!-- Import configuration for all MyCompany team builds -->
    <Import Project="MyCompany.TeamBuild.Common.targets"/>

    <!-- Import build-specific configurations -->  
    <Import Condition="'$(BuildDefinition)'=='Dev - quick'"     Project="MyCompany.TeamBuild.Quick.targets" />
    <Import Condition="'$(BuildDefinition)'=='Main - full'"     Project="MyCompany.TeamBuild.Full.targets" />
    <Import Condition="'$(BuildDefinition)'=='Main - quick'"    Project="MyCompany.TeamBuild.Quick.targets" />
    <Import Condition="'$(BuildDefinition)'=='Release - full'"  Project="MyCompany.TeamBuild.Full.targets" />

    <!-- This would be much cleaner as we add more branches, but msbuild doesn't support it :(
         Imports are evaluated declaratively at parse-time, before any tasks execute
    <Target Name="BeforeEndToEndIteration">
      <RegexReplace Input="$(BuildDefinition)" Expression=".*\s-\s" Replacement="">
        <Output TaskParameter="Output" PropertyName="BuildType" />
      </RegexReplace>
    </Target>
    <Import Condition="$(BuildType)==full"  Project="MyCompany.TeamBuild.Full.targets" />
    <Import Condition="$(BuildType)==quick" Project="MyCompany.TeamBuild.Quick.targets" />
    -->
</Project>

By doing something similar, you can ensure that all builds from the Dev branch are "quick" builds (which for you means no labeling, etc), all builds from the Release branch are "full" builds, and builds from the Main branch can be either depending on which build definition the user launches from Visual Studio / TSWA. Myself, I have "quick" builds set up with Continuous Integration and "full" builds running nightly.

Richard Berg
I saw you post on modular team builds and while this is an excellent approach to constructing build scripts, I'm looking for help on the physical process of developing build scripts. For example, how do I prevent running a build script that is not in "production" from be recorded as a production build. If that makes any sense.jMM
jMM
I expanded the post with a concrete example -- let me know if that helps.
Richard Berg
This was very helpful, thanks.
jMM