I've been meaning to write this post for a couple of months now as a follow-up to a session that Colin and I gave at the Microsoft Architect Insight Conference back in March, but just haven't found the time... at least, that's my excuse - anyway cutting to the chase!
Since the release of Team Foundation Server (TFS) there have been several Continuous Integration add-ons produced by various folks:
We've used most of the above, but despite however well they worked have found myself wanting some feature or other that was available in CCNet (actually it more about being badgered by developers about the missing features!). Whilst some of the above could have been extended to support these features, I couldn't help but feel that this would have been reinventing the wheel - hence the idea to extend CCNet.
By the time I started this Vertigo had already released the VSTS plug-in for CCNet (which is a CCNet source control plug-in), so it was just a matter of producing a CCNet task plug-in that was able to trigger a Team Build. The guts of calling the Team Build web service I based on the original CI Sample, but I was also keen to provide a mechanism for customising the behaviour of a Team Build in a more dynamic way than just creating another build type and changing the MSBuild properties.
Team Build provides a mechanism for passing custom MSBuild properties into it via a source controlled file called TFSBuild.rsp. This file consists of 1 or more lines each containing a valid MSBuild commandline switch (e.g. /p:PropName=value, would set the property 'PropName' to be 'value'). With that in mind, I developed the plug-in to allow these switches to be specified in the CCNet server configuration file (on a per CCNet project basis) and have it update the '.rsp' (in source control) before calling the build web service.
I'll hold off diving into any more detail at this point, but if there is interest out there then I can do a follow-up.
Attached to this post should be the plug-in assembly which you need to copy into your CCNet 'server' directory (along with the VSTS plug-in referred to above), and below is a configuration excerpt that shows how to configure the 'teambuild' task in CCNet.
<project name="TeamBuild_CI">
...
<tasks>
<teambuild>
<tfsServerUri>http://MyTfsServer:8080</tfsServerUri>
<teamBuildServer>MyBuildServer</teamBuildServer>
<teamProject>MyTeamProject</teamProject>
<teamBuildType>MyTeamBuildType</teamBuildType>
<workspace>MyBuildServer_MyTeamProject_MyTeamBuildType</workspace>
<dropsLocation>MyDropsArea\MyTeamProject</dropsLocation>
<msBuildParameters>
<MsBuildParameter>/v:d</MsBuildParameter>
<MsBuildParameter>/logger:ThoughtWorks.CruiseControl.MsBuild.XmlLogger,ThoughtWorks.CruiseControl.MsBuild.dll;msbuild-output.xml</MsBuildParameter>
<MsBuildParameter>/p:SkipInitializeWorkspace=true</MsBuildParameter>
<MsBuildParameter>/p:SkipGet=true</MsBuildParameter>
<MsBuildParameter>/p:SkipClean=true</MsBuildParameter>
<MsBuildParameter>/p:SkipDropBuild=true</MsBuildParameter>
</msBuildParameters>
<useMsTest>true</useMsTest>
<useMsTestCodeCoverage>true</useMsTestCodeCoverage>
</teambuild>
</tasks>
<publishers>
<merge>
<files>
<file>C:\MyTeamBuildWorkspacePath\MyTeamProject\MyTeamBuildType\BuildType\msbuild-output.xml</file>
</files>
</merge>
<xmllogger>
<logDir>.\Web\Logs</logDir>
</xmllogger>
</publishers>
...
</project>
Let me know if you find it useful, interesting or a waste of your time! (actually, maybe save your bandwidth in the case of the latter).