Bamboo: Automatic merging of Plastic SCM branches
Atlassian's Bamboo is one of the most popular Continuous Integration servers, used by big enterprises and small startups alike. Of course, we released our own plugin to integrate Plastic SCM as a valid repository source in Bamboo quite a long time; however, you might have noticed that it didn't support an interesting Bamboo feature: automatic branch merging.
Well, not anymore. Since our release 220.127.116.117, we've extended our Bamboo plugin and adapted our client core to provide this option! But don't leave just yet. We'll show you a quick example of how to allow Bamboo to automatically merge your Plastic SCM branches, using our lightning-fast Plastic SCM Merge Machine behind the scenes.
Setting up Bamboo
First of all, you'll need your Bamboo server with our plugin installed. You can find it at our downloads page. In case you need some help to get it installed, please take a look at our installation instructions page.
You'll need at least a project with a plan having Plastic SCM as a source repository. In my example, I've set up a local Plastic SCM server and I'll be using a new repository called quakecode. As you can see in my Bamboo dashboard, I've created a project called "QuakeCode" with a single plan named "Quake1". This plan is configured to track my /main branch in the quakecode repo.
Once you have the initial setup, you'll need to configure your plan to include some branches. Since here at Codice we're very fond of task-driven development, I've imported the Quake III code into my main branch and I've performed a simple change in a task branch. This is how my repository looks like right now:
Let's make Bamboo acknowledge this. Open your plan configuration panel and click the "Branches" tab.
This section allows you to set the default values for all tracked branches, which might help you save time if you have a defined repository strategy. In our example, we'll skip this screen to focus on manual branch configuration. If you click on the "Create plan branch" button you'll be prompted with a creation dialog.
You can see that my branch is automatically detected, so I activated the checkbox next to it to select it. I also checked the "Enable branches" option to start the Bamboo automatic processing. Click "Create" and your plan will track your new branch.
You'll also need to configure the automatic merging. It's pretty much the reason why we're here, isn't it? ;) Open the plan configuration screen again and select your new branch plan in the menu on the left. Select the "Branch merging enabled" checkbox to display the automatic merging options.
- The Branch Updater keeps track of a given parent branch. If there are changes in it after a successful build of your tracked (child) branch, Bamboo will automatically perform a merge operation from the parent to check whether the changes of your tracked branch are still compatible with it. You're also given the option to commit that merge into the repository (provided that no conflicting changes appear during merge, of course!).
- The Gatekeeper works the other way round: after each successful build, your tracked branch changes will be merged into the parent branch. This will detect if your task branch will need manual interaction before being integrated. You can automatically commit the successful merges, too.
We encourage you to read the full description at the Bamboo documentation site!
Branch Updater strategy
We'll start trying the Branch Updater strategy, as marked on the previous screenshot. This can be useful in task-driven development, since the main branch is guaranteed to be operative at all times. So, let's enable the "Merge result" checkbox and click save!
You can see that the first detected changeset in my branch didn't trigger a merge. That's because there were no changes in /main after I created the branch.
I'll change the quake project directory structure a bit in main.
(Do you notice something about this screenshot? Yes! It's our GTK client!)
Checking in those changes will advance my /main branch, like this:
This won't trigger any actions in Bamboo, though. Remember: automatic merging strategies will only apply after new changes are detected in the tracked branch. Keep working, then! I'll implement those nice (and imaginary) features listed in my task enclosure.
That should be enough for Bamboo to work its magic. Wait a minute and... Bam! There you are!
Let's have a look at the results page. You can see that Bamboo checked out changeset number 4, executed the defined test suite (a dummy ls execution in my case, since we're not focusing on that) and then merged the latest changeset from /main! The results were checked in at changeset 5, branch /main/task001. This is how my Branch Explorer looks like now:
This is a wonderful way to keep your task branch updated if there are frequent changes in its parent. Of course, as with any other new detected changeset, Bamboo will run you test targets on the merge result changeset:
No further merge was required this time, either.
"Ok, but wait a second; what if there are conflicting changes in /main?", you might say. Don't worry! Bamboo will detect that the merge operation didn't have a clean result and you'll be notified. I've set up a conflict scenario: the last changesets in /main and /main/task001 on the following Branch Explorer screenshot contain a change at the same line in my /ui/menudef.h file.
Let's see what Bamboo says...
Not bad at all! The Plastic SCM Merge Machine detected merge conflicts which couldn't be automatically resolved and returned a failure code. I'll need to solve that myself :'(
Let's hope that Bamboo likes it!
Again, no further merge required. So, this is the basic use of a Branch Updater merging strategy. Of course, you could deactivate the automatic merge commits, too. It would warn you when the changes detected in the tracked branch parent are no longer compatible with your task.
Let's take a look at the other automatic merging strategy: the Gatekeeper.
As we said, it pursues the opposite target: keep a parent branch updated with the detected changesets in the tracked branch. This might not be the best idea if you're using task-driven development, since it may pollute your main branch with changeset which don't pass the tests; but leaving the automatic checking of merges disabled may serve as a warning of incompatible code.
Let's test this. I've created a feature branch, called /main/fixes-1.0:
Remember, since I didn't enable the automatic branch tracking, I need to create a new plan for this branch manually from the plan configuration panel:
I already had a plan for /main/task001, so I left it unchecked. We need to set the merge options, too:
I can merge my previous task, /main/task001, into main. The feature branch won't be modified, so Bamboo won't apply any automatic merge.
I'll check in a couple changesets in my /main/fixes-1.0 branch.
When Bamboo detects them, it'll try to merge them into /main. Let's have a look at the results:
As the "Pushed" line reads, changesets from /main/fixes-1.0 have been merged into /main. This is the resulting Branch Explorer diagram:
Of course, if any conflicting file had been detected during that merge we would have seen an error result page. Just like under a Branch Updater strategy.
You can see that this behavior introduces changes into the /main branch without human supervision, make it unsuitable for a standard task-driven development process. However, if you disable the automatic check-in after Bamboo merges, integration masters might find it interesting to keep track of future integration conflicts.
We've shown you the basics of what Bamboo automatic merging offers. It can be a powerful tool for project managers and integration masters to control build errors and attack problems before they appear.
We're pretty happy to release this new functionality in our plugin, and we'll hope you'll do, too! We'd love to hear your opinions about it, so don't hesitate to leave a comment on our blog, post your thoughts on our forum, or write us a tweet if you prefer!