Submitted by rtyler on Mon, 2010-04-12 06:00
At the first Bay Area Hackathon in mid-2009, the topic du jour was "pre-tested commits." As potential implementations of the concept were discussed over burgers from Brickhouse in downtown San Francisco, we realized as a group a few things: first, those burgers were delicious, but more importantly: pre-testing commits is very-SCM dependent and involves a lot of moving parts. One of the positive changes that came out shortly after the meet up was the support for "Concurrent Builds", allowing a job to be executed concurrently on different slaves, a precursor to pre-tested commit support. Fervor for the pre-tested commit feature lowered as time went on, the feature being too dependent on the SCM itself was generally accepted as the reasoning behind the feature languishing.
Chances are the feature is in fact too large for Hudson to support alone. It requires Hudson, the SCM and likely a third tool to work in concert together to perform such a feat.
With Git, and the phenomenal code review tool Gerrit, and the Gerrit plugin by intrepid plugin developer, Jyrki Puttonen, pre-tested commits with Hudson, Git and Gerrit are possible.
After Hudson got some major publicity at PyCon Atlanta 2010 I haven't been as quick as I would have liked with Python-related posts and tutorials. I use Hudson to build and test a number of pure Python modules and C extensions across numerous Python versions (covering 2.4 - 3.1). For most beginners, or those simply looking to get started with Python on Hudson, starting with my job configurations is too much at once, so instead I wanted to start at the "beginning" so to speak.
The trouble with getting people started with Hudson, given how simple and visual it is to use, is that articles with sample configurations are not particularly useful; a screencast however is a good medium for visually walking somebody through Hudson. The screencast below (also on YouTube) is the first in a series of screencasts I'll be doing, not only for Python on Hudson, but for Hudson overall.
In this post I'll show a very basic tips on how to compile an Android project using Hudson. Specifically how I use Hudson to create release versions of my apps.
Debug vs Release
I'm assuming that you are using Eclipse with the ADT plugin. During development you can test your app on the emulator or a device and resources like R.java and aidl files are compiled for you automatically by the plugin. When it's time to release your app, you'll need to go through some steps:
- You must sign your app using a certificate
- You must update your AndroidManifest.xml to remove the android:debuggable attribute
- Replace your Google Maps API debug key with the one belonging to your release certificate (if you are using a MapView)
- Generate an apk package for the release and test it on a device or emulator
It would be nice to automate a few of these steps, and this is where Hudson comes in.
Automated builds: Ant
For automated builds the Android SDK uses Apache Ant, which Hudson has great support for. To generate a template build.xml you can use the android tool from the SDK using the following command:
android create project -n template -t android-7 -p template -k dummy.pkg -a Dummy
The target is specified as "android-7" meaning that we are building for Android 2.1. For apps that use MapView we would use "Google Inc.:Google APIs:7". It is a good idea to always target the latest SDK. From this template project we'll grab the build.properties and the build.xml and copy those to the Android project that we want to build. Edit build.xml and set the project name to your Android project name.
The local.properties file contains the path to the SDK root and shouldn't be checked in to version control. For our use we'll set the properties that are in that file on the Hudson job configuration page.
Running the build in Hudson
This part is easy: create a new freestyle job and let it be build with ant. The targets that we want to execute are
clean release. Release will compile, package and sign your apk. Now to get this working right, some custom properties should be set (use the Advanced button).
target=Google Inc.:Google APIs:7
The sdk.dir should point to the Android SDK root on your Hudson node. In my case I'm running Hudson locally on my machine. The target property refers to the SDK we want to use as mentioned earlier. The *key.** properties are related to signing of the apk. My strategy is to have a separate key store and private key for each application that I develop. I also check that keystore in to SVN. I also archive the **-release.apk* artifact so that I can download the latest release apk directly from Hudson. After completing these steps, you should be able to build your Android app with Hudson.
Updating the AndroidManifest for release
...But we're not done yet :) Remember what I said about updating the AndroidManifest.xml? For that we need to edit the build.xml, which by default contains nothing more then a
tag to pull in the Android SDK ant target definitions. For my Rainy Days application, I adjusted build.xml like this:
Removing debug attribute from AndroidManifest.xml
Setting release maps key
What the above snippet does is removing the android:debuggable attribute from the AndroidManifest.xml and replacing the maps API key in res/layout/maplayout.xml with the correct key for release. The
-package-resources target is pulled in from the Android android_rules.xml file.
Now when Hudson builds my app I get a ready to release apk that I can install on my device or emulator, which is pretty nice.
There is are some issues with this approach however. As you might have noticed:
- Replacements are done in the workspace, we are not really building exactly what's in svn
- Each new build should start out fresh for that reason, for example by using the svn revert option.
Additionally I can not yet tag the release version with the updated files, because the subversion tagging plugin doesn't support this by design. This could be worked around by adding svn statements in the build.xml however. For now I don't really mind as I make minor changes to the resource files, but I'll be looking at improving this situation.
Things to add: unit testing, coverage...
One thing that I'd really like to add is unit testing. This is a little bit more complicated though, since unit tests require a running emulator and a running emulator requires a gui. The Hudson Xvnc plugin could be very helpful here.
The Android build scripts for test projects already include EMMA output, it shouldn't be to hard to use the Hudson plugin for that.
When Hudson is running on a local machine, the Batch task plugin can automate installing the apk on a device to automate things further.
Building Android applications with Hudson is not that hard, since the builds are based on Ant. By hooking in to the standard Android build targets it's easy to update files like AndroidManifest.xml which in turn makes sure the release process is controlled and predictable.
Android unit tests depend on the emulator which is a little bit more challenging to set up, but Hudson already has some plugins available to make this easier.
Editor's Note: Hugo Visser is the developer of Rainy Days and Engine Watch for Android. You can
follow him on Twitter and on his blog.