MSBuild Inline Tasks to the rescue


A colleague (Pål Bendiksen) recently asked if there was an MSBuild task available to checkin pending changes in a Team Foundation Server workspace and get the check-in id. Looking at the MSBuild Extension Pack I saw no solution. Another solution would be to exec out to tf.exe, however there are complexities with scraping the output of that (…take note of the new ConsoleOutput and ConsoleToMSBuild properties exposed in the upcoming 4.5 version of the Exec Task. which make consuming output easier).

A short while later Pål reminded me that from MSBuild 4.0 you can create inline tasks. See: MSBuild Inline Tasks and Walkthrough: Creating an Inline Task for some great guidance.

Inline tasks are a great feature to leverage if you don’t have a compiled task immediately available. Once you get the time though, try get it added to your compiled task library where you can ensure your code meets any quality gates you have set, e.g. Stylecop, Code Analysis, Code Contracts etc…

Here’s the simple implementation which ‘gets the job done’…

<Project ToolsVersion="4.0" DefaultTargets="Default" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <UsingTask TaskName="CheckinTask" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll" >
        <ParameterGroup>
            <collectionURI ParameterType="System.String" Required="true" />
            <workspaceName ParameterType="System.String" Required="true" />
            <CheckinID ParameterType="System.Int32" Output="true" />
        </ParameterGroup>
        <Task>
            <Reference Include="Microsoft.TeamFoundation.Client" />
            <Reference Include="Microsoft.TeamFoundation.VersionControl.Client" />
            <Using Namespace="Microsoft.TeamFoundation.Client"/>
            <Using Namespace="Microsoft.TeamFoundation.VersionControl.Client"/>
            <Code Type="Fragment" Language="cs">
                <![CDATA[
                        CheckinID = 0;
                          Uri serverUri = new Uri(collectionURI);

                        TfsTeamProjectCollection collection = new TfsTeamProjectCollection(serverUri);

                        VersionControlServer versionControl = collection.GetService<VersionControlServer>();

                        Workspace[] wsList = versionControl.QueryWorkspaces(workspaceName,
                versionControl.AuthorizedUser, System.Net.Dns.GetHostName());

                        if (wsList.Length != 0)
                        {
                        Workspace ws = wsList[0];
                        CheckinID = ws.CheckIn(ws.GetPendingChanges(), "Build server");
                        }
                ]]>
            </Code>
        </Task>
    </UsingTask>

    <Target Name="Default">
        <CheckinTask collectionURI="http://M4600:8080/tfs" workspaceName="M4600">
            <Output TaskParameter="CheckinID" PropertyName="ID"/>
        </CheckinTask>
        <Message Text="CheckinID = $(ID)"/>
    </Target>
</Project>
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s