Using MSBuild and Team City for Deployments (Part 3 of 4): Transform and Deployment

Transform and Deployment

The first build configuration in our team city project built, tested, analyzed, and packaged our application for deployment.  It created a set of artifacts that we can use to deploy this version of our application to each of the target environments.

Next we need to actually deploy our application.  This process requires two steps:

  1. Apply config transformations
  2. Deploy the package

Setting up the Transform and Deploy Build Configuration

One of the first things you will notice about the transform and deploy build configuration in our Team City project is that it does not have any VCS roots.  This is because it is unnecessary for these tasks to pull down the source and rebuild the application.  All they need is the artifacts of the we created in our build and package build configuration.  To access these artifacts, all we need to do is add them as dependencies for our configuration (steps #6):

Artifact Dependencies
Artifact Dependencies

As you can see in the image above, we need to be sure to depend on the three artifacts we created in our original build and package configuration.

Applying MSBuild Config Transformation without a Full Build

Since the artifacts necessary to deploy our application were created in the package step, it is unnecessary for us to rebuild our application.  Instead we just need to modify the web.config file appropriately for the target environment.  There is a very simple MSBuild target that will allow us to do this without a full build:


<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Transform"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003"&gt;
<UsingTask TaskName="TransformXml"
AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.Tasks.dll"/>
<Target Name="Transform">
<TransformXml Source="$(TransformSourcePath)Web.config"
Transform="$(TransformSourcePath)Web.$(Configuration).config"
Destination="$(PackagePath)Web.config"
StackTrace="false" />
</Target>
</Project>

view raw

gistfile1.txt

hosted with ❤ by GitHub

This target takes four inputs and uses those to transform the base web.config using the appropriate transformation:

  • Source – This is the relative path to the base web.config file.  We packaged this and the transformation files as artifacts of our original package build configuration.  They are included and available here because they are a dependency of our build configuration.
  • Transform – This is the relative path and file names of the transformations (you can see the provided $(Configuration) switch is being used to determine the correct transform file to use.
  • Destination – The destination for our new configuration file once it has undergone transformation.  This is the location of the package we intend to deploy.
  • StackTrace – Whether or not we would like a stack trace made available.

Here is the actual MSBuild command that is run by Team City:

Config Transformations Step
Config Transformations Step

Once this task is completed then we have a package with the following properties:

  • A fully optimized release build.
  • A web.configuration file that is correct for the target of our deployment.
  • Only the files and folders necessary to run this application on a hosted environment.

Now all that’s left is to deploy the application…

Deploying with MSDeploy

Our tool of choice for deploying Microsoft Web applications to IIS is MSDeploy (and I strongly recommend it to the reader).  You could easily use XCOPY, ROBOCOPY, or your copy file tool of choice, but MSDeploy offers a much more robust set of features and is tailored to deploying IIS assets.  For more information on MSDeploy you can go to the official MSDeploy support site.

The build configuration for this step is extremely simple:


"C:\Program Files\IIS\Microsoft Web Deploy V3\msdeploy.exe" -verb:sync -source:contentPath="%teamcity.build.workingDir%\%env.PackagePath%\" -dest:contentPath="%env.DestinationSite%",computername="%env.DestinationServer%"

view raw

gistfile1.txt

hosted with ❤ by GitHub

Next Post –> Using MSBuild and Team City for Deployments (Part 4 of 4): Setting up a Web.Config Transformation without a Solution Configuration or Publish Profile

Previous Post <– Using MSBuild and Team City for Deployments (Part 2 of 4): Continuous Integration Build and Verify

8 thoughts on “Using MSBuild and Team City for Deployments (Part 3 of 4): Transform and Deployment

  1. Great series Dave, my only recommendation is to put the MSBuild/MSDeploy commands (with command line parameters) into a batch file and keep the batch file in source control. This way your build configuration changes are tracked.

    1. Thanks Chuck! Good point and something I’ve been considering.

      One thing to keep in mind is that Team City does a great job of keeping revision history for all aspects of your build. You can see a full history of all of your changes right in the Team City UI. Because of this, it doesn’t seem necessary to add your build scripts to a source control repository just for revision history. I think it is probably better to just let Team City do its job and revision your build configurations. Source repositories for versioning source code and the build configuration to manage and version your build and deployment setups.

      In general, I think it might be best to keep all of the build artifacts separate from the source repository. If I was going to keep build artifacts in source control then I would prefer to do it in a separate repository than my source code. I’ve even been trying to come up with a way to remove the .msbuild files from the source repository.

  2. Hey Dave,
    Is there supposed to be some info at the end on how the deployment build step is configured?

    1. Hi Kevin. It was actually in the article as a gist, but at some point the blog engine started handling the gist includes differently so it wasn’t showing. I have fixed all of the includes in that series of posts, so the source files are now showing. Please let me know if you need more info. Thanks!

      David

  3. Hi David–

    Thanks for the great article. This saved me hours of work! I like and agree with your separation of “build” and “deploy”. I got my site deploying to our development, staging, and production sites in a number of hours thanks to you.

    Thanks,
    Brad

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.