I'm attempting to make use of configuration transformations in a continuous integration environment.
I need a way to tell the TFS build agent to perform the transformations. I was kind of hoping it would just work after discovering the config transform files (web.qa-release.config, web.production-release.config, etc...). But it doesn't.
I have a TFS build definition that builds the right configurations (qa-release, production-release, etc...) and I have some specific .proj files that get built within these definitions and those contain some environment specific parameters eg:
<PropertyGroup Condition=" '$(Configuration)'=='production-release' ">
<TargetHost Condition=" '$(TargetHost)'=='' ">qa.web</TargetHost>
...
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)'=='qa-release' ">
<TargetHost Condition=" '$(TargetHost)'=='' ">production.web</TargetHost>
...
</PropertyGroup>
I know from the output that the correct configurations are being built. Now I just need to learn how to trigger the config transformations. Is there some hocus pocus that I can add to the final .proj in the build to kick off the transform and blow away the individual transform files?
The web.config transformation functionality that was added to Website Projects in Visual Studio 2010 is disabled by default for command-line and TFS builds.
There are two relatively straightforward solutions:
Option 1: Edit the build definition and add the following to the "MSBuild Arguments" field:
UseWPP_CopyWebApplication will cause the new Web Publishing Pipeline (WPP) to be activated for the build. WPP performs the web.config transformations and can also be used to block things such as .PDB files from being copied to the bin folder.
Option 2: Both MSBuild and WPP are fully extensible. Create a new XML file in the same directory as your project and use the ".targets" extension - for example, ProjectName.custom.targets. Place the following MSBuild code into the targets file:
Right click on your website and select "Unload project". Right click on the unloaded project and select Edit. Scroll to the bottom of the project file and look for these lines:
These lines are where the C# and Web Project build process gets hooked up. Insert an import to your custom build extensions (target file) immediately before the CSharp import:
That's it - you're good to go. The MSBuild customization method is a bit more work to set up, but the benefit is that you can use the new targets file to "hook" into the build process and have much more control over how your build happens on the server. For example, you could hook in tasks to perform CSS and JS compression.
I'd also recommend looking at "wpp targets" - if you name another MSBuild file with the specific name "ProjectName.wpp.targets" you can control the entire website publishing process. We use it to remove the -vsdoc javascript documentation files as the published website output is copied:
Everything said, you're probably better off leaving out the production web.configs from your build entirely. We place the transforms directly onto our production deployment machine and use powershell to transform as we deploy the application.
I finally managed to get this working. I'm using TFS 2008, but also using MSBuild 4.0 so it should work for you.
First, add this import to TFSBuild.proj:
Next, add a BeforeDropBuild target:
You can then copy the Web.QA.config.transformed to wherever you need it to go.
All you should need to do is setup which configuration should be used within the TFS build definition.
In my case I have setup a configuration specifically for CI that then performs the correct web.config transformations. Ensure that you have added the "CI" transform file and you should be good to go.
I found another way to accomplish this instead of creating a custom activity. You just need to modify the visual studio project file of the web application that is being built.
Add the following (a placeholder for the 'AfterBuild' target can be found towards the end of the project file):
Then you just have to add
/p:IsAutoBuild="True"
to the 'MSBuild Arguments' field found in the 'Advanced' section of the build definition.This will force TFS 2010 to do the transformations on the web.config when TFS does the build.
More details can be found on Kevin Daly's Blog.
To do this in WorkFlow, you have to create a Custom Activity. There's quite a good article about it here
For this specific activity you need to create and Activity project (change it from .Net 4 Client profile to .Net 4) and reference Microsoft.Build.Framework and Microsoft.Build.Utilities.v4.0 from the GAC and then Microsoft.Web.Publishing.Tasks from %programfiles%\msbuild\Microsoft\VisualStudio\v10.0\WebApplications (%programfiles(x86)% if you're on a 64bit system).
When that's done, you add these two classes:
First, there's a stub:
Then theres the activity class it self:
The reason for the BuildEngineStub is that the TransformXml class uses it to do logging.
The only thing you need to be careful about is that the TransformXml.Execute function locks the source configuration file until the build process is finished.
Here's an easier answer for you. :)
http://social.msdn.microsoft.com/Forums/en-US/tfsbuild/thread/d5c6cc7b-fbb1-4299-a8af-ef602bad8898/
From the link (in case it gets moved/404/etc):