If you provide the interval trigger without any parameters, you will get the default 60 seconds between the time the last integration ends and the next cycle begins. By default, the build fires only if something changes in the source repository. You can change the default settings this way:
<intervalTrigger seconds="30" buildCondition="ForceBuild"/>
This will cause the CCNet to cycle this project every 30 seconds and build every time regardless of any changes in the repository.
Let's consider a more complicated scenario. What if you want to build projects that are referencing a shared library and something changes inside? You can use another type of trigger, a project trigger, as in Listing 2.
<project name="WindowsCalculator"> <workingDirectory>c:\CI\WindowsCalculator\</workingDirectory> <artifactDirectory>c:\CI\WindowsCalculator.Artifacts</artifactDirectory> <webURL>http://localhost/ccnet</webURL> <triggers> <intervalTrigger initialSeconds="0" /> <projectTrigger project="Framework"> 1 <triggerStatus>Success</triggerStatus> </projectTrigger> </triggers> <sourcecontrol type="svn"> <trunkUrl>https://HAL/svn/P001/trunk</trunkUrl> <executable>C:\Program Files\Svn\bin\svn.exe</executable> <username>marcin</username> <password>password</password> </sourcecontrol> <tasks> <msbuild> <executable> C:\Windows\Microsoft.NET\Framework\ [CA]v4.0.20506\MSBuild.exe</executable> <projectFile>build.proj</projectFile> <buildArgs>/p:Configuration=Release /verbosity:minimal</buildArgs> <logger> C:\Program Files\CruiseControl.NET\server [CA]\ThoughtWorks.CruiseControl.MSBuild.dll </logger> </msbuild> </tasks> </project> <b> 1 Project dependency trigger </b>
We are performing an ordinary CI build every 30 seconds and, additionally, we are checking if a dependent project completed its build (#1). If it did, we fire the build for WindowsCalculator as well.
You can distribute your projects over more machines. CCNet lets you distribute your projects indirectly. This means you don't have a centralized server that is managing build processes but you can couple several CCNet instances. For example, if the Framework project is built on a separate machine, you can provide the additional attribute serverUri to your project trigger like this:
<projectTrigger serverUri="tcp://server:21234/CruiseManager.rem" project="Core"> <triggerStatus>Success</triggerStatus> <innerTrigger type="intervalTrigger" seconds="30"/> </projectTrigger>
This way, one CCNet instance will ask another instance about the Framework build. Additionally, the innerTrigger element lets you define how often it happens. We decided it should poll the changes from another CCNet server every 30 seconds rather than the default 5 seconds, which might be too often for a distributed scenario.
What if you have a long-running build you want to perform once a day, possibly at night? For example, you may need to generate documentation from your source code. It takes a lot of time. It is not necessary to generate the documentation whenever the source code changes. You can use the schedule trigger to accomplish this. Let's define it:
<scheduleTrigger time="03:00" buildCondition="ForceBuild" />
In this case the build will fire every night at 3:00 AM.
You can limit the trigger further. Let's say you want this build to run once a week at night on Sundays. Here you are:
<scheduleTrigger time="03:00" buildCondition="ForceBuild"> <weekDays> <weekDay>Sunday</weekDay> </weekDays> </scheduleTrigger>
Using triggers you can easily manipulate the build chain. But this chain has an end. When the build is done you have to pass on the feedback. You can do it with publishers.
As you can see, there is a lot to configure with CCNet. You will learn a lot about how the CI servers are working by manually configuring CCNet. You will have to use the CCNet documentation quite extensively to get it done the way you want it to work. And it will take a little time to bring it to the right level.