Installing Jenkins on an Ubuntu Amazon EC2 instance

Note: This post was written over four years ago and may no longer work correctly. This post will remain published for posterity.

This tutorial assumes you have already created an Amazon EC2 instance and are able to ssh to it. In our case, we used the Quick Launch Wizard to spin up a 32-bit instance of Ubuntu Server Cloud Guest 11.10 (Oneiric Ocelot).

Once you have a running EC2 instance you’ll need to modify the instance’s security group to open up ports 22, 80 and 443.

The first thing I did was update the EC2 timezone to our local timezone:

$ sudo ln -sf /usr/share/zoneinfo/America/Los_Angeles /etc/localtime

Install any version control systems you might like to use:

$ sudo apt-get install git

Then pretty much just follow the installation instructions from the Jenkins Wiki. I’ve copied the actual steps here for posterity.

Installing Jenkins:

$ wget -q -O - http://pkg.jenkins-ci.org/debian/jenkins-ci.org.key | sudo apt-key add -
$ sudo sh -c 'echo deb http://pkg.jenkins-ci.org/debian binary/ > /etc/apt/sources.list.d/jenkins.list'
$ sudo aptitude update
 
# Note this will install the openjdk dependencies automatically!
$ sudo aptitude install jenkins

Setting up an Apache Proxy for port 80 -> 8080:

$ sudo aptitude install apache2
$ sudo a2enmod proxy
$ sudo a2enmod proxy_http
$ sudo a2enmod vhost_alias
$ sudo a2dissite default
$ touch /etc/apache2/sites-available/jenkins

Use your favorite editor to update /etc/apache2/sites-available/jenkins with the following virtual host configuration:

<VirtualHost *:80>
	ServerAdmin webmaster@localhost
	ServerName ci.company.com
	ServerAlias ci
	ProxyRequests Off
	<Proxy *>
		Order deny,allow
		Allow from all
	</Proxy>
	ProxyPreserveHost on
	ProxyPass / http://localhost:8080/
</VirtualHost>

Enable the new jenkins virtual host and restart apache:

$ sudo a2ensite jenkins
$ sudo apache2ctl restart

Jenkins should now be live and accessible from port 80! Now you can begin configuring Jenkins to your liking. I’ll follow-up with a post highlighting our Jenkins configuration. For now, here are the plugins we’ve chosen to install:

  • Green Balls
  • Post build task
  • Instant Messaging Plugin
  • IRC Plugin
  • Rake plugin
  • Git Plugin
  • Github Plugin
  • GitHub API Plugin
  • Github OAuth Plugin

Android app build automation with Jenkins

In a nutshell, Jenkins provides an easy-to-use so-called continuous integration system, making it easier for developers to integrate changes to the project, and making it easier for users to obtain a fresh build.

This post assumes you have a working ci server running Jenkins (or Hudson).

First download and install the Android SDK to your Hudson server. Make sure it’s in a directory that’s accessible by your Hudson user.

$ sudo su hudson
$ cd ~/
$ curl -lO http://dl.google.com/android/android-sdk_r11-mac_x86.zip
$ unzip android-sdk_r11-mac_x86.zip

After unpacking the SDK you’ll need to install the individual Android platforms.

$ cd android-sdk-mac_x86/
$ android update sdk --no-ui

Now go get some coffee or take a smoke break, this is going to take a while.

Phew. Okay, now that’s done we can configure our new Hudson task. I’m going to assume you’re somewhat familiar with boot strapping a new project in Hudson, so I’m going to gloss over some of the details. Just make sure it’s pointed at your Android app’s source code repository.

In the build section of the project config you’ll want to specify a new “Execute Shell” build step with the following script.

# Ensure the SDK is in the Hudson user's system path
PATH=/Users/hudson/android-sdk-mac_x86/tools/:$PATH
 
# Change to the Hudson workspace directory
cd $WORKSPACE
 
# Create the required build files in the workspace
android --verbose update project --path .
 
# Execute the build
ant clean debug
 
# Copy the apk out of the workspace so your testers can get at your fresh build
scp bin/YourAppName-debug.apk foo:bar/

Pro Tip: Add this build script to your code repository and simply execute that script from Hudson. That way you can track your changes.

Note that if you’ve bundled extra libraries into your app you may see a build error when running this code. If so, try executing the ant build with the -lib option like so.

$ ant clean debug -lib foo/bar/libdir/

If you get into trouble, know that you can execute this build from the console as the Hudson user. Try running through the script manually first so you can identify any errors.

Update (2012-02-01): After living with this set up for a few months we started to run into some issues. It turns out, running your Ant builds from a shell script means Jenkins won’t always notice that your builds are failing. We also started running JUnit tests that, when a test failed, did not also trigger a build failure.

As a result we discovered that it was far better to run your Android builds using the Jenkin’s Ant Plugin. This allows you to invoke a series of Ant commands like clean debug or clean release. Jenkins will also format the Ant output and properly mark your build as failed or successful.

You can also take advantage of the Post Build Task plugin to run a script after your build is successful. This is useful for copying your .apk files elsewhere.

Don’t forget to run $ android update project --path . before your Ant commands are invoked, or your Android SDK folder may not be properly linked to your project.

Update (2012-09-06): The Android Emulator Plugin for Jenkins is a great tool that will help you manage the Android SDK on your CI server. It’s a far better option than installing the tools yourself. While you’re at it, you should check out the Android Lint Plugin to make sure your project is in tip-top shape.

Update (2012-03-02): I recently did a talk on Android build automation with Ant and Jenkins at the 2013 Snow-Mobile conference in Madison, Wisconsin. You can view the slides from the talk online at docs.google.com/presentation/d/19ddXSEVfd6-bGItNfROJMlL6O2rA1XOcRiBdE3NpgV4/edit?usp=sharing.