Now that I’ve discussed the advantages of separating your build and deployment scripts, lets look a little more closely at deployment scripts. As with build scripts, the first principle is simple and comprehensive - make sure you can deploy your product with one command. I don’t care whether it’s launched with a button on a web page, a shortcut on your desktop, or via the command line. However, you do it, the deployment script should do everything. It should take the build files, wherever you have stored them, and make that build available to your customers.
As such, the deployment script really cares about two inputs - what build to deploy, and which customers to deploy it to. The build should be easily specified by version number (and product name, if multiple products can use the same deployment script). All builds should be stored on a file server so they can be easily accessed without rebuilding them. All configurations should be available there, and a given deployment will typically take a certain configuration, depending on the deployment target and the purpose of the deployment, but it’s also worth allowing this to be specified when running the script. For deploying developer builds internally, the deploy script should be able to take files built by a developer on their own machine. That’s one reason to make sure your official build scripts and those used by developers are one and the same.
You should be able to specify the customers who receive the build as deployment targets. Deployment targets may include the developers machine, the QA team, internal dogfood, alpha testers, beta testers, and official releases. For a product like FogBugz (or Kiln) that is available in both a hosted environment as well as a licensed installer, each of those is a possible deployment target. For example, a developer may want to deploy the build he created after fixing a bug to his own machine, or to the QA team for test verification. The official build machine will be able to run the scripts that deploy an official build to alpha, beta, or regular customers.
Depending on the deployment target and the specific requirements of the product, the deployment scripts may do a large variety of things. It doesn’t really make sense for deployment scripts to be written in a build-oriented technology like make, ant, or MSBuild. I suspect that the real reason so many make replacements have been built using dynamic languages is because build managers haven’t properly separated build and deploy scripts. If they had, the advantages of being able to write code into your build scripts largely go away. The need for code (and the libraries you get with most languages) is most apparent in the deployment scripts.
For example, deployment scripts will often need to do much more than just copying files around. They may be required to setup web servers, modify databases, configure registry or xml-based settings, upload or download files to servers, create and modify web pages, change file permissions, etc. So you’ll want to use a language and framework that makes these types of operations easy to perform. Python, Powershell, and Perl seem like good choices.
Finally, as with build scripts, work to not repeat yourself in your deployment scripts. If different deployment targets use largely the same operations, refactor to eliminate duplicate code. Keeping your deployment scripts separated from your build scripts, clean, and capable of all the deployment possibilities you need with one command will make your life much easier as a build manager.
