In a previous post, I spoke about how to use Robolectric to unit test Android applications without having to resort to the emulator. In this post, I’ll detail setting up Atlassian Bamboo to run continuous integration of an Android application.
What is Bamboo?
For those of you who don’t know, Atlassian Bamboo is a Continuous Integration system. Many people have probably heard of Confluence (think internal wiki and collaboration software), Stash (think BitBucket) or JIRA (issue tracking software). These three systems are widely used in Enterprise software development shops and many businesses in general.
To me, Bamboo is a vital key in the software development process. Combining Bamboo with JIRA and Stash provides some really great features, such as creating task branches directly from your issue tracking software, seeing what issues were resolved with a commit, and being able to track released versions with all of their fixes detailed in a nice changelog.
When performing Android development, I needed to get Bamboo building my projects. Doing so involved two separate pieces:
- Installing the Android SDK so that Bamboo had access to it.
- Configuring Bamboo to build the actual project.
Note that I’m assuming that you already have a JDK installed on the server, and that you’ve already installed Bamboo.
Installing the Android SDK
This task was fairly straight-forward. First, I had to download the actual Android SDK from Google’s website. This meant visiting the Android SDK website, and then clicking on View all downloads and sizes. I just wanted the SDK tools, not the ADT bundle, so I selected the android-sdk_r23.0.2-linux.tgz package which was about 140 MB in size (note that when you read this, the SDK may be several versions more advanced – your mileage, therefore, may vary).
Once downloaded, I copied it up to my server, and expanded it in a place where all users of the server could access it:
sudo mkdir /opt/android cd /opt/android sudo tar xvzf ~thomas/android-sdk_r23.0.2-linux.tgz
This expanded the SDK to the following directory:
I then fired up the SDK manager to install the necessary components. First though, I had to log out, and then SSH with X-11 forwarding turned on so that I could see the GUI it provides (note that you can do everything without the GUI using the
--no-ui option for the
android update sdk command):
ssh -X 10.0.0.60
Next, I actually ran the
android tool as root:
However, this resulted in an error message:
Exception in thread "main" java.lang.UnsatisfiedLinkError: no swt-pi-gtk-3550 or swt-pi-gtk in swt.library.path, java.library.path or the jar file at org.eclipse.swt.internal.Library.loadLibrary(Unknown Source) at org.eclipse.swt.internal.Library.loadLibrary(Unknown Source) at org.eclipse.swt.internal.gtk.OS.(Unknown Source) at org.eclipse.swt.internal.Converter.wcsToMbcs(Unknown Source) at org.eclipse.swt.internal.Converter.wcsToMbcs(Unknown Source) at org.eclipse.swt.widgets.Display.(Unknown Source) at com.android.sdkmanager.Main.showSdkManagerWindow(Main.java:402) at com.android.sdkmanager.Main.doAction(Main.java:390) at com.android.sdkmanager.Main.run(Main.java:150) at com.android.sdkmanager.Main.main(Main.java:116)
The quickest way to solve this problem (as discussed here), was to install the
sudo apt-get update sudo apt-get install sudo apt-get install libswt-gtk-3-java
I then re-ran the SDK manager:
And got the normal SDK manager window up. I then proceeded to install the components I needed as usual:
The next step was to configure Bamboo to actually perform the build. I went ahead and created a new Plan for my code repository. When configuring the tasks, I left the default Stage in place. Under the default stage, I left the default Source Code Checkout task in place, but added a new task to perform the build. Because I was using Gradle, I created a Script task:
The script task required only two pieces of information. For the actual script, I used the Gradle wrapper that I had checked into source code control, and used the
build target (
./gradlew build). In addition to that, I had to tell the script where the Android SDK was located. For that, I created an environment variable called
ANDROID_HOME and set it to where the SDK was located. Here is a screenshot of the configured task:
When I first ran the build, I was surprised that no test results were being reported, even though the
build target in the Gradle wrapper runs the actual unit tests. I realized I needed to use a JUnit Parser task to parse the test results. All that was needed for that was to specify the directory where the results of the unit tests would be located. I did that with a simple ANT-style path:
Here is a screenshot of the configured JUnit Parser task:
With that complete, I triggered a manual build, and checked the test results tab to make sure everything ran:
83 tests run, all successful. Excellent!
As you can see, it is fairly straightforward to get simple unit testing going on Bamboo with the Android SDK. This assumes of course, that you don’t actually need the emulator, and are using a package such as Robolectric. In a future post, I’ll talk about some more of the challenges of developing a CI strategy with the Android SDK, and how to solve them.