August 3, 2011

Building Android projects with Jenkins, Ant and Mercurial

I have recently set up a Jenkins build server for my Android projects hosted on Bitbucket. It’s not difficult but there are a couple pitfalls and the information on how to do this isn’t available from one single place so I decided to document the process and put up the information over here. Maybe other people will benefit from having a step-by-step guide too.


I'm using Bitbucket to store my projects so I'm going to use Mercurial for source control. I want to use SSH for authentication. It's a bit more of a hassle to set up but I don't like to store my Bitbucket credentials in Jenkins.

Right now I'm using the generated ant build scripts. I might switch to Gradle or Maven in the future so stay tuned for updates.

These are the versions I used for this guide:

  • Ubuntu Server 11.04 Natty Narwhal (I love typing these names)
  • Mercurial 1.7.5
  • Jenkins 1.423
  • Java OpenJDK version 1.6.0_22

Preparation

I’m assuming you already have a fully functional machine with a Debian flavored OS like Ubuntu. If you want to use another Unix need to replace all the apt-stuff with the package manager of your choice.

First let’s get our system up to date and install a couple of prerequisites.

apt-get update
apt-get upgrade
apt-get install openjdk-6-jdk ant mercurial

If you’re running on a 64-bit system you will also want to install ia32-libs to enable the Android SDK to run in 32-bit mode.

apt-get install ia32-libs

The Android SDK

Now we've got that over with lets get started for real. First we need to decide where we want to put the Android SDK files. I chose /opt/ But you can put it anywhere you want. Lets download and extract the files we're going to need there

cd /opt
wget http://dl.google.com/android/android-sdk_r12-linux_x86.tgz
tar xvfz android-sdk_r12-linux_x86.tgz

This will download and extract all the files to /opt/android-sdk-linux-x86.

The last thing we need to do is to update the sdk. This will make it download all the files it needs to actually build stuff. It's easy to get confused here because normally you'd do this with the GUI the nice people at Google built for us. But when you're logged in to your build server through a terminal like me this won't work. Luckilly it's easy to update the SDK from the command line.

/opt/android-sdk/tools/android update sdk -u -f

This will just download all the available packages. The -u switch keeps the SDK from trying to show any UI. -f forces it to overwrite any previously downloaded stuff if there is a newer version available. Remember to do this whenever there are new versions of Android available.

Now go make some tea. This will take a while.

Setting up Jenkins

The next step is to set up Jenkins. This is a bit easier because Jenkins is available as a .deb package. You can add the Jenkins repository to your sources and then install it.

echo deb http://pkg.jenkins-ci.org/debian binary/ > /etc/apt/sources.list.d/jenkins.list
apt-get update
apt-get install jenkins

You now have Jenkins running on port 8080 on your server. Unfortunately Jenkins is wide open after you install it. Let's set up some password security first.

Go to http://:8080 with your favorite browser and select Manage Jenkins/Configure System Select Enable Security Go to Select Security Realm and select Jenkins's own user database Now click Save at the bottom of the screen.

Now you can add some users who have access to Jenkins. Select Manage Jenkins again, now go to Manage Users to do this. The link to add a user is hidden on the left side of the screen.

After you've finished adding users you have to go back to the Configure System screen and select how you want to authorize users. For Authorization select one of the last three choices depending on how much control you want over what users can do.

Source control

Now lets see if we can get Jenkins to get our project from Bitbucket. First we need to install the Mercurial plugin. Go to Manage Jenkins / Manage Plugins and install the Mercurial Plugin on the Available tab. If this tab is empty refresh the plugins on the Advanced tab.

Now we're going to set up ssh authentication. Jenkins has set up it's own account on the server so we're going to create a keypair for that account and add it to Bitbucket with the right authorizations. That way Jenkins can login to Bitbucket and clone our repository. You're probably still logged in to the command line of your buildserver. Create the keypair like this:

sudo su - jenkins
cd
ssh-keygen -t
less ~/.ssh/id_rsa.pub

Just use the default path for the keys and press enter when you're asked for a passphrase. The last command lists the public key Jenkins will use to access your repository. Copy this key go to the account settings on your bitbucket webpage, look up the box with SSH keys in the title, paste in your key and click Add key. That's all there is to it.

Now we should be able to clone our repository. Make sure you're still logged in as the Jenkins account in your terminal and type:

hg clone ssh://hg@bitbucket.org//

You'll probably be asked if you want to add the bitbucket key to the list of known hosts. Type yes and go on, Mercurial should now get your complete project for you.

Configuring the build

Point your browser to your Jenkins page again. Log in and select New Job. Type the job name for your build and select Build a free-style software project. And press Ok

Select Mercurial for source code management and type

ssh://hg@bitbucket.org//
for your repository URL. Set the branch to default and you're good to go. No need to enter passwords because we set up SSH earier. Click Save and test out if Jenkins is able to clone your repository.

Now all we have left to do is to tell Jenkins how to build our project and we're done. We do this by adding a build step on the build configuration page. Just click Add build stepand choose Invoke Ant

You can now add build targets for Ant. For this example you can use clean and release to make a release build. If your build.xml file isn't right at the root of your project you need to click Advanced and tell Jenkins where to find it relative to your project root.

All we need to do now is tell Ant where it can find the Android SDK. We do this by adding an environment variable in the properties field.

sdk.dir=/opt/android-sdk
and we're done.

1 comment:

  1. Can you tell me, please, what is your dir structure on Mercurial? What kind of files are you having there?

    ReplyDelete