Recently I started on a new project, with a new client. As the project is new and the client doesn’t have an established .Net development group, we’re finding out that some things which we would often take for granted just aren’t in place. One thing that came to light early on was the lack of a repeatable deployment process. We’re scheduled to have a dedicated build and deploy person on our team in a few weeks, but in the meantime, I find myself in the undesirable position of having to manually deploy and configure our solution to our dev and QA environments. Our solution consists of an ASP.Net MVC application and three WCF services. Each of these pieces of the solution has some degree of configuration data that needs to change with each environment. These changes include things like connection strings (database server name), WCF security settings, etc. Without any kind of automated deployment process in place, that means I need to manually edit our configuration files each time we deploy. Personally, anytime I need to manually edit configuration files, I manage to screw them up in some way.
So, with the prospect of another month of botched deployments in mind, I decided to see if I could find an easy solution to getting builds setup for our dev and QA environments. One of the things I noticed early on with Visual Studio 2010 ASP.Net projects was that for some reason, I had a couple of extra configuration files:
Since part of the problem I was trying to solve related to configuration data, I decided to do some research to find out what these extra config files were and if they could help me. I came across this blog post which provided me with the info I needed. As it turns out, the additional files, Web.Debug.config and Web.Release.config are referred to as config transforms. The idea is that you use web.config as your baseline, with the settings you need for your local development environment. Then, for each solution configuration, you have a configuration trasnform file which has the changes you want to apply to your baseline configuration for that particular environment. When you create a new solution, you have initially Debug and Release solution configurations, so that’s why you see Web.Debug.config and Web.Release.config.
In our project, since we currently have only dev and QA environments, I went ahead and added two new solution configurations, called dev and QA. After adding the new configurations, to add the web.config transforms, you need to right click on web.config and select Add Config Transforms:
Your project should now look something like this:
Once you get your config transforms added to the project, you need to edit your transforms so that they contain the changes you’d like applied to your baseline. There’s plenty of good info on MSDN and elsewhere online on how to do this, so I’m not going to go into this much beyond a quick example of what a simple transform might look like:
The top file, web.config is my baseline and has a connection string that’s pointed to the local default SQL server instance. Below, we see the transform for the dev environment. Notice the connection string has a different SQL server name and has a couple of extra attributes. xdt:Transform and xdt:Locator control how the config transform build task applies the changes to the baseline. In this case, I’m saying that in the baseline config, replace the connectionStrings/add element that has a name attribute matching AppDataDb.
Now that we’ve built out all of the config transformations, how do we incorporate them into a build? Visual Studio 2010 provides packaging functionality for web applications which apparently takes advantage of the config transform feature. However for reasons I won’t go into here, I’m not able to use packages for deploying in my current project. Instead, modified our project files to have an AfterBuild task that runs when our apps our built on our build server. This task takes care of applying the config transforms. To make the this process easier, I installed the PowerCommands for Visual Studio 2010 extension, since this has an option to directly edit project files. After you install the PowerCommands and restart Visual Studio, right click on your project file and select Edit Project File:
Scroll down to the bottom of your project file and find the AfterBuild event. Depending on what kind of web project you’re working with, this may be commented out, if so, uncomment it. We need to add a TransformXml task to the AfterBuild event, like so:
Note that in my case, I was working with an ASP.Net MVC project which already has a task in the AfterBuild target, the AspNetCompiler task. In an MVC project, the AfterBuild target contains the condition “’$(MvcBuildViews)’==’true’”. This is to enable view compilation, which is disabled by default. You can either set the MvcBuildViews variable to true in your project file, or, as I ended up doing, move the condition from the AfterBuild target to the AspNetCompiler task.
So, with our config transforms completed and project edited, all that remains is to setup TFS build. All I did here was to setup new builds, one for each of our configurations, setting each build to use the appropriate solution configuration (dev or QA). I’m far from a TFS expert, so I’m sure there are better ways to handle this, but for our simple needs, this seems to be working just fine.