So, everyone knows how Bamboo works brilliantly with Maven — it can build any Maven 1 or Maven 2 project out of the box, using just the metadata stored in the Maven’s project files. We use this capability of Bamboo to continuously build all of our Maven-based projects. You can see plenty of examples here, on http://bamboo.developer.atlassian.com
However, all of those builds depend on our Maven infrastructure, which has gotten pretty complicated over the years. We use Maven in all areas of our development and occasionally things go wrong: deployments are missed, artifacts go missing or servers go down.
So, I started thinking: what if we could use Bamboo to test the Maven infrastructure, instead of just depending on it? After a little brainstorming, it turns out that you can.
I’ve created eight new builds on http://bamboo.developer.atlassian.com.
Four builds (ARCH-CONF, ARCH-Jira, etc.) make sure that the current version of each product’s Plugin Archetype can be deployed. Nothing much special there — they just run the maven commands and make sure nothing breaks.
But the next four builds (ARCH-CONFCREATE, ARCH-JiraCREATE, etc.) are more interesting. My goal was to create a build that mimicked the environment of a brand new plugin developer’s virgin machine, and then use Maven to install all the necessary pieces. That means using the same settings.xml that we do, using a clean local repository, using the archetype to create a new plugin, and finally executing the maven commands to download all the dependencies and build the plugin. Any missing step or dependency must cause a build failure, and instantly alert us to the problem.
Luckily for me, Bamboo and Maven already supported all the things I needed.
Bash Script Builders in Bamboo
The first thing I had to figure out was how to get Bamboo to perform a discrete set of commands that represented what a user would do when setting up his environment for the first time, and didn’t necessarily come out of any existing build definition (maven, ant, etc).
Fortunately, Bamboo doesn’t need a project model, it has lots of different types of Builders. One of those Builders allows Bamboo to execute any arbitrary bash command. So I wrote a simple script to perform all the necessary actions. (Apologies in advance for my lame scripting skills.)
Cron-based Build Triggers in Bamboo
Normally, Bamboo builds are triggered by watching our subversion repository for changes. Any change to the code might cause a problem, so we run a build after each check-in. But in this case, the artifacts that might cause problems are not in our project, but they are resources out of the net. So we need to test every few hours to ensure that everything is working.
Bamboo allows you to specify arbitrary build times using cron. So I set our test builds to run every four hours (staggered by ten minutes, so they don’t overlap).
Local Maven Repository Override
Now we get down to the environment. In normal Bamboo operations, the Bamboo user maintains it’s own local maven repository; it defaults to the user’s home directory and is shared by all of the user’s maven processes. This way, each build doesn’t have to download the same dependencies over and over. It saves a ton of time and bandwidth. However, in this case we want to test those downloads, and we can’t rely on an internal copy in case the live copy suddenly fails.
Fortunately, Maven allows you to override the local-repostory’s location on the command-line. So I specified a new directory, that was guaranteed to be empty every time the build runs.
mvn package -Dmaven.repo.local=/Users/nolen/build-dir/local-repository/
Maven Settings.xml Override
The Maven settings.xml specifies a lot of crucial information about the build environment. We have a public settings.xml for plugin developers, and a private settings.xml for Atlassian developers. Generally, the Bamboo user uses the private settings.xml, but here I needed to ensure that this build used the default, public settings.xml, the same one we ask all plugin developers to use.
Just as it does for the repository, Maven allows you to override the location of the settings.xml on the command-line. In the script, we download the most up-to-date copy of the settings.xml, and then make sure that all mvn commands use it, by specifying it in the command-line.
As in the last example:
mvn -s /Users/nolen/build-dir/settings.xml package -Dmaven.repo.local=/Users/nolen/build-dir/local-repository/
The last step in the puzzle was making sure that Bamboo recognized when my script experienced an error. Bamboo judges the success of any build based on whether the
process returns ‘0’. Fortunately, bash has this built-in as well. Just set the -e flag in the script, and the script will terminate with an error when any of it’s constituent commands fail.
Put all those pieces together and you end up with a fully-automated system to make sure that our complicated and many-facted Maven infrastructure alwaysplays nice. Hopefully this system will alert us to new problems almost as soon as they occur, and lead to a more reliable build experience for people inside and outside of Atlassian.
And always remember, check your settings.xml.