CruiseControl is a tool for implementing Continuous Integration. It helps manage the builds for your projects. You can schedule the builds based on time or on any modification made to the repository storing your project. Beyond controlling the builds, it also provides a reporting dashboard for monitoring the status of your projects.
So, the workflow goes like this. You make some modification to the code base and check it into the repository. After a few minutes of waiting (a cup of coffee or tea), a mail notification will be sent to you telling you whether or not your modification caused any problem to the code base. If no problem, well, you can be relaxed and either go home or get another work item. If there’s a problem, you can quickly check the build log included in the mail to see what was the cause. After you fix the problem, you can sit back and wait for the email notification of the result of this fix. Normally we would like to set the waiting time to be within 10 minutes so we can get quick feedback. Note that there’s no manual operation on the server side in the workflow. Every thing is automated.
This is great, really great indeed!
The configuration of CruiseControl itself is through a XML file. In the file you specify the builder, the schedule, the notification, etc. Usually, we would like to put this configuration file in the repository as well. And that brings the idea of “eating your own dog food”.
A separate CruiseControl builder is set up for updating its own configuration file. Whenever I need to change any settings, I simply modify the XML file and check it in. A few minutes later, all changes to the configuration are taking effect. This is great in that I don’t need to log into the build machine. It could be done on any host as long as I or anyone else can check in the configuration file.
Everything is perfect now, except ...
The current version of CruiseControl does not support adding/removing builders on the fly. That is, if you add a new builder, you have to restart CruiseControl. Well, I admit that the needs for adding builder rarely happens.
I know version 2.2.1 has been out for quite a while. I have just installed it but had problems with it, so I go back to version 2.2. The problem relates to Subversion modification set, which always reports the last modification is 1970/xx/xx ... Not good!
I’ve been involved in setting up continuous integration for quite a while. So far so good. However, because the project is composed of several components, things were getting a little ugly. The problem was that it spent far too long to finish a complete build, which made me split it into two separate ones. One for the normal, relatively fast build which only performs unit tests and limited report generating. The other one is daily build which takes much longer to generate a complete Maven project site. I still wasn’t very satisfied with this strategy because the normal build still took me 10 minutes to complete. It did not provide static analysis report either (which I really think should be part of a normal build).
The tools I use are CruiseControl and Maven. I have set up one CruiseControl instance for each of the two builds. The root cause of the slowness is that there are many components. Each time we build, we build every component, from the first to the last. Even if only one of the components have changes, we still build all of them every time. I have thought of having one CruiseControl instance for each component. However, that did not work because I had no way of detecting binary dependency. Say if component A depends on component B, we should rebuild A when A has any change. We should also rebuild A as long as B has any change. If A and B all have their own separate CruiseControl instances, I don’t know how to achieve that effect.
Well, luckily I have spotted this paper today: Enterprise Continuous Integration Using Binary Dependencies. The basic idea is that we will publish the latest build artifacts of all components to a central repository. If component A depends on B, then it will fetch B from the repository instead of building B manually. When we are building A, we check in the repository whether the latest version of B has been modified or not. That way we can detect changes from binary dependencies!
The key for me is that CruiseControl can have multiple modification sets. So I will have one modification set for source code repository and one for binary dependencies. By using Maven, I already have the ability to detect changes of dependenciy versions. Luckily CruiseControl even has a modification set called mavensnapshotdependency (finally there’s some return from using Maven). This way I don’t have to rebuild all components every time. Only build necessary components when only necessarily. What a perfect world!

