Friday, 24 April 2009

Auto-Configuration with TFS Builds

Over the last couple of months I’ve been working on a project which is making use of TFS Continuous Integration builds to a few environments. Until recently, one of the major pains of deploying builds to multiple environments was configuring each build manually after the fact.

Then, along came MSBuild Community Tasks. Admittedly, MSBCT is not a “new” thing by any means, and there’s probably not a lot of anything new here for some people, but I thought I’d provide some insight of how I’ve made good use of the tasks (particularly XmlMassUpdate and Attrib) to take the bulk of the effort out of automagically configuring builds right out of TFS.

Referencing the Community Tasks

In order to reference the MSBuild Tasks, add the following entries into your build project file. The XmlMassUpdate task does the majority of the heavy lifting in relation to auto-configuration, and the Attrib task clears the read-only flag on the config file(s) prior to copying to your build destination.

<UsingTask TaskName="XmlMassUpdate" AssemblyFile="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.dll"/>
<UsingTask TaskName="Attrib" AssemblyFile="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.dll" />

Referencing the Configuration Substitution File

The location of your configuration substitution file is done by adding the following entry to your build project file. This file will be used to swap out local development settings (for example, connection strings, file paths, service endpoint addresses) for settings relevant to the environment you’re building to.

<PropertyGroup>
    <
SubstitutionsFilePath>$(SolutionRoot)\Path\To\ConfigSubstitutions.xml</SubstitutionsFilePath>
</PropertyGroup>

Excluding the Configuration Substitution File from Deployment

In most cases, you’re not going to need the substitution file to be dropped to your build environment along with the rest of the application files. To exclude the file from the drop, add the following to your build project file.

<ItemGroup>
    <
ExcludeFromBuild Include="$(SubstitutionsFilePath)"/>
</ItemGroup>

Doing the Business

With all the setup done for making the tasks available, the last thing to do is to make the magic happen. Pasting in the following code clip will execute the configuration substitution task just before the build files are copied to your drop location.

<Target Name="BeforeDropBuild">
    <
Message Text="Configuration substitutions file located at $(SubstitutionsFilePath)"/>
    <
Message Text="Substitution path is /configuration/substitutions/MyConfiguration"/>
    <
Message Text="Updating configuration in $(OutDir)Path\To\My.config"/>
    <
Attrib Files="$(OutDir)Path\To\My.config" ReadOnly="false" />
    <
XmlMassUpdate ContentFile="$(OutDir)Path\To\My.config" SubstitutionsFile="$(SubstitutionsFilePath)" ContentRoot="/configuration" SubstitutionsRoot="/configuration/substitutions/MyConfiguration"/> </Target>

When the build completes, you can optionally do some post-deployment processes by adding an AfterDropBuild target to your build project.

And so ends today’s lesson.