Chained Builds in CruiseControl.rb (Update)
Last Thursday I wrote about the kind of chained builds functionality that I want from CruiseControl.rb. I think I’ve got it hacked in, at least to the “good enough” stage.
The first big change was to change the @trigger instance variable for the Project class from a single trigger to an array of triggers. I modified its name to @triggers to reflect this change. So in the initialize method for the Project class, instead of saying:
We now say this:@trigger = ChangeInSourceControlTrigger.new
Next, I modified the@triggers = [ChangeInSourceControlTrigger.new]
buildifnecessary method to collect information from all of the triggers about which revisions need to be built.
revisions = []
@triggers.each { |trigger| revisions += trigger.getrevisionstobuild(self) }
revisions = revisions.uniq.sort
if revisions.empty?
...
I also made a change to the triggeredby method for the Project class so that it accepts multiple triggers, and so that it always adds triggers to the existing set (instead of replacing them). Here’s what my modified version of triggeredby looks like.
def triggeredby(*things)
things.each do |thing|
if thing.is_a?(String) || thing.is_a?(Symbol)
@triggers << SuccessfulBuildTrigger.new(thing)
else
@triggers << thing
end
end
This allows me to declare dependencies in my cruise_config.rb file like so:
I had to modify the logicproject.triggered_by 'projectA', 'projectB', 'projectC'
get_revisions_to_build method for the SuccessfulBuildTrigger class a little bit, so that it wouldn’t return any build numbers from triggering projects that were older than the latest build of the “triggered” project. Here’s what that block looks like now.
The last step was to add the spaceship operator to theif last_successful_build.nil? || project.find_build(last_successful_build.label) [] elsif project.last_build && project.last_build.label.to_i >= last_successful_build.label.to_i [] else [Revision.new[last_successful_build.label] end
Revision class, so that I can sort arrays of them.
Note that thedef <=>(other) number.to_i <=> other.number.to_i end
number attribute for the Revision class sometimes refer to an integer, and other times to a string. I suspect that this is a bug, but calling to_i on it does the trick for this purpose.
It took a bit of experimenting to get it right, but this seems to be working properly now. It took maybe a couple of hours to get it working, and the code was easy to read and understand.
Hi Lyle,
We’ve added chained builds to the head version of cc.rb. We haven’t gotten it out the door as a release yet, but if you take the latest from svn…
In your cruisecontrol.rb file you specify:
project.triggered_by ‘My Project-Fast’
–Rolf
July 24th, 2007 at 9:00 amRolf, I already know about the current support for chained builds in CC.rb. I wrote about it previously and identified some of its shortcomings (from my point of view). This article describes how I hacked in a fix to get it to do what I want.
July 24th, 2007 at 9:36 am