As your codebase grows and your build starts to take an increasingly long time, it often makes sense to think about splitting your build process into a set of dependent builds (<shamless-plug>check out my paper "Scaling Continuous Integration" from XP2004 for some tips on how to do this</shamless-plug>). Currently, the main way to go about triggering dependent builds is to set up a separate project containing the secondary build process that you want to run. It can be triggered by changes to a file or folder that is being monitored by a FileSystemSourceControl. Here's an example of what your ccnet.config file might look like:
<cruisecontrol>
<project name="developerBuild">
<sourcecontrol type="cvs">
...
</sourcecontrol>
<build type="nant">
<buildfile>main.build</buildfile>
<targets>
<target>compile</target>
<target>unit.test</target>
<target>publish.distribution</target>
</targets>
</build>
<triggers><pollingInterval seconds="60" /></triggers>
...
</project>
<project name="customerBuild">
<sourcecontrol type="filesystem">
<repositoryRoot>C:\project\distribution</repositoryRoot>
</sourcecontrol>
<build type="nant">
<buildfile>integration.build</buildfile>
<targets>
<target>acceptance.test</target>
<target>ncover</target>
</targets>
</build>
<triggers><pollingInterval seconds="300" /></triggers>
...
</project>
</cruisecontrol>
The targets are meant to be illustrative of the types of things that you might want to put into the different builds.
As of CCNet 0.7.1, there is a new publisher called ForceBuildPublisher that can be used to force build for a project on a local or remote ccnet server. The ForceBuildPublisher can be set to force a dependent build depending on the status of the integration: whether it succeeded, failed or generated an exception. Here's what the above ccnet.config file would look like if you used this publisher:
<cruisecontrol>
<project name="developerBuild">
<sourcecontrol type="cvs">
...
</sourcecontrol>
<build type="nant">
<buildfile>main.build</buildfile>
<targets>
<target>compile</target>
<target>unit.test</target>
<target>publish.distribution</target>
</targets>
</build>
<triggers><pollingInterval seconds="60" /></triggers>
<publishers>
<forcebuild>
<project>customerBuild</project>
</forcebuild>
<serverUri>
tcp://localhost:21234/CruiseManager.rem
</serverUri>
</publishers>
...
</project>
<project name="customerBuild">
<sourcecontrol type="test" />
<build type="nant">
<buildfile>integration.build</buildfile>
<targets>
<target>acceptance.test</target>
<target>ncover</target>
</targets>
</build>
...
</project>
</cruisecontrol>
Note: that you can easily change the serverUri property to refer to a ccnet server running on a remote machine if you want to distribute your build process.
See also Enterprise Continuous Integration with Binary Dependencies example for some other examples demonstrating how to do this.