The effort to simplify the “getting started” part of a development activity is small compared to the cost of allowing developers to muddle through. Most organizations ignore the costs of a broken construction process because work seems to get done in spite of it.
Consider the following situations:
- A development team can’t reproduce a problem found in production. After much manual effort they discover that the development environment is using a slightly different version of a third party library, and also a slightly different deployment configuration. The configuration files are edited by hand
- The overhead of fixing a problem includes a day to set up the development environment, since in includes a number of manual steps
By the time you hit these cases it is often too late to fix the underlying problem, so you muddle through, and forget the problem until it happens again.
The Importance of Construction
While some recent article discuss the importance of construction [Knoernschield], construction is an often neglected aspect of software development. While language constructs, performance, application functionality, and even version management practices grab the attention of developers, good practices in these areas are meaningless unless you can deliver a working application. To deliver a working application you need to be able to construct a working version of the complete application at every stage of the application development process; without a running application you won’t be able to test, and without tests, there is no way to verify your application’s quality.
A good build (or construction) process is essential for all types of development, agile and not, but a good construction process is a prerequisite for agile development because of agile method’s reliance on feedback; the clearest feedback is a running application along with a suite of unit tests. Without a reliable, repeatable, build process the best testing practices can be rendered futile because you have no reliable way to tell what you are building with, and what you are executing.
In most environments, construction happens at all levels of the application. There is a build that release engineers typically do. But developers must perform some sort of build process to test their code. The more similar that the various kinds of builds are, the less likely the “works for me phenomenon” will occur. This carries over to the idea that the developer’s build should be as similar as possible to the Integration Build and Release Build. While there may be subtle differences to account for environment, for example, setting up configuration files to point to a development database, it is to your advantage to have the build processes be as similar as possible so that the resulting application works the same, allowing one to both detect problems earlier (i.e., you can detect an issue in a development workspace before the application is released) and also to reproduce them more easily in the cases where there are issues discovered in production code that you did not have tests for in development.
Figure 1 illustrates the idea of a common build script. A build script along with some configuration properties should allow you to build (and perhaps deploy) for a variety of environments. A common script allows to more easily track what differs between environments.
If you include the deployment step as part of the build, your developers will be better able to reproduce problems in their workspace, and thus be able to resolve them.