With Visual Studio, we are able to create different build
configurations with the Configuration Manager. This allows us to create
different web.config files for a particular build target like Stage, Prod. The
idea behind this is that each target configuration contains the correct
application settings for that target environment.
When we build our projects on Visual Studio, we notice that
the web.config file is transformed to contain the changes that are needed for
the build target. When we use TFS Team Build, this does not happen by
default. An approach that we can take to
address this is as follows:
Add a target
directive only on the web project definition
For this step, we need to edit the .csproj file and add the
following XML entries:
<UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.Tasks.dll" />
<Target Name="AfterBuild" Condition="'$(IsTFSBuild)' != ''">
<Message Text="'Message After Build:
TFSBuild Status $(IsTFSBuild) - $(OutDir)\_PublishedWebsites\$(TargetName) '" />
<TransformXml Condition="Exists('$(OutDir)\_PublishedWebsites\$(TargetName)')"
Source="Web.config"
Transform="Web.$(Configuration).config"
Destination="$(OutDir)\_PublishedWebsites\$(TargetName)\Web.config"
/>
Element Name
|
Description
|
UsingTask
|
This element allows the MSBuild process to know in what assembly to
find the TrasnformXml task. We need to note that the path is the one on the
Build Server not a personal work station.
|
Target
|
The target is the action that runs the transformation process. We
want this to be done AfterBuild has completed, and we only want this done
when the IsTFSBuild argument is not empty. We add this argument to the TFS
build definition.
|
Message
|
The message element helps us make a log entry, so that we can
validate if this action is getting executed.
|
TransformXml
|
With this directive, we are executing a transformation task and
merging the web.config file with another config file that is associated to the
build target. For example for a release build, the $(Configuration) is set to
“Release”. The result is merged and copied on the _publishedWebsites folder
|
*Note this can also be done as part of the build definition,
but web.config is only applicable to web projects.
Save your file and unit test the change using the MSBuild
application from the Visual Studio command shell. The command should look like
this:
msbuild webproject.csproj /p:Configuration=Release
/p:IsTFSBuild=True > out.log
On our desktop the OutDir is set to the Bin folder, so we can
change the folder paths to read like this:
<TransformXml Condition="Exists('$(OutDir')"
Source="Web.config"
Transform Web.$(Configuration).config "
Destination="$(OutDir)\Web.config"
/>
A merged web.config file should be copied to the Bin folder.
Make sure to not include two target elements with the same name (AfterBuild).
The last element always override the one that was declared before it.
Add a MSBuild
Argument to the build definition
Now that the project file has been checked-in, we can test
this on Team Build. First we need to add the IsTFSBuild argument to the build
definition. This is done on Visual Studio. Add the parameter in the MSBuild
Argument textbox as shown below:
Now, we can queue a build and take a look at the
_PublishedWebSites folder. The web.config file should be merged with the
configuration from the build target. In
case this did not happen, we can look at the build log file. We can look for
the AfterBuild tag and find the message that was added to the project file. If
this is not visible in the log file, we need to make sure that there are no
typos on the changes and arguments that we are using.
Key Benefits
This process is a key component for the delivery a build and
deployment automation process.
Management of configuration files for multiple environments.