CruiseControl Enterprise: 10 Best Practices
# 1: Publish with a Publisher
Many projects use the concept of publishing: placing built artifacts into a repository, or making test results available to end users. The ArtifactsPublisher is a very popular way to publish to CruiseControl's own repository of timestamped directories, making logs and archives available via the CruiseControl dashboard or legacy reporting application. But ArtifactsPublisher is just one of a family of Publishers, my favourite being the AntPublisher. If your Ant build finishes by publishing artifacts to a repository or tagging your version control system, there may be another way to do things. Consider the Ant example below:
<project>
<target name="dist" description="build everything">
</target>
<target name="clean" description="delete all build artifacts">
</target>
<target name="test" description="run unit tests">
</target>
<target name="publish" description="publish to repository">
</target>
<target name="cruise" depends="clean,dist,test,publish"/>
</project>
The end state of the build is to publish unit-tested artifacts to an unspecified repository of some kind via the publish target. This is well and good, but the concept of publishing doesn't really fit the developer build; if we can disconnect the publishing activity from the rest of the build, we can run the same build in CruiseControl as the developers. To do this, have CruiseControl invoke your developer build, leaving publishing as a separate Ant target:
<project>
<target name="dist" description="build everything">
</target>
<target name="clean" description="delete all build artifacts">
</target>
<target name="test" description="run unit tests">
</target>
<target name="publish" description="publish to repository" if="logfile">
</target>
<target name="dev" depends="clean,dist,test"/>
</project>
The 'if' attribute on the 'publish' target ensures that the target can only ever be run by a publisher or a determined person. Next, you need to make some changes to your CruiseControl configuration:
<!-- some config removed from this example -->
<schedule interval="60">
<ant antWorkingDir="${checkout.dir}" buildfile="build.xml" target="dev"/>
</schedule>
<publishers>
<onsuccess>
<antpublisher antWorkingDir="${checkout.dir}" buildfile="build.xml" target="publish"/>
<onsuccess>
</publishers>
And you're done. Once you apply the new configuration to CruiseControl, it will start to run the same Ant build as the developers, meaning that there's no mystery when the build breaks. It may also shorten the build feedback loop by reporting success faster. While the developers celebrate or lament the state of the build, the AntPublisher can get on with the work of pushing artifacts around your network. I also use it to tag the codebase on a successful build - another thing that is specific to Continuous Integration. Publishers can be configured unadorned inside the <publishers> element in the config file to run every time a build completes regardless of status, or they can be wrapped in <onsuccess> or <onfailure> to run conditionally.
Publishers have a cousin element called Bootstrappers, but I'll cover that another time.
©Copyright 2007 Julian Simpson. All rights reserved.
Comments > (HTML is allowed)
-
EvgenySeptember 2nd, 2007 @ 09:37 PM
We are using CruiseControl at our workplace. And since I introduced the system, I am also in charge of it. The developers here never heard about continuous integration before, and telling them that their library will be published automagically, either daily, or after each submit to version control - it is just not acceptable (by them). It is all good and well to publish the artifacts to the project logs directory. But from there on - it seems that the only option to promote (some of the) builds as releases -- is to copy files manually to the somewhere where "customers" can take it. Customers are for example other teams in the enterprise. Anyway, where I am getting at -- there is no way to publish artifacts AFTER the build has completed. to publish on-demand, when a developer finished his thing, and CruiseControl successfully built it -- to push-a-button and have the artifacts delivered somewhere. There is just no such button to push. Any special reason why there is no option to just fire-up an Ant script/target on-demand with a button click?
-
CQSeptember 9th, 2007 @ 08:18 PM
You can specify which ant target to execute through the JMX interface.
-
Dave CameronSeptember 10th, 2007 @ 01:17 PM
Evgeny, you can also set up another project that only runs when you force it. Then the force build button for that project becomes the magic button to promote the artifacts. Maybe Julian will cover that in an upcoming blog...
-
Dave CameronSeptember 10th, 2007 @ 08:15 PM
The if="logfile" clause always seemed fishy to me: We have a similar pattern with CC.Net, but we suggest people should use the "CCNetLabel" variable. But, in both cases we're testing one variable to determine something different. In the interests of clarity, should there maybe be a Cruise=true environment variable? Then the target's clause would read if="cruise" and people wouldn't need to know about cruise's other variables.
-
EvgenySeptember 13th, 2007 @ 01:01 AM
We are using CruiseControl at our workplace. And since I introduced the system, I am also in charge of it. The developers here never heard about continuous integration before, and telling them that their library will be published automagically, either daily, or after each submit to version control - it is just not acceptable (by them). It is all good and well to publish the artifacts to the project logs directory. But from there on - it seems that the only option to promote (some of the) builds as releases -- is to copy files manually to the somewhere where "customers" can take it. Customers are for example other teams in the enterprise. Anyway, where I am getting at -- there is no way to publish artifacts AFTER the build has completed. to publish on-demand, when a developer finished his thing, and CruiseControl successfully built it -- to push-a-button and have the artifacts delivered somewhere. There is just no such button to push. Any special reason why there is no option to just fire-up an Ant script/target on-demand with a button click?

