Automated deployments with TeamCity, Deployment projects & SVN

comments

One of the continually high risk and sometimes fiddly operations in web deployment is a web application’s deployment, and yet a lot of people working in smaller teams seem to have become stuck in the land of cowboys because the task of automated deployments seems either too difficult, too time consuming to setup or is perceived as un-needed. I’m about to attempt to prove all of these things wrong, while at the same time allowing you to get back to doing what you do best: write code.

Depending on the company you work in, you either have a locked down automated process for deployments or some dude is deploying from his local machine using drag and drop into an FTP client. This may work if a project is infitisimaly small or if you know you only have to do it once. Happily this is almost always not the case: Most projects contain more than one file, and will probably grow as your client comes back for changes, because they are so happy with your twitter replacement that costs money.

What is the problem?

Deploying a website means changing a sites configuration, maybe adding some new items to your sites environment – who knows, each application is different. These can be done by hand, but it is better if it is done in an automated fashion, so there is less chance of getting things wrong. This is what we are going to solve.

There are many many things that could make deployment of your project complicated, but we will start with what even the simplest websites can get value from;

  1. Different app settings between local and live servers
  2. Different connection string between local and live servers

Some other things you can automate, that i will add in a later post will cover some of the more advanced topics, such as;

  1. Database schema changes between local and live servers
  2. Synchronisation of live dynamic assets such as uploaded images etc between local and live servers

These are the settings that you need to change when you deploy your everyday basic website. As i said, these are really, really basic things, but the most important thing to be gained from having an automated deployment setup is one golden thing above all else:

Repeatability

Gremlins You need the piece of mind that every time you deploy there is less chance of issues, you get rid of so many potential business changing problems:

  • You always deploy the latest from your source control so that if someone has forgotten to get the latest on their local machine, they don’t inadvertently create some bug reversions.
  • If you are away from the office and one of your colleagues needs to deploy for you, the process is simple.
  • You place more responsibility on the quality of checked in code – if you check in, it needs to build, it needs to work, and it needs to not break anything.
  • No one accidentally uploads site settings that are dated, or potentially wrong for the deployment environment.
  • Plus many more potential Gremlins.

 

What we are going to do about it

What i am going to show you to do is the following:

  1. Setup Team City for Continuous Integration
  2. Add Web deployment projects to your sites
  3. Get Team City to build and deploy your site locally every time you check in.

This deployed folder will be the one that everyone will use for making deployments from – never from your local machine.

Please note that i am using Visual Studio 2008 for this demo, and Visual Studio 2010 has some wonderful new capabilities that can make what i am about to show you even easier – Scott Hanselman talks about them here.

Let’s get to it – Install software

So the first thing your going to have to do is download and install the following things on the pc you want to use as your build machine – this doesn’t have to be a separate pc, and could be installed on your local machine, or even inside a locally hosted virtual machine.

  1. Team City (On the build machine)
    http://www.jetbrains.com/teamcity/
  2. ASP.Net Web Deployment projects (on both the build machine and the development machine)
    http://www.microsoft.com/downloads/details.aspx?familyId=0AA30AE8-C73B-4BDD-BB1B-FE697256C459&displaylang=en

You will also need some form of source control, for the setup I'm going to show you i am using Visual SVN server, which i have preconfigured. Team City supports many different types of source control through addons, but out of the box it supports the following (not a small list):

  • ClearCase
  • CVS
  • Git
  • Mercurial
  • Perforce
  • StarTeam
  • Subversion
  • Team Foundation Server
  • Visual Source Safe

So no matter what you are using for source control Team City should have you covered.

During the installation of Team City it will install a web server on a designated port that you enter. Take note of this port for our configuration later.

image

Once installation of TeamCity is complete start both the Build Agent and Server services. When the installer is done you will be presented with a license agreement and be asked to create the first user account with administrator privileges. Take note of these details so that you can login later.

Step 1. Adding deployment projects to your Web sites

So this is where things get interesting. You’ve installed the web deployment project support on your local development machine, and are ready to go. Now all we need to do is add the new project type to your site.

Start by opening your web application/website in Visual Studio.

Then right click on the project you want to setup automated deployments for and click “Add Web Deployment project” to add the new project type to your solution, enter a name for your deployment project. I usually call mine “[SolutionName].[WebAppName].Deployment”.

image

If you’ve never added a web deployment project to a website before this will all be new to you. To give you a really quick rundown on web deployment projects i’ll just say this: Web deployment projects are basically just build scripts for MSBUILD.

Now you want to create a new build configuration for your deployment. This allows us to target a build for TeamCity to target later, and stop the deployment project from running when your building locally.

In the Build menu click “Configuration Manager” to open the screen below:

image

Click the solution configuration drop down this is currently selected “Debug” and Select “<New…>”.

In the new windows enter the configuration name as “Deployment” and click OK

image

Now using the same drop down select your Debug and Release build configurations and unselect the deployment project you just created from the build by un-ticking it.

image

Move the configuration drop down back to the Deployment configuration you just created so that we can set it up for Team City to run. Now close this window.

Now you need to create alternate configuration files for both your ApplicationSettings and ConnectionStrings configurations. So go ahead and create two new Configuration files. i save mine as /Configs/AppSettings.Live.config and /Configs/ConnectionStrings.Live.config. The contents of these files need to be your live or staging settings, that will be deployed when TeamCity builds the deployment.

<appSettings>
    <add key="MySetting" value="Different from local settings"/>
</appSettings>

Save the files. Now right click web deployment project and select properties to open its configuration. Make sure you have selected “Deployment” from the configuration drop down, then select the Compilation option on the left and enter the location for the build server to deploy to. This needs to be a local address as if it was being run on the build server. Not locally. In my case i’ve entered a UNC path to my webserver’s network share to deploy to, just to show you its possible. You’ll probably prefer to enter a local path like C:\builds\mywebsite. Remember this is as-if the path was being entered on the build server itself, as this project will be run on the build server once it downloads it from your source control.

image

Then select the Deployment option on the left. This where you can setup some basic transforms for your web.config files. We want to replace our applicationSettings and connectionStrings sections. You can simply enter the section to replace and the path to the file to replace it with. Enter yours to point to the file you just created.

image

Save this by clicking OK and your done with the Visual Studio settings for your deployments. Now onto the automation side of things.

Step 2. Creating a new Team City Project

Login to Team City by using the IP of your Team City server following by the port your entered earlier and using the user your created earlier into a web browser

ie http://mybuildserver:80

image

Once logged in click Administration on the top right. Once this page has loaded, click the Create project link.

image

Enter a name & description for your new project. Save this dialog.

image

The next page will have two extra tabs. One of these tabs is labelled VCS roots. Click this link so that we can add your source control servers settings to team city. Then click Create VCS root.

Enter a name for your VCS root and select the provider. As i stated I'm using Visual SVN, but your configuration may change – the advanced configuration of your source control provider is out of the scope of this post – refer to the Team City help for setting up yours. For me i just enter the URL for my SVN repo and the username and password i want to use and i also select full support in the Externals support setting.

image

Make sure you also check the box Make this VCS root available to all of the projects if you want to do multiple projects with this SVN server (not necessary for our configuration though) then click Save. Now click back to the General tab. Now click the Create new build configuration link.

On this page enter a name for your build – i call mine Local Deployment. Leave all the rest of the settings as is and click the button labelled VCS settings >>

On the next page select your recently created SVN repo from the drop down above. Leave everything else as is, and click the button “Choose build runner”.

On the Build Runner configuration page, select MSBUILD from the list.

Then enter the project or solution file to run from within your project into the Build file path. My solution filename is called MyWebsite.sln

Leave everything else as is, except for two important textboxes labelled “Targets” and “Command line parameters”.

In these two enter Targets: “Rebuild” and Command line parameters: “/p:Configuration=Deployment

Its really important to note the second one, as this setting tells MSBUILD to run the “Deployment” configuration we created earlier when a build is fired.

image

 

Click Save.

On the next page there will be a bunch of new navigation items on the right. Click on the link titled Build triggering. This page will take you to the configuration of when builds should be run. I want a new deployment to fire every time i check in. This way whatever is running on my staging server is always up to date.

To do this, tick the box labelled Enable triggering when files are checked into VCS.

Click Save and your done!

To test the deployment is very simple. Click Build queue to take you to the build queue watching page.

Now open visual studio on your development machine, make a change and check it in. This should now fire a build. refresh your build queue page a few times and you should be able to watch the build/deployment happen in real-time.

Any errors that occur will be very easy to fix as the build will give you a full report if it fails.

Troubleshooting

A common error that may happen if you have not installed the web deployment project types onto the build server is:

Microsoft.WebDeployment.targets" was not found.

This can be fixed by either installing the project types on the build server or copying the folder C:\program files\MSBuild\Microsoft\WebDeployment\v9.0\Microsoft.WebDeployment.targets to the build server from your local development machine.

Further Reading

A few other posts i have written that take what we’ve learned above further: