Queue a Team Build from another and pass parameters

I have previously blogged about queuing a new Team Build at the successful completion of another Team Build for Team Foundation Server 2010. Since then I’ve had a few people ask how to queue a new Team Build and pass information into the new Team Build via the build process parameters. Recently I’ve needed to implement this exact behaviour for a client, and with TFS 2013 which has quite different default build process templates, so I thought I’d share it here.

In my situation I’m building on top the default TfvcTemplate.12.xaml process but the same approach can be easily applied to the Git build templates too. To begin, I have added two build process parameters to the template:

  1. Chained Build Definition Names – this is an optional array of strings which refer to the list of Build Definitions that should be queued upon successful completion of the current build. All the builds will be queued immediately and will execute as the controller and agents are available. The current build does not wait for the completion of the builds it queues. My simple implementation only supports queuing builds within the same Team Project.
  2. Source BuildUri – this is a single, optional, string which will accept the unique Team Build identifier of the previous build that queued it – this is not intended to be specified by a human but could be. When empty, it is ignored. However, when provided by a preceding build, this URI will be used to retrieve the Build Number and Drop Location of that preceding build and these values, plus the URI, will be made available to the projects and scripts executed within the new build. Following the new Team Build 2013 convention, these values are passed as environment variables named:
    • TF_BUILD_SOURCEBUILDURI
    • TF_BUILD_SOURCEBUILDNUMBER
    • TF_BUILD_SOURCEDROPLOCATION

The assumption is that a build definition based on my “chaining” template will only queue other builds based on the same template, or another template which also accepts a SourceBuildUri parameter. This also means that builds can be chained to any depth, each passing the BuildUri of itself to the next build in the chain.

The projects and scripts can use the TF_BUILD_SOURCEDROPLOCATION variable to access the output of the previous build – naturally UNC file share drops are easier to consume than drops into TFS itself. Also the TF_BUILD_SOURCEBUILDURI means that the TFS API can be used to query every aspect of the preceding build, notably including the Information Nodes.

Prior to TFS 2012, queuing a new build from the workflow and passing parameters would have required a custom activity. However, in Team Build 2012 and 2013, Windows Workflow 4.0 is used which includes a new InvokeMethod activity making it possible to add items to the Process Parameters dictionary directly from the XAML.

The final XAML for the Build Process Template with support for queuing and passing parameters is available as a Gist. If you’d like to be able to integrate the same functionality with your own Team Build 2013 template you can see the four discrete edits I made to the default TfvcTemplate.12.xaml file from TFS 2013 in the Gist revisions.

When a build using this chaining template queues another build it explicitly sets the RequestedFor property to the same value as the current build so that the chain of builds will show in the My Builds view of the user who triggered the first build.

In my current implementation, the SourceBuildUri passed to each queued build is the URI of the immediately preceding build, but it some cases it may be more appropriate to propagate the BuildUri of the original build that triggered the entire chain. This would be a somewhat trivial change to the workflow for whomever needs this behaviour instead.

3 comments

  1. Pingback: Queue another Team Build when one Team Build succeeds | Jason Stangroome
  2. Joshua McKinney (@joshuamck)

    Jason,

    One problem I’ve seen with a similar change is the changeset on the original build doesn’t flow through to the later builds. It’s hard to tell from the XAML whether this is the case in your changes. This can cause TFS to associate builds with incorrect / inconsistent changeset numbers. In several instances we also saw false positive failing tests. Queuing a build before the previous one finishes is one trigger of this problem.

  3. Jason Stangroome

    Hi Josh,

    I’m not explicitly passing the changeset through to subsequent builds in my XAML but in my use case, chained builds are consuming the build drop output, not new files from version control.

    However, the SourceGetVersion property on the IBuildDetail is available and could either (a) be passed to the chained builds, or (b) the chained builds could read it from the API via the SourceBuildUri.

    In Team Build 2013, very little happens between the point I queue the next build in the chain and the current build completing so I haven’t hit any issues here yet.

    Regards,

    Jason