In this post I’d like to highlight various features in Bamboo that were developed separately during the past year or so. If you combine these little pieces together you can make your Bamboo to be a powerful friend in DVCS-oriented software development. This time I’ll focus mostly on doing CI on dev branches and merging. Next time I’ll cover areas like test failures, quarantining, and a bit about JIRA.
One of the main purposes of Bamboo is to build your code, run the tests against it and notify you about any errors or breakages. I believe it has even industry name: “Continuous Integration.” Technically, it’s something you could hack up easily using home-made scripts and a piece of duct-tape. However, Bamboo lets you manage the build, test and notify process in a friendly fashion, allowing you to easily navigate to the broken tests or view build logs or easily browse build history. You don’t need to manually check all that stuff by manually examining test result xml’s, or SSH into build machines to view the logs. Instead, you can use your favourite web browser to see all that data in a single site. In the not-so-hypothetical case I’ve committed a code that breaks existing test it could look like this:
As you can see in the above picture, Bamboo helps to determine who has broken things (“Changes by Piotr Stefaniak” – uh oh, that’s me), how severe the breakage is (“New test failures: 1″ – phew, not so bad), and what is breaking (“WhenConnectingSshUsingKeyfileAuthTest.testDefaultSshCommandConnectivity” – ah right, I’ve forgot to update the unit tests from that class, mea culpa). I can fix that easily in the next commit.
So far nothing stunning yet. So, let’s get to more interesting things you can do with Bamboo.
Consider a situation where you are a developer working in a moderate-size team in a moderate-size project that is quite covered with automatic tests. Let’s assume that there are multiple developers working simultaneously on the same codebase. I’m pretty sure that in such an environment it would be possible that multiple developers check in the faulty code at the same time, which later results in the test breakage (or build error). And if these people don’t fix the broken stuff quickly, prolonging the situation, it might affect also other developers negatively – like for example they will introduce invisible breakages/bugs that will not reveal themselves until the initial problem is fixed. Or the broken tests will block cutting the release. That sort of thing – in any case, some people will have to wait for other people to fix the stuff. Not a very optimal situation, is it?
One possible counter-measure is to use branches. With modern DVCS’ like Git or Mercurial, branching has become a fast and cheap operation. So some developers might want to utilize branches to separate their work from the other developers. That way if one developer checks in faulty code (breaking the test, or even breaking the whole build) it won’t disturb the rest of the team. The developer will be able to fix their stuff on the branch, and when all the test are green again they can merge the branch upstream and start another branch for the next task. As long as you’re not using branching-by-fork in your team, Bamboo will detect new branches in your repository and will automatically run the tests against them. You can even make Bamboo link JIRA issues to the relevant builds if you’re using branches for features:
However, a careful reader might notice that in the above scheme there is a gap. When there are multiple developers working on separate branches, it might be possible that these separate branches will stay ‘green’ when tested separately. But when you merge all of them together, some tests are failing (because changes from branch A affected the changes from branch B, and even worse: these two affected the tests added in branch C). If you would do these merges manually, without dry-running the tests, you would inevitably break your upstream build, ending in the same situation I’ve described above: some people would have to wait for you to fix your stuff. Can you avoid that?
Fortunately, yes. If your code base is stored in the single repository, you can configure your Bamboo to dry-run the tests before pushing the merge into the repository. So whenever a new check-in occurs on the branch, Bamboo will take the code from the branch and try to merge it against upstream branch (without committing!) and run the test plan against the dry-merged result:
That way you can avoid surprises when performing the manual merge in future. If your branch has drifted too much from the main code (and for example has broken some tests merged in from another, finished branch) then you will be aware of that fact with your next branch build. And you can fix the stuff before merging, thus making your fellow developers’ life a little bit less miserable.
Furthermore, as manual merging might occasionally lead to a situation where two developers merge their branches simultaneously (thus making some code hit the upstream branch without being dry-run tested), you can use Bamboo to perform the merge automatically at build time, and push the merge back to the repo only if the build runs successfully.
If the developer thinks the work is done on the branch (and for example the code has passed successfully the review process), they can log into Bamboo and run a customized build. If the branch merges cleanly with the upstream and there no test failures, Bamboo will push the merge at the end of the build. This makes it completely possible to avoid merging branches to the upstream untested… for a price: if there is a situation that multiple developers run the customized builds simultaneously (wishing their branches to be auto-merged to the upstream), one of them will be rejected and will have to re-run the branch. No magic here. As you can see, that technique should be beneficial for the teams where branch merges occur maybe several times in a day. On the other hand, if you need to merge branches several times per hour and need all of them to reach the upstream as soon as possible, then this technique will be a shot in the foot, especially if your test suite runs very long (extended run time increases the probability that two people will want to merge their stuff during the one run cycle).
Branch updater (Level = hard)
Currently Bamboo runs the builds on your branch when there is a new commit on **that branch**. This preserves some resource power, and comes from presumption that the breakages in the merged code (dev branch + upstream branch) are usually caused by the faulty code on the branch, not on the code from upstream. However, you may be worried about the drift between the feature branches and the upstream branch. So you might wish that, whenever new code is pushed to the upstream branch, it should be somehow tested with the dev branches. That way you could avoid a surprise where a stale branch (no commits for a few days/weeks) which was ‘green’ becomes silently so divergent from the upstream, that you cannot merge it back any longer without putting additional work. Or you might wish that whenever a new commit arrives on the upstream branch, your branch is dry-run tested again against the upstream’s head revision.
While you won’t find instructions for this in Bamboo’s help docs (ahem), you can trick it a bit to get things working. The trick is to add a duplicate repository in your plan configuration that will point to the same upstream branch:
Together with automatic branch detection and the gatekeeper strategy, this makes a powerful tool for keeping your development branches merge-able with the upstream. Whenever you come to the office in the morning you will know if your branch has become stale during night (for example due to the fact that developers from another time zone have committed changes to the upstream breaking your new stuff). (Not that this ever happens to us.) For even more resource preservation, you can even pick exactly which branches should have this special treatment. Maybe not all of your branches should be monitored for staleness, as some of them are a 20% project or something of similar non-importance.
The downside is that Bamboo will – unsurprisingly – start to report duplicate commits for your plans. Not very convenient, but on the other hand not very harmful. Your choice.
That’s plenty for now. I’ll be back soon with more tips for using Bamboo to it’s full potential on a DVCS team!
ps: If you haven’t upgraded to the latest version yet, or tried Bamboo at all, download it here.