Apache Continuum: Ensuring the Health of your Source Code (Part 2)

Brett Porter

September 2009

The build definition

As we have seen in the Continuum build life cycle overview earlier, Continuum uses build definitions for building the projects.

We can think of build definitions as instructions for Continuum on how to build the project. There are two levels of build definition: project group level and project level.

Project group build definition

Let's go back to the Project Group Summary page of our centrepoint application and click on the Build Definitions tab. Continuum configures a default build definition for each project group created. The content of the build definition depends on the type of the project. For Maven 2 projects, goals such as clean install and clean deploy need to be defined while Ant and shell projects do not require this. Instead, they configure their respective command-line goals.

As we can see from the Project Group Build Definition of our Centrepoint project group below, the goals to be executed for the build can be configured as well as the schedule of its execution.

Apache Maven 2 Effective Implementation

The default Project Group Build Definition has clean install as its goals. Having install as a goal means that the project's artifacts will only be available locally (in the local Maven repository) to where our Continuum instance is running. Consumers of the project (for example, the project's Quality Assurance team) will not necessarily have permission to access the machine itself and it is out of the question to obtain the latest build from the local repository. Instead, the right way to do is to set up a deployment repository for snapshot artifacts, configure Continuum to build the project, and deploy the built artifacts to the snapshot repository, so that there is a new build each day that can be consumed by the QA team for testing.

<name>Archiva Managed Releases Repository</name>
<name>Archiva Managed Snapshots Repository</name>

We don't need to configure anything else in our settings.xml and security-settings.xml.

Now let's create a new build definition for our Centrepoint project group. Click the Add button on the group build definitions page, then fill in the Build Definition as follows:

Apache Maven 2 Effective Implementation

The POM filename is the actual filename of our project's pom.xml that will be used for the build. The Goals are the goals we want to execute when using this build definition. As we want our artifacts to be available to the snapshots repository, we will set clean deploy as our goals. The Arguments specify the additional arguments that will be used when building the project. In our case, these are Maven 2 arguments, as our project is a Maven 2 project. If you had wanted to do a fresh checkout instead of just updating from the source repository during the build, you would tick the Build Fresh checkbox.

One behavior of Continuum to take note of is that if there were no changes to the SCM in the last build; Continuum would no longer build the project. This sometimes causes people to panic and think their CI is broken, but it is actually not. When you think about it, it makes sense that this is the default behavior. There were no changes in the code, so why build it? To countermand this behavior, you would tick the Always Build checkbox in the build definition. This would tell Continuum to always build the project whether there were any changes in the SCM or not.

The Is it default? field signifies that the build definition is the default one that will be used when the project build is explicitly triggered (forced build) from the Project Group Summary and Project Summary pages. This field can only be edited if there are multiple build definitions defined for the project.

We will discuss schedules next, but for now we will just use the DEFAULT_SCHEDULE. The same goes for Build Environment. We will cover this at the end of this article. For now, we will leave as it is.

As for the last two fields, they simply specify the type of project the build definition is for and the description of the build definition respectively.

Click Save and our build definition is created.

Now for each project group, we can define multiple build definitions and attach it to a schedule. A schedule is just a plain old schedule of when a build will be triggered or executed. The diagram below, which Wendy Smoak created for Continuum effectively shows how the project group, build definitions, schedules, build queues, and notifiers (which we will discuss later on) work together.

Apache Maven 2 Effective Implementation

Going back to the schedules, a default schedule running every hour is already pre-defined in Continuum and that is where the default build definition is attached. We will create a schedule for our project's nightly builds where we will attach the build definition that we created so that there is a fresh snapshot each day which the QA team can test for all the changes or fixes in the code from the previous day. From the Schedules tab on the left you can add a new schedule. Fill in the form as follows:

Apache Maven 2 Effective Implementation

The important field to take note of in the Schedule is the Cron Expression.

A Cron Expression is a representation of a time or times at certain intervals. This is used typically to fire or trigger a schedule to do or execute something.

From the Cron Expression we have specified above, we are configuring our schedule to build each night at 12 midnight.

The other field to take note of is the Build Queue. This simply defines where the project(s) attached to this schedule will be queued. If no build queue were set, Continuum would use the DEFAULT_BUILD_QUEUE.

Save the schedule that we created. Go back to Centrepoint's Build Definitions tab, edit the Project Group Build Definition we created earlier and attach it to our NIGHTLY_BUILDS schedule.

When setting a schedule, sometimes an hour is too long to wait. If a problem occurs it may be drowned out by other changes, or the developer may have switched context. Builds should be kept short and scheduled frequently. Long-running tasks, such as performance and functional tests, and nightly builds can be run on separate schedules.

To demonstrate how build definitions are used, click the build icon (third column from the right) of our snapshot deployment build definition. After the projects in the group have finished building, go back to the Project Group Summary page and click on the build number link (fifth column from the left) of one of the projects. Clicking on the build number leads us to the build result of that specific build including the build definition used and the build output. We will cover build results in the succeeding sections. You can also check the snapshots repository at http://localhost:8081/archiva/repository/snapshots to see that the projects were deployed.

Project build definition

A project level build definition is essentially the same as a project group build definition—it could be tied to a schedule and everything. The only difference is that it's on a per project level. Therefore, when only that project was triggered to be built, continuum would use the default project level build definition.

The notifiers

We mentioned earlier in the article that one of the benefits of using a CI server is that when the build breaks, the project members would immediately know of it. This is where notifiers come in. Notifiers are a configuration in the CI, which send out notifications to the project members regarding the status of the build.

Different types of notifiers

In Continuum, there are five types of notifiers that can be configured. These are the:

  • Mail notifier: The mail notifier sends out an email to a specific address regarding the status of the build. For the mail notifier to work, it's good to keep in mind to set up a mail server first. Remember, we did this whilst installing prerequisites at the beginning of the article.
  • IRC notifier: This notifier sends out a message to a specific IRC channel alerting the channel of the project's build condition.
  • Jabber notifier: This notifier sends out a message to a specific Jabber account.
  • MSN notifier: This notifier sends out a message to a specific MSN account.
  • Wagon notifier: This notifier deploys the build results to a specific URL (for example, to the project's site) using Wagon.

These notifiers can be configured to notify the project team on certain conditions of the build. They can be set up to Send on Success, Send on Failure, Send on Error, and/or Send on Warning as seen in the following screenshot:

Apache Maven 2 Effective Implementation

They are self-descriptive, but we will give each one a quick run through:

  • Send on Success: Send out a notification if the build was successful.
  • Send on Failure: "Code red! Code red! Code RED!!!". Need we say more? Okay, just to elaborate... a notification will be sent out when the build fails. By fail, we mean that a problem was encountered during build execution. This can be a compile failure, a test failure, or simply a dependency not being found.
  • Send on Error: A notification will be sent out when there was an error outside of the build execution. A good example of this is when the source repository goes offline and Continuum cannot update its working copy.
  • Send on Warning: A notification will be sent out if the build was not a successful build, a failed build, or an erroneous build.

A notification is sent only when a project's state is modified. For example, if the previous state of all the projects in the group is SUCCESS and on the next build, all the projects in the entire group were built successfully again, no notification will be sent. However, if the second build of one of the projects failed (state is FAILURE), a notification will be sent specific to that project.

The Send a mail to latest committers field for the Mail Notifier tells Continuum to send a notification mail to those developers who committed changes to the source repository as part of the last build. The Mail Recipient Address does not have any effect on the Send a mail to latest committers as the email addresses where the notification mail will be sent are retrieved from the list of project developers.

Like build definitions, notifiers can also be configured at the project group level and/or at the project level. Notifiers are cumulative, which means notifiers configured at the group level always takes effect whether or not there are notifiers configured at the project level. This is similar to the co

Now, let's create a group mail notifier for our centrepoint application. In our exercise, we will use our own valid email address for the mail notifier. We want to know everything that is happening to our project build so we tick all the checkboxes except for Send a mail to latest committers (we don't have usernames in our SVN repository so we don't have any use for this). Let's build our project by pressing the Build All Projects button on the Project Group Summary page. We should get a successful build and the build states of all the projects in the group should show the SUCCESS icon. However, no notification mail was sent. This is because there were not any changes in the build state nor were there any changes in SVN.

Now, let's edit the test case of one of the modules of our Centrepoint application. Go to your local checkout of the project and open PropertiesProjectStoreTest.java located at modules/store-file/src/test/java/com/effectivemaven/centrepoint/store/properties/ either in your IDE or in a text editor. Add the following failing test to the class:

public void failingTest()
assert false;

Commit the changes that we made and then let's build the Centrepoint project group in Continuum. Now, we will see that we got an email notification (similar to the one in the following screenshot) that contains a summarized build result status for Centrepoint Data Store (Flat File) project, which had the failing test case.

Before continuing, make sure to remove the broken test and commit again so that the build succeeds!

Apache Maven 2 Effective Implementation

To learn more about how to configure the different types of notifiers in Continuum, visit http://continuum.apache.org/docs/1.3.3/user_guides/notification/index.html.

Configuring notifiers in Maven

The Maven 2 project model allows configuration for the CI server officially used by the project. This can be achieved through the <ciManagement> section, wherein the type of CI server, the URL where it is running and the build notifiers to use can be configured.

As we can see in the sample configuration below, it has similar parameters to what we can configure in Continuum.


The value in the <configuration> section varies depending on the type of notifier extended and used.

If a notifier is configured in the POM of a project when it was added to Continuum, that notifier would be automatically configured in Continuum and will be used to send out build notifications. Take note though that notifiers declared in the POM cannot be edited or deleted through Continuum. It must be removed by hand in the POM and checked in to the source repository.

In the case of some open source projects (like Maven for example), a notifications mailing list specific for build notifications is set up and a mail notifier is configured in the project's parent POM to send build notifications to that mailing list. So whoever would like to be notified of the builds can just subscribe to that list and there is no need to add specific email addresses in the build server's notifier configuration.

The Build results

We already had a peek at the build results in our discussion on build definitions. Now let's go back to the Centrepoint Data Store (Flat File) project. Click the Builds tab. You should see a list of all the build results from building the project in the previous section. Click the Result link (first column from the right) of the build whose State shows FAILURE. We can see that it contains information about the build (how it was triggered, the duration of the build, and such), the changes in SCM and project dependencies, the build definition used, generated reports, and the build output (which can also be downloaded).

Apache Maven 2 Effective Implementation

One other important piece of information to take note of is the generated reports. As we can see, one of these reports is the Surefire Reports.

Apache Maven 2 Effective Implementation

As we can see from the screenshot above, Surefire Reports is divided into three sections. The first is the Summary, which contains the summary of the executed tests. It is similar to what we see at the end of the test phase when we build a project from the command line. The second section is the Package List. This contains the packages and test classes that were executed during the build. It also includes the number of test cases that passed, failed, or were in error. The last section is Test Cases, which is a list of all the test methods that were executed, including the cause (or causes) of the error or failure.

Surefire Reports is handy when there are test failures during the build. It is easy to identify which test case(s) failed, as the reports are broken down to this level.

Dependency changes

Continuum builds the project when there are changes in its dependencies. These dependencies must be projects that are also in the Continuum instance and is usually evident in inter-dependent modules. Project dependencies are tracked from the Maven POM, and this can be seen from the project information page.

Let's go back again to our Centrepoint Data Store (Flat File) project. Looking at the pom.xml of the Centrepoint Web Application project, we can see that it has a dependency on Centrepoint Data Store (Flat File).


Given this scenario, when the Centrepoint Data Store (Flat File) is build is triggered from the schedule, Continuum will see that the Centrepoint Web Application project has a dependency on it. If Continuum detects any SCM changes when it updated the working copy of Centrepoint Data Store (Flat File), then it will also build Centrepoint Web Application even if it is not attached to the same schedule.

One thing to take note of regarding dependency changes is that this only happens for scheduled builds. If the build is explicitly triggered (forced), then Continuum will only build that project and not the dependent projects.

Installations and build environments

In company settings, different projects have different build environments. Some projects require a specific version of Java to be used while other projects need additional environment variables to be set in order for them to be built. Because of this, it is better to have different environments where we can build and test our projects to ensure that they are platform independent and can be built on these environments.

To address this need, Continuum has installations and build environments.


Installations or builders are tools or environment variable settings, which can be configured if some projects require a different or specifi c tool apart from the default tools installed in the server. An installation may be a tool, such as Java or Maven, or it can even be an environment variable setting such as MAVEN_OPTS.

Let's say we want to increase the memory allocation for Maven when building our example application. This can be achieved by setting the MAVEN_OPTS environment variable before building the project. Now, we only want that to be used when building our example application and not when building other projects in Continuum. What we can do in this case is create a build environment in Continuum where the MAVEN_OPTS environment variable is set.

In the navigation menu, click on Installations and add a new one. Create an Environment Variable type installation. Fill in the form as follows:

Apache Maven 2 Effective Implementation

The Name field is just a name for the installation used by Continuum as reference. The Environment Variable Name is the actual environment variable we want to set and the Value/Path is the value we want to use for the environment variable. As for the checkbox, ticking that box means a Build Environment (which we will discuss in the next section) with a similar installation name will automatically be created.

Now click Save to create the Continuum installation.

Build environments

We can define multiple installations in a build environment. The purpose of this is so that we can simulate and configure all the different variables that compose or affect the environment. For example, we want to make sure that our project builds using certain Maven versions.

Now lets create a build environment for our project where we will use the MAVEN_OPTS installation we created in the previous section.

Click Build Environments from the navigation menu and add a new one. Fill in the Build Environment form as follows:

Apache Maven 2 Effective Implementation

To configure our MAVEN_OPTS installation to the build environment, just select MAVEN_OPTS and click the Add button. Then click the Save button to create the build environment.

We can use this to build our example application. Let's go back to the Project Group Summary page of Centrepoint and go to the Build Definitions tab. Edit the default build definition and set Centrepoint Default Build Environment as the Build Environment.

Apache Maven 2 Effective Implementation

Save the changes and click the build icon (third column from the left) of our default build definition. We can check the build result and see from the Build Definition Used that the build environment we have just configured was used.


In this article, we have learned the proper way of setting up and using Continuum to our best advantage.

We have learned what build definitions are, how to schedule a build in Continuum, how to set up notification, and how to configure and use build environments.

You've been reading an excerpt of:

Apache Maven 2 Effective Implementation

Explore Title