views:

45

answers:

1

This is a feature I'm used to from TeamCity - I could specify that a certain build configuration will be triggered by the success of another build configuration.

I could even pass the results of one build to another - but perhaps this is asking too much.

I'm looking for a similar functionality in TFS2008, is there a way to set a trigger on a build configuration that it shall start after another finished successfully ?

+3  A: 

I use the following target in my TFSBuild.proj:

Inject the new targets into the build process. We only trigger dependent builds if a "drop" was successfully created:

<PropertyGroup>
    <DropBuildDependsOn>
        $(DropBuildDependsOn);
        CreateDependentBuildItemGroup;
        TriggerDependentBuilds;
    </DropBuildDependsOn>
</PropertyGroup>

Create a itemgroup that contains a list of the dependent builds we want to trigger (the Include attribute will list the name of the dependent build as it appears in the build explorer - in my case below, the dependant build is called "Integration"). In our build process, we sometimes want to trigger more than one build, and we want to point the next build at the binaries that were produced by the current build (in this example, I want to run Integration tests against the binaries produced). Notice the hack to get around spaces in configuration names - eg "Any CPU" will cause a problem in the MsBuild args. Using this format, we can have custom MSBuild args per dependent build.

<Target Name="CreateDependentBuildItemGroup">
    <ItemGroup>
        <DependentBuild Include="Integration">
            <!--Using 8dot3 format for "Mixed Platforms" as it's tricky (impossible?) to pass a space char within /msbuildarguments of tfsbuild-->
            <MsBuildArgs>/p:CallingBuildDropFolder=$(DropLocation)\$(BuildNumber)\Mixedp~1\Ship;CiSmallBuildNumber=$(CiSmallBuildNumber);BuildNumberPostFix=$(BuildNumberPostFix)</MsBuildArgs>
            <PriorityArg>/priority:AboveNormal</PriorityArg>
        </DependentBuild>
    </ItemGroup>    
</Target>

Now, trigger the builds. Notice that we use a Custom GetOption: we want to make sure that dependent builds use the same changeset that the current build used - we can't use Latest, cos someone may have checked in in the meantime - so we want all dependent builds in our "chain" to all be based of the same changeset. The actual command is within the Exec, and the BuildStep stuff is to make sure we report the success (or failure) of the Exec.

<Target Name="TriggerDependentBuilds"
        Condition=" '$(CompilationStatus)' == 'Succeeded' ">
    <BuildStep TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
               BuildUri="$(BuildUri)"
               Name="TriggerStep"
               Message="Triggering Dependent Builds">
        <Output TaskParameter="Id"
                PropertyName="TriggerStepId" />
    </BuildStep>

    <PropertyGroup>
        <TriggerBuildCommandBase>TfsBuild start $(TeamFoundationServerUrl) $(TeamProject)</TriggerBuildCommandBase>
    </PropertyGroup>

    <Exec
        ContinueOnError="true"
        WorkingDirectory="C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\IDE"
        Command="$(TriggerBuildCommandBase) %(DependentBuild.Identity) /queue /getOption:Custom /customGetVersion:$(GetVersion) %(DependentBuild.PriorityArg) /msbuildarguments:&quot;%(DependentBuild.MsBuildArgs)&quot;">
        <Output TaskParameter="ExitCode"
                ItemName="TfsBuildResult"/>
    </Exec>

    <BuildStep Condition="'@(TfsBuildResult)'=='0'"
               TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
               BuildUri="$(BuildUri)"
               Id="$(TriggerStepId)"
               Status="Succeeded" />
    <BuildStep Condition="'@(TfsBuildResult)'!='0'"
               TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
               BuildUri="$(BuildUri)"
               Id="$(TriggerStepId)"
               Status="Failed" />
</Target>

I hope that helps...

Peter McEvoy