This post introduces a Maven plugin for easily building native PhoneGap apps for iOS, Android, WP7 (and more) from any WAR project, in any environment. It assumes that you are familiar with using Maven and have a WAR project you wish to build. In return, when you run your build you'll get native binaries automatically built then installed/deployed to your repository. Best of all because it's all part of your standard Maven build, your CI server can handle your one-click release builds signed with your distribution keys ready for app store distribution.

Introduction

PhoneGap Build is a hosted service which wraps HTML5 applications into native applications. The plugin connects to the service, uploads the exploded WAR directory, waits for the builds to complete and then downloads the native binaries installing/deploying them as attached artifacts.

Building your first native app

First of all you're going to need to visit the PhoneGap Build website and sign up for an Adobe account (GitHub doesn't work with the API unfortunately). Test out your shiny new credentials by running the following command from a terminal -

mvn com.github.chrisprice:phonegap-build-maven-plugin:list -Dphonegap-build.username=[USERNAME] -Dphonegap-build.password=[PASSWORD]

If everything works as planned then you should see all your applications and keys that are currently hosted on the service (empty that is, if you just signed up!). If there's a problem then double check the command and also check that your credentials work on the website.

Including the plugin in your project

Now for something more exciting! You'll need to make two additions to your project, firstly to configure maven to use the plugin during the build lifecycle, and secondly to customise how PhoneGap Build should wrap your application. Start by adding the following to the project>build>plugins section of your POM -

<plugin>
	<groupId>com.github.chrisprice</groupId>
	<artifactId>phonegap-build-maven-plugin</artifactId>
	<version>0.0.2</version>
	<executions>
		<execution>
			<id>phonegap-build</id>
			<!-- the goals are lifecycle bound by default -->
			<goals>
				<goal>clean</goal>
				<goal>build</goal>
			</goals>
			<configuration>
				<platforms>
					<platform>android</platform>
				</platforms>
			</configuration>
		</execution>
	</executions>
</plugin>

Now create a file called config.xml in src/main/phonegap-build which contains a few key details about your application. The config.xml file also gives you fine control over the configuration of the PhoneGap wrappers, documented in detail here however, for now just copy the following -

<?xml version="1.0" encoding="UTF-8" ?>
    <widget xmlns="http://www.w3.org/ns/widgets" xmlns:gap="http://phonegap.com/ns/1.0"
        id="[GROUP-ID].[ARTIFACT-ID]" version="[VERSION]">
    <name>PhoneGap Build Sample</name>
    <description>
        A sample for phonegap-build-maven-plugin.
    </description>
    <author href="/blog/cprice/" email="cprice@scottlogic.co.uk">
        Chris Price
    </author>
</widget>

At the minimum you'll need to change GROUP-ID, ARTIFACT-ID and VERSION to correspond to the maven project co-ordinates, feel free to change the author etc. but it isn't required at this point.

Running the build

When you've made the changes to the config.xml, you should be able to run the following -

mvn clean install -Dphonegap-build.username=[USERNAME] -Dphonegap-build.password=[PASSWORD]

You should see your application being packaged locally and then uploaded to the service. After a short wait, the service needs some time to perform the actual build, the native Android apk file will be downloaded and installed in your local repository. Simples!

Multiple platforms

You now have an Android binary without having to mess around with the SDK or any PhoneGap project templates, impressive, but what about if we now get a requirement for a WP7 binary?

If we tweak the plugin configuration in your POM like so -

<platforms>
    <platform>android</platform>
    <platform>winphone</platform>
</platforms>

And re-run the command above -

mvn clean install -Dphonegap-build.username=[USERNAME] -Dphonegap-build.password=[PASSWORD]

You'll see not only an Android version downloaded and installed but sat alongside it is now a WP7 xap. Building for webOS (webos), BlackBerry (blackberry) and Symbian (symbian) follows exactly the same pattern. iOS (ios) requires a little more configuration, you need to supply your developer certificate and provisioning profile, but once configured a single Maven build can produce native binaries for all the major mobile platforms and install/deploy them straight into your repository.

Configuring the plugin to build for a platform will cause the build to fail if there is an error building for that platform so be sure to only include the ones you are interested in e.g. don't attempt to build for iOS without configuring your developer certificate and provisioning profile.

Storing your credentials somewhere more secure

One of the things you'll likely want to change if you start using the plugin in your project is how the service credentials are passed to the plugin. Passing them in on the command line is laborious and worse still very insecure. The best way to do this is to store them as a server in your settings.xml. This has the major advantage of allowing different developers to use their own credentials whilst still sharing the same project. It also allows the passwords to be encrypted if that floats your boat.

Signing your Android build for distribution

When it comes to distributing your application to the Play Store, the developer certificate that by default the service signs Android binaries with just isn't going to cut it. You'll need to follow a few steps to generate a self-signed (i.e. free!) private signing key and then configure the plugin to use it. This process is detailed on the plugin website.

Conclusion

This part covered configuring the plugin to build PhoneGap Android applications for development, and also signed distribution builds ready for the app store. In the next part I'll cover building applications for iOS (which is slightly trickier because you'll need to configure your developer certificate and provisioning profile).

Until then if you get stuck, please check-out the sample application or post an issue on the bug tracker, if you want to customise the Android PhoneGap wrapper be sure to revisit the config.xml settings and if you want to skip ahead, there's also more detailed documentation on the plugin site, including instructions for building for iOS.