Sunday, May 27, 2012

Automatic Android App Builds with Github, Travis and Ant

Continuous integration is awesome.  Android is okay, I guess.  Both together is pretty darn cool.

If you're using a version control system, which you should be, you may be interested in automatically building your project every time you push a change to your repository.  You can do this in a few ways - traditionally, you can host a Hudson or Jenkins instance on your local machine and set up a commit hook that tells your CI instance that it's time to go make a build.  Your CI bot will then go fetch the source from your new commit and build it, then report the results to you.  However, then the build is still using your PC's resources, so there's not that much benefit (especially if someone somewhere else pushes to your repository with the correct commit hook unexpectedly).  If you have your own server somewhere, you can use that, problem solved...

Not all of us do, though - and for that there are a few sites that will host for you.  One is CloudBees (which I have not used and will not talk about), and the other is Travis, which I did use, and will talk about.

Travis is tightly integrated with GitHub, and doesn't expose a buildbot like Hudson or Jenkins.  It doesn't expose its service hooks, either, so as far as I can tell, it doesn't support hooking into repositories that aren't hosted on GitHub - if you want to use it, you need to mirror your source to GitHub.

That said, it is incredibly easy to use with GitHub.  Simply sign in with your GitHub credentials on the Travis website - in your account properties you can "switch on" projects that you want Travis to build on commit.

Travis uses a single descriptor YAML file named .travis.yml in the root directory of your repository to execute the build.  Your .travis.yml defines which language Travis should use to build, where, and which pre- and post-build steps to take.  A list of supported languages can be found on the Travis documentation here.

In the case of Android projects, Travis does not come with the Android SDK, so you need to download the SDK and the correct Android release libraries yourself in the prebuild by specifying a before_script.

before_script:
    - sudo wget -q http://dl.google.com/android/android-sdk_r18-linux.tgz
    - sudo tar xzvf android-sdk_r18-linux.tgz > /dev/null
    - sudo android-sdk-linux/tools/android -s update sdk --filter android-7,platform-tool --no-ui
    - sudo android-sdk-linux/tools/android -s update project --path ./FridgeMagnet --target "android-7"
    - sudo android-sdk-linux/tools/android -s update test-project --path ./FridgeMagnetTest -m ../FridgeMagnet
I'm building my project based on Android 2.1, so I am downloading android-7 (Android 2.1).  android update takes an ID to determine which packages to download - you can see a list of the correct IDs for each available package using android list sdk and specify which packages to download using the --filter argument.  platform-tool is needed to build with ant.  android update project sets up the ant build.xml for each project - needed for the next step. In some cases,  you may find that the permissions in your Travis environment are limiting, so I use a big hammer and simply add:
- sudo chmod -R 777 ./*
at the bottom of my before_script.

Travis downloads source to a non-persistent environment with every push, so it is necessary to download the SDKs every time.  This is the suggested method.

Next we want to actually build, using ant.  You can specifiy your build script under script: in your .travis.yml.  In the most simple case you can simply specify:
script:
- cd ./FridgeMagnet
- ant clean
- ant debug
If you have more than one project build, you can use a bash script as your script: action instead of specifying each action in the .travis.yml - otherwise if one project build fails, Travis will stop the build process completely.  You can then return the success status from your script so Travis knows whether your build ran correctly or not.
#!/bin/bash
FAILED=0
cd ./FridgeMagnet
ant clean
ant debug
if [ "$?" = 1 ]; then
echo "FridgeMagnet build failed!"
    FAILED=1
fi
cd ..
exit $FAILED
Now you should be able to see your builds on Travis as they are built under http://travis-ci.org/#!/githubusername/GitHubProjectName.

For an example, my project FridgeMagnet can be found on GitHub and Travis.

1 comment: