How are build and deploy scripts different?
I got a couple of comments on Hacker News regarding my post about eliminating absolute paths in your code and scripts. User fragmede brought up the issue of using absolute paths to a common bin folder so that once you’ve built you can easily run and test your code. I responded by pointing out that what he actually is discussing is not part of a build script, but part of a deploy script. It’s easy to let the two scripts ambiguously coincide or put stuff that belongs in one in the other, but there is a lot of value in keeping them separate.
First of all, you don’t always want to deploy when you build, even on a development machine. On the build machine this concept is more clear. You may have a continuous build machine, which rebuilds your product from source with every checkin, or on a regular schedule. These builds could potentially be deployed to the same machine, but you’ll more likely want them deployed elsewhere, if at all. It may \be that all the continuous build is needed for is to verify that there are no build breaks or test failures, and no deployment is necessary.
Second, building for every deployment is wasted effort. Once you’ve built your product in a given configuration, you should be able to deploy what was built to a number of different locations. Obviously, you should be able to deploy it locally, to your dev machine. But if you’ve built on an official build machine, you’ll also want to be able to deploy to an internal dogfood. If your product is web based, this probably means configuring and setting up the internal server with the built files. If it’s a client app, it means making that client app available to everyone in your organization by notifying them and putting the installer on an internal file share. You may also want to deploy the build, once its been thoroughly tested, to beta testers and finally to all of your customers.
The last two points highlight an overriding principle: you want to decouple build and deployment scripts so you can change each separately. For FogBugz and Kiln there are lots of different build configurations - ship/debug, x86/x64, hosted/licensed, etc. Likewise there are lots of possible deployment targets - dev machine, QA machine, licensed installer available on internal share, or available as a customer download, internal dogfood installation, and obviously, deployment to actual customers. You want the capability of deploying any given configuration to any given deployment target for testing/debugging purposes, though of course, you’ll rarely if ever use certain configuration/target combinations.
Of course, the normal script that developers will run should wrap these scripts, so that they don’t have to run the build script, then deploy the build to their dev box in two separate steps.