Where Should You Deploy From?
By Adrian Sutton
Once you have an automated build, the next step is to automate deployment1. A lot of people take this to mean that you should be able to check out the code, compile it and deploy it all from your local work station. I think this is largely a really bad idea.
Firstly, if you have deployment system that needs to vary, or might in the future need to vary, based on the version of the product, then your deployment scripts have to be in source control with the product and be branched and versioned just like the actual source code. If your product just spits out a zip file that is uploaded to a web server for clients to download, you my want to separate the deployment of that zip file from the code base since it will change based on changes to the web server, not changes to the code. You should however still be able to build the zip file from scripts that are versioned with your source code.
In either case though, there’s no reason that you should be deploying builds from your local machine. Having a centralized deployment machine is a good idea for many of the same reasons that having a standard integration machine – primarily to avoid the it worked on my computer issues. At Ephox, our integration machine is also our deployment machine and we’ve simplified deployment of a build to the web site down to a couple of clicks on a web page that the integration machine runs. Technically, we can kick off the deployment from any machine without having to get up and the actual work is handled by the deployment server.
The deployment script is home grown and very basic – it actually just runs an ant process on the server and passes through the output – but it has a couple of nice features. Firstly, it allows you to select any successful build of any of our products and deploy it all through the same interface. Secondly, once you’ve picked the build to deploy it shows you the list of check-in comments for the changes specific to that build. You can also get it to retrieve a subversion log of all changes between two builds.
Switching to a deployment server has had a few benefits at Ephox – firstly, it means that your local machine is free to continue work while the build uploads. Even though an upload can be done in the background, the computer is tied up doing the build and running all the tests for a while, plus the developer can’t make changes to that source check out until it’s done. It all becomes a hassle, so moving that over to a separate machine makes it easier to get on with the next task straight away.
More importantly though, it means that every single build that is sent out to a client is built the same way, from a completely clean check out2 and we know that every single test has been run against it and passed. We’ve had a lot of success with eliminating regressions in builds we send to clients and the central build server was a good way to make sure we didn’t cut corners and skip the tests “just this once”. These days running the tests is so in-grained in our culture we could probably lose the server and still not be tempted to cut corners.
That same deployment system can also deploy new builds to all our internal systems with a single command. Again, it’s just a matter of copying files around so it doesn’t need to be versioned with our source code, but it has given us a huge amount of testing and feedback because the whole company is always using the latest cutting edge build from development. It certainly keeps the engineers focussed on not breaking stuff too.
Looking back on it, for the small amount of time required to set it up and the almost non-existent maintenance required, setting up a central distribution server has been one of the biggest pay-offs we’ve seen for improving our development process. Every company should consider doing it.
1 – in fact, some would argue that automating deployment is part of automating the build↩
2 – we configure cruise control to completely delete the checked out source tree and check out a fresh copy to make sure it is in a pristine state. We have a faster build that runs on every commit that just does an update, but that build stops as soon as it has run all the tests, so no distribution is made.↩