Our last Jam was both theoretical and practical. In the theoretical part we looked at what makes a quality build system. The practical part took some of the theoretical concepts and applied them, focusing specifically on continuous integration using Hudson. We also played around with some of the tools typically used in Java projects to aid in the project quality.
In the current context a build system is something that automates the static checking, compilation and running of automated tests (unit, integration and functional) against production code. If the build system has been carefully designed it may also include a process to manage the upgrade of a database and also create deployable artifacts (of course a build system may do more or less of the activities described). A facility to deploy these artifacts to various environments may also be included, though this is increasingly being handled by the continuous integration environments as they mature.
While the choice of tool used to automate the tasks mentioned above does not really matter, there are choices that will make the job easier. Some in the industry argue that the XML approach offered by tools such as Ant is cumbersome and not as powerful as new approaches that are offered by tools such as Rake or the Groovy Ant Task the script is actually written in code. Certainly the thing that must be avoided is starting a project using plugins that are offered by IDE’s to build certain parts of a system. Doing this tends to lock the building of a project into the IDE which makes the task automation impossible (unless of course if the IDE plugin has a scriptable equivalent). Over time it can become increasingly difficult to release the dependency on the IDE plugins. The aim is to create an automated build system that can be invoked by an external agent (a continuous integration tool or a developer) and not require any further intervention.
Simplicity is key! An easy to use build system will not require the definition of properties before it can be executed on a developer machine. For efficiency it should be possible for a developer to check a code base out of a repository and be able to invoke the build system on it (provided the requisite build tool has been installed correctly).
One goal of a build system is to make it fast, so it is painless and easy for a developer to run a full build prior to checking code changes into the code repository. The pain comes when the build is slow to complete. In such a scenario it is worth optimising the system (code or build system itself) so it executes faster. Sometimes the pain can be transferred to the continuous integration tool. This implies that a different build task or target may actually be invoked by the continuous integration tool. It is common to have a default build that is executed by developers (remember our goal of making it easy for developers to get up and running) which runs a good portion of the build omitting that which is slow. The slow parts can be transferred to the continuous integration version of the build.
We also looked at failing fast. It is important to ensure that those things that run quickly do so early so they can also fail early. For example, static code analysis tools that check for duplicate code should be run first as they are generally quicker to execute than a compiler or automated tests and therefore save time by failing early and fast.
In the practical component of the evening we used Hudson to integrate a solution to the Anagrams problem that we solved in the first Code Jam. That solution was hosted on GoogleCode and can be found here. It is also the same as the solution posted in the first Code Jam. The aim of the practical component was to install and configure Hudson, understanding the capabilities of what it and tools like it can do. We then modified the build file that came with the project to add checks to it. We also looked at a number of tools that are commonly used in Java build systems. All of the tools we looked at are open source:
- TiddlyWiki (used for instructions)
- JDK 6
- Same Code Duplication Detector
- Find Bugs
So how does a build system affect the agility of a project? A quality build system will help verify the quality of a system. Beyond that it aids in the concept of frequent releases (one goal of Agile) by making the artifacts required for deployment easy to create and obtain. Even deploying them in some cases.