Dashboard > CruiseControl > ConfiguringCruiseControl > CruiseControl Scheduling Scenarios
CruiseControl Scheduling Scenarios Log In | Sign Up   View a printable version of the current page.

Added by Kevin A. Lee , last edited by Mykola Dzyuba on Feb 27, 2009  (view change) show comment
Labels: 
(None)

CruiseControl Scheduling Scenarios

Overview

Although you can create a CruiseControl schedule quite simply, it is clear that different users have different requirements. There are a number of capabilities in CruiseControl that can meet these requirements but they are often not understood or well documented. This page is therefore an attempt to describe a number of common scheduling scenarios and how they can be implemented in CruiseControl.

Note: Please comment or modify this page if you have a better or alternate way of realising these scenarios!

The Continuous Integration (CI) build

The default CruiseControl mode of working is to execute a build on a schedule - only if modifications have been made:

<modificationset>
    <cvs localworkingcopy="C:\Sources\project"/>
</modificationset>
<schedule interval="1200">
    <ant
     antscript="${dir.javatools}\ant\bin\ant.bat"
     antWorkingDir="${dir.project}"
     buildfile="${dir.project}\build.xml"
     target="integration"/>
</schedule>

This example will execute an Ant build every 20 minutes (1,200 seconds) but only if something has been committed to the repository.

The nightly build

To execute a nightly build you can use the time attribute to the Ant builder:

<modificationset>
    <cvs localworkingcopy="C:\Sources\project"/>
</modificationset>
<schedule>
    <ant
     antscript="${dir.javatools}\ant\bin\ant.bat"
     antWorkingDir="${dir.project}"
     buildfile="${dir.project}\build.xml"
     time="2300"
     target="integration"/>
</schedule>

This example will execute a single nightly build at 11PM (2300), but again only if something has been committed during the day.

The forced nightly build

To execute a nightly build even if no modifications have been made you can specify that the project element does not require any modifications using the requiremodification attribute:

<project name="project-nightly-build" requiremodification="false">
...
    <modificationset>
        <cvs localworkingcopy="C:\Sources\project"/>
    </modificationset>
    <schedule>
        <ant
         antscript="${dir.javatools}\ant\bin\ant.bat"
         antWorkingDir="${dir.project}"
         buildfile="${dir.project}\build.xml"
         time="2300"
         target="integration"/>
    </schedule>
...
</project>

This example will execute a nightly build at 11PM as before, but this time it will build even if nothing new has been committed to the repository.

The fallback build - CI during the day, falling back to a forced nightly build

To execute a CI build as normal during the day but then force a nightly build (if no build has been executed during the day) you can use the timebuild plug-in as follows:

<modificationset>
    <cvs localworkingcopy="C:\Sources\project"/>
    <timebuild username="bldadmin" time="2300"/>
</modificationset>
<schedule interval="1200">
    <ant
     antscript="${dir.javatools}\ant\bin\ant.bat"
     antWorkingDir="${dir.project}"
     buildfile="${dir.project}\build.xml"
     target="integration"/>
</schedule>

This example will potentially execute a build every 20 minutes (1,200 seconds) if something has been committed to the repository, however if nothing has been committed during the day, the timebuild plugin will create a "fake" modification to force a nightly build at 11PM.

The mixed build - CI during the day and nightly build but calling different build targets

If you work on a large project that takes several hours to compile from scratch, and receives dozens of submissions from lots of developers every day, you probably don't want to wait all those hours to get feedback from your CI builds. One solution is to do CI builds incrementally, letting the compiler work through dependencies to compile only what's needed when a submission is made to the source code. But it's still probably a good practice to do a full build from scratch at least nightly, because incremental builds may not always find every possible problem. You can use the incremental build to give very quick but imperfect feedback on the status, catching the most common problems developers will submit, while the nightly build full gives more rigorous, but slower, feedback, catching those few problems that fell through the cracks of the incremental build.

To execute a quick CI build as normal during the day and then a complete build at night you can create different CruiseControl projects that check the same repository location but call different build targets:

<project name="project-CI-build">
    <modificationset>
        <cvs localworkingcopy="C:\Sources\project"/>
    </modificationset>
    <schedule interval="1200">
        <ant antWorkingDir="${dir.project2}"
         buildfile="${dir.project}\build.xml"
         target="partial-build"/>
    </schedule>
</project>

<project name="project-nightly-build" requiremodification="false">
    <modificationset>
        <cvs localworkingcopy="C:\Sources\project">
    </modificationset>
    <schedule interval="1200">
        <ant
         antscript="${dir.javatools}\ant\bin\ant.bat"
         antWorkingDir="${dir.project}"
         buildfile="${dir.project}\build.xml"
         time="2300"
         target="complete-build"/>
    </schedule>
</project>

This example has two projects which monitor the same location C:\Sources\project. The CI project will build every 20 minutes if changes have been committed to the repository and execute the Ant target partial-build. The nightly build project on the other hand will execute at 11PM whether anything has been committed to the repository or not and execute the Ant target complete-build. Typically the partial-build target would not execute an ant clean before building, however the complete-build target would.

The dependent build

To execute a build only if a build in another project succeeds, you can use the buildstatus plug-in as follows:

<project name="project1">
    <schedule interval="1200">
        <ant
         antscript="${dir.javatools}\ant\bin\ant.bat"
         antWorkingDir="${dir.project}"
         buildfile="${dir.project}\build.xml"
         target="deploy-application-to-webserver"/>
    </schedule>
</project>

<project name="project2">
    <modificationset>
        <buildstatus logdir="logs\project1"/>
    </modificationset>
    <schedule interval="1200">
        <ant
         antscript="${dir.javatools}\ant\bin\ant.bat"
         antWorkingDir="${dir.project}"
         buildfile="${dir.project}\build.xml"
         target="run-functional-tests"/>
    </schedule>
</project>

This example will only build project2 if project1 has been successfully built.

The Pause build

To obtain fine grained control over your build schedule you can use the pause plugin. This allows you to stop builds happening at certain times, for example if you want to backup your source control repository, you can use the pause plug-in as follows:

<schedule>
    <ant
         antscript="${dir.javatools}\ant\bin\ant.bat"
         antWorkingDir="${dir.project}"
         buildfile="${dir.project}\build.xml"
         target="integration"/>
    <pause starttime="0200" endtime="0600"/>
</schedule>

This example will pause (prevent any builds happening) between 2am and 6am in the morning. You can have multiple pause elements so you can also use this as a way to manipulate any schedule.

The forced periodic build

To execute a periodic build even if no modifications have been made:

<project name="periodic-build" requiremodification="false">
    <modificationset>
        <cvs localworkingcopy="C:\Sources\project"/>
    </modificationset>
    <schedule interval="1200">
        <ant
         antscript="${dir.javatools}\ant\bin\ant.bat"
         antWorkingDir="${dir.project}"
         buildfile="${dir.project}\build.xml"
         target="integration"/>
    </schedule>
</project>

This example will execute a build every 20 minutes (1,200 seconds), even if nothing new has been committed to the repository. This build will still check the repository for modifications in order to add them to the cruise email. If you don't want the overhead of checking the repository (since we are running regardless of changes) you can also do this:

<project name="every-20-minutes" requiremodification="false">
    <modificationset>
        <alwaysbuild/>
    </modificationset>
    <schedule interval="1200">
        <ant
         antscript="${dir.javatools}\ant\bin\ant.bat"
         antWorkingDir="${dir.project}"
         buildfile="${dir.project}\build.xml"
         target="integration"/>
    </schedule>
</project>

This build will always run every 20 minutes (1,200 seconds).

Different Builds on different Days

An attempt to answer Glenn's question: Build A runs Monday, Wednesday, Friday. Build B runs Tuesday Thurdsay. Just add several ant tasks within your schedule task.

<project name="Build A monday, wednesday, friday" requiremodification="false">
...
    <modificationset>
        <cvs localworkingcopy="C:\Sources\projectA"/>
    </modificationset>
    <schedule>
        <ant
         antscript="${dir.javatools}\ant\bin\ant.bat"
         antWorkingDir="${dir.projectA}"
         buildfile="${dir.projectA}\build.xml"
         time="2300"
         day="monday"
         target="build"/>
        <ant
         antscript="${dir.javatools}\ant\bin\ant.bat"
         antWorkingDir="${dir.projectA}"
         buildfile="${dir.projectA}\build.xml"
         time="2300"
         day="wednesday"
         target="build"/>
        <ant
         antscript="${dir.javatools}\ant\bin\ant.bat"
         antWorkingDir="${dir.projectA}"
         buildfile="${dir.projectA}\build.xml"
         time="2300"
         day="friday"
         target="build"/>
    </schedule>
...
</project>

<project name="Build B tuesday, thursday" requiremodification="false">
...
    <modificationset>
        <cvs localworkingcopy="C:\Sources\projectB"/>
    </modificationset>
    <schedule>
        <ant
         antscript="${dir.javatools}\ant\bin\ant.bat"
         antWorkingDir="${dir.projectB}"
         buildfile="${dir.projectB}\build.xml"
         time="2300"
         day="tuesday"
         target="build"/>
        <ant
         antscript="${dir.javatools}\ant\bin\ant.bat"
         antWorkingDir="${dir.projectB}"
         buildfile="${dir.projectB}\build.xml"
         time="2300"
         day="thursday"
         target="build"/>
    </schedule>
...
</project>

This example will execute Build A's build script on mondays, wednesdays and fridays at 11 pm. It will execute Build B's build script on tuesdays and thursdays at 11 pm. All builds will run even if nothing new has been committed to the repository (due to requiremodification="false").

Two builds in one project

This example shows a scenario where one of the builds has to run just once a day at a specific time (Build 1). The other build (Build 2) has to run at all other times.

<project name="MyProject" requiremodification="true">
...
<schedule interval="7200">
   <!-- Build 1  -->
    <ant time="0101"
     antscript="${dir.javatools}\ant\bin\ant.bat"
     antWorkingDir="${dir.project}"
     buildfile="${dir.project}\build.xml"
     target="run.unit.and.performance.tests"/>
   <!-- Build 2  -->
    <ant multiple="1"
     antscript="${dir.javatools}\ant\bin\ant.bat"
     antWorkingDir="${dir.project}"
     buildfile="${dir.project}\build.xml"
     target="run.unit.tests"/>
</schedule>
...
</project>

The Build 1 that calls run.unit.and.performance.tests ant target will be executed at 1:01 am. The Build 2 that calls run.unit.tests will be executed every 2 hours excluding the interval used by the first build. The sequence of ant tasks is important here. The build with the most specific schedule has to be specified prior to the builds with a more generic schedule.

Other scenarios?

If you have any other scenarios, please add them here...

SD

Can we have two seperate child elements in the <schedule> tag. For the example below I would like <ant> to run first and then <exec>

<schedule interval="86400">

      <ant ...

      <exec ...

</schedule>

Yes, you can have two separate child elements in the schedule tag but that probably won't give you what you expect.

 
  <schedule>
    <ant ... >
    <exec ... >
  </schedule>

Would only execute the ant builder.

 
  <schedule>
    <ant ... >
    <exec multiple="3" ... >
  </schedule>

Would run the exec builder ever third build. (Usually this multiple attribute is used to run a different target, like 'clean', every few builds.)

To get both builders to run on a build you'd need to use the composite builder:

 
  <schedule>
    <composite>
      <ant ... >
      <ant ... >
    </composite>
  </schedule>

What would you recommend for the following scenario:
projects A and B are independent projects and project C depends on the both - A and B.
Every time A or B are built successfully, I would like to have C to be built as well.

Here my questions are:

1/ If A failed, B succeeded that triggers C to be built and C fails because A is fail. I would like C won't be triggered in this case at all,
until A is fixed.
2/  A and B do not share any code and I would like to run them simultaneously - in different threads. However, C must not be run while A or B is running

I did not find a good way to configure neither 1/ nor 2/. Would you have some recommendation on that?

This is a real case environment - our code base contains projects in C++ and Java and the setup includes the artifacts from the both of them, thus
projects A and B are compiling C++ and java and project C compiles setups. We can't afford ourself to compile everything on every change,
just because of the size of the projects (C++ takes about 20 min to compile, the same for java)

Moisei:

You can accomplish #1 by using a combination of the build status and veto source controls. It is the veto in particular that would have C about a build if A is broken.

You can accomplish #2 by using the lockfilelistener/bootstrapper combination. A and C would share one lock file while B and C would share another.

(Note, this answer is likely to be merged into the main document and have both comments removed.)

What about this scenario:

- I want to run a shortened build (basically just tests) whenever a scm change is made. (mvn verify)

- I want to run a much longer suite (metrics, creating web-sites, etc) every night at midnight (either every night, or only if something has changed in scm since the previous midnight, independent of the "short" build running successfully since then. (mvn install site-deploy | ch.hortis.sonar:sonar-maven-plugin::sonar)

And this is complicated by the fact that I am using the same configuration of <plugin name="project"> for like 20 projects.  To do this, do I have to make 2 different plugin names? And if so, do I have to declare all my instances of the projects twice?

How can i achieve a forced build at say 4 AM, but only if i have pushed the force button within the last 24hours.
 
I have a production site which builds continuously, but I do not always i want my release server to be built every night. Therefore i need a way to click the button when i leave my office, and then know that my release server will be built at 4AM in the morning, ready for the next workday.
 
Any tips appreaciated!

Can we have several project and one starts when the previous one finishes, even if it fails? etc...

Something like the buildstatus plugin but if the build fails also.

Is it possible to start build,  only when build an another project succeeds. In my case projects belongs to different plugins(But in the same config file).

Isovi: a delayed build after button click should be possible by making a schedule that builds only manually and define a <pause> which ends when you want the build to run.

Powered by a free Atlassian Confluence Open Source Project License granted to ThoughtWorks, Inc.. Evaluate Confluence today.
Powered by Atlassian Confluence 2.7.1, the Enterprise Wiki. Bug/feature request - Atlassian news - Contact administrators