I’ve always wanted to do automated deployments by checking in code. I feel strongly that any files on a webserver should be in source control. So, why not take it one step further and let the code check-in do the deployment as well. The methods below are in use at the company I work for. I’ve been using this method for 6 week or so now and have had close to 100 automated deployments with this method. Although its not perfect, it’s a very good start.
I am using the following components. By no means do you have to use the exact same technology here. This post is meant to promote concepts and not necessary technology. As long as the technology of your choice is capable of these concepts, you’ll be up and running in no time.
This is a list of the technology/software that I am using, but as mentioned above, these concepts don’t require the same technology, just technology that can do these things.
- Git – Source control
- Unfuddle – for shared source control
- TeamCity – Continuous Integration (CI) and build server
- Ruby/Rake/Albacore – Build scripts
- MSDeploy/WebDeploy – to do the syncing/deployment to web servers
Starting with the basics is source control. In my case, I am using Git but really, any source control system that has fairly lightweight branching is completely fine. What I mean by this, is that you need to be able to merge changes from one branch to another very easily. Git and Mercurial are perfect for this.
I am using braches to manage my deployment environments. So, I have 4 branches that I manage for this on top of my feature branches that I create.
Master/trunk/head – this is the branch I use when I’m done with a feature and ready to share it with my team. Its suppose to be bleeding edge code. You may or may not have this mapped to a deployment environment. In our case, I do not simply because I want this branch to be an easy way to share code with my team, but it may not be ready for deployment to a web server.
Dev – this branch is mapped to our Dev server. So, when I move code into this branch, I typically want someone to test out a feature before I’m ready to push it out to beta/QA. A good example of the usage of this is that I want a co-worker to play with a new rollover menu that I’ve created and want to see their interaction with it. I watch how it works for them, and go back and make changes.
Beta – this branch is mapped to our Beta/QA server.
Production – this branch is mapped to our production environment
I am using Unfuddle for a variety of things, one of those being our shared source control. Unfuddle provides SVN and Git hosting (to date). I have all my origin’s setup to Unfuddle to make things a little simpler. This really just needs to be any place that multiple users can get to the code. SVN by default as this, Git does not as it’s a distributed SCM. This could just as easily be a file share on our internal network.
We are using TeamCity as our build server. I chose TeamCity as it seemed to fit our needs the best. I’ve used CruiseControl.net in the past but I hate XML files so I didn’t want to use that again, however CruiseControl.net would work just the same. See this post on how I’ve hooked up Git/Unfuddle and TeamCity
I’ve played with a couple of build scripts (MSBuild, Nant, UppercuT, psake, and Albacore). I chose Albacore for a number of reasons but mainly I like Ruby. If you are a Powershell guy, go with psake. If you like Nant but don’t like XML, go with UppercuT. The point here is not the technology but the fact that you have script-enabled builds. If your project doesn’t have this, CREATE THEM and get those scripts in SOURCE CONTROL!
Up until this past year, my deployments were done by either, FTP, xcopy or drag and drop with Windows Explorer, and in a lot of cases, a combination of all of these. This was the case until Web Deploy entered the picture. If you fit into the FTP/XCopy group, please watch this presentation by Scott Hanselman. Trust me, this will make your life much better.
The Good Stuff
Okay, enough of the definitions and documentation, show me the code already!
My folder structure:
The build scripts are in, you guessed it, Build folder. Here I have a sub folder for each build/deployment environment:
You must have build configurations in your Visual Studio Projects/Solution that match in some way (they don’t need to be named the same).
All this really does it call msdeploy.exe with parameters (that’s what is in my .bat files). I let msdeploy do the heavy lifting of syncing and deploying to the web server.
My common folder has assemblyinfo.yml and build.yml to define common properties (e.g. path to solution, etc.) for all builds.
TeamCity configuration I’ve setup to use Rake and the build runner.
The big thing here is that you simply merge changes in from master or wherever you want. Also, if you need to make fixes in Production for example, make those fixes on that branch and simply pull those changes back to the master.
The final step that I do is have TeamCity tag the repository on every successful build.This way, I’ve got the branch tagged for every deployment. This is helpful if I need to rollback a changeset.
That’s about it. Once you’ve got this setup, you’ll never regret it.