Anders G. Nordby

Lead Software Engineer at Sopra Steria

Creating deployment zip package with MSBuild and Team City

I had already set up continous integration with MSBuild and Team City, when the network guys suddenly decided that I could no longer have direct access to the test servers. In other words, I had to rewrite my deployment routine into building a zip package that I can manually deploy by coping and installing it on the test servers. I also decided to split the application files from the configuration files. Currently I’m only deploying to one server, but this will soon change, and I thought it a good idea to just build the application files once, and then have a separate package of config files for each environment.

The first thing I did, was create two local directories on the Team City server to deploy to. Then I changed my MSBuild file from deploying to the test server (which I had no longer access to) and simply deploy to the local directories instead. This is what my MSBuild file now looks like:

<Project xmlns="">
	<UsingTask TaskName="TransformXml"
  <Target Name="BuildAllAndDeploy" DependsOnTargets="Compile;transform-configuration-files;Deploy;" />

  <Target Name="Compile">
    <Message Text="=== COMPILING $(Configuration) configuration ===" />
    <MSBuild Projects="$(SolutionFile)"
             Properties="Configuration=$(Configuration)" />
  <Target Name="transform-configuration-files">
    <Message Text="=== DEPLOY CONFIG FILES to $(DeployConfigPath) ===" />
    <Message Text="=== XML transformation from $(WorkingFolder) to $(DeployConfigPath) ===" />
	  <TransformXml Source="$(WorkingFolder)web.config" Transform="$(WorkingFolder)web.$(Configuration).config" Destination="$(DeployConfigPath)\web.config"/>
	  <TransformXml Source="$(WorkingFolder)episerver.config" Transform="$(WorkingFolder)episerver.$(Configuration).config" Destination="$(DeployConfigPath)\episerver.config"/>
	  <TransformXml Source="$(WorkingFolder)episerverFramework.config" Transform="$(WorkingFolder)episerverFramework.$(Configuration).config" Destination="$(DeployConfigPath)\episerverFramework.config"/>
	  <TransformXml Source="$(WorkingFolder)episerverLog.config" Transform="$(WorkingFolder)episerverLog.$(Configuration).config" Destination="$(DeployConfigPath)\episerverLog.config"/>
	  <TransformXml Source="$(WorkingFolder)connectionStrings.config" Transform="$(WorkingFolder)connectionStrings.$(Configuration).config" Destination="$(DeployConfigPath)\connectionStrings.config"/>
    <TransformXml Source="$(WorkingFolder)IS-ESP.config" Transform="$(WorkingFolder)IS-ESP.$(Configuration).config" Destination="$(DeployConfigPath)\IS-ESP.config"/>
    <Copy SourceFiles="$(WorkingFolder)FileSummary.config" DestinationFiles="$(DeployConfigPath)\FileSummary.config" />

    <Message Text="=== DEPLOYED CONFIG FILES to $(DeployConfigPath) ===" />
  <Target Name="Deploy">
     <Message Text="=== DEPLOY LATEST BUILD to $(DeployAppPath) ===" />

       <DeployWebFiles Include="$(WorkingFolder)**\*.*" Exclude="$(WorkingFolder)**\*.cs;$(WorkingFolder)**\*.bat;$(WorkingFolder)**\*.rb;$(WorkingFolder)**\*.csproj;$(WorkingFolder)**\*.user;$(WorkingFolder)**\obj\**;$(WorkingFolder)**\*.pdb;$(WorkingFolder)**\*.config;$(WorkingFolder)**\*.vspscc;$(WorkingFolder)**\*.build;$(WorkingFolder)**\*.build.*;$(WorkingFolder)**\lib\**;$(WorkingFolder)**\Templates\Styles\sass\**;" />
    <Message Text="=== TheFiles: @(DeployWebFiles) ===" />

    <Copy SourceFiles="@(DeployWebFiles)" 
          DestinationFiles="@(DeployWebFiles->'$(DeployAppPath)\%(RecursiveDir)%(Filename)%(Extension)')" />

    <Message Text="=== DEPLOYED LATEST BUILD to $(DeployAppPath) ===" />

I then added two artefact paths to my Team City configuraion:

c:\TempDeploy\AppFiles =>
c:\TempDeploy\ConfigFiles =>

The Team City configuration now looks like this:

This works perfectly! I can now download the artifacts like this:

The solution is easy to expand with more environments (which I know will be coming pretty soon), and I can also use the tagging functionality in Team City to know which artifacts I have deployed to what servers.

By the way, out of curiosity, I searched up the location for the artifacts on the Team City server:


2 responses to “Creating deployment zip package with MSBuild and Team City

  1. Thomas 2014-06-18 at 13:08

    Stupid network guys… 😛 You should force them to manually install new testversions using notepad and command prompt

  2. Alberto 2015-07-15 at 00:29

    Thanks for finally talking about >Creating deployment
    zip package with MSBuild and Team City | Anders
    G. Nordby <Loved it!

Leave a Reply

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

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

Google+ photo

You are commenting using your Google+ 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

%d bloggers like this: