Many developers don’t use source control and don’t use any automated tools. This is extremely inefficient and troublesome. Those on teams are forced to use source control in an effort to share the latest code with all members of the team. In the source control environments, there is a tacit agreement not to commit any code to the repository that will break the build. If the build breaks, it hinders the velocity of the other developers on the team because they cannot move on while the build is broken.
What does “build” mean?
Some folks use the term “build” to mean compile, and that is incorrect. On the teams that use no automated tools, the compile might be the only step in their build process, but the two are still different. The “build” is a process of taking the source of a software system and making it ready for deployment. Some teams will manually compile the source and stop before deploying to a development environment. These teams are short-changing themselves because the only feedback they’ve obtained about the current bits is that there are no syntax or linking errors. There is no verification that any part of the software functions as intended. Next, they may manually perform some steps to get all the bits and configuration in order to deploy the system to a development environment. Then after some manual testing, they’ve obtained some level of feedback.
Let’s compare the above with an Agile build.
Here are some steps that are often performed in the build process of an Agile team – these steps are always automated so they run fast and are repeatable:
- update latest code _and dependencies_ from source control. (automated process will get latest code from the SCC repository)
- compile solution (standard compile and link)
- copy application files to test location (output binaries moved to location to prep for automated testing)
- run automated unit tests. (automated tests produced through TDD or otherwise – give immediate feedback on the state of the system)
- automated environment setup to prepare for an integrated test of the system
- run integration tests. (gives even more feedback that the integration points of the system are functioning correctly – might include a database)
- run regression tests (if you have them – verifies that all past functionality is still working as before – this is a type of integration test)
- tag source control with build number if successful (only tag successful builds – discard unsuccessful ones)
- Notify development team members of success or failure
Some teams add more steps depending on their needs, and some teams don’t have integration or regression tests suites yet. Each build process should be developed by the team and tailored to the system. The above are some of the more common steps that Agile teams include in a build process.
The point of an automated build process is to transform the current code into a working system and get feedback on the current quality as fast as possible. If the entire process is fast, you will run it often and obtain feedback often. If it’s slow, you won’t do it often. The only requirement for the developer is to start the build. Many Agile teams even automate that step by having a program kick off a build after every commit to the SCC repository. That process is called “Continuous Integration”.
At the end of a build, the team should be confident that if they deployed these bits to an environment, it would work. There still may be bugs discovered, but they are confident that old bugs haven’t resurfaced and the system works at least as good as it did on the last build. The extra testing steps in the build process ensure that the state of the software is always moving forward. Without these steps, developers have no way of knowing if a change broke an existing feature.
Feedback is key in a build process. The team should decide what steps can be added to the build process to generate as much feedback as possible. My team recently inherited a system with a build duration of 25 minutes. This is way to slow for us, and our initial goal is to reduce that duration to 10 minutes. We’ll be able to do this by emphasizing fast unit tests more and doing away with some of the really slow integration tests (that have delicate, cumbersome data setup scenarios).
Tools my team uses in our build process:
- Subversion (source control)
- CruiseControl.net (build runner and tagger – keeper of the builds)
- CCTray (system tray notification of successful or failed builds)
- NAnt (Xml scripting format to describe steps to be run during the build)
- NUnit (automated test harness)
- .Net SDK (includes compiler and linker)