Changing Lanes - Mobile Development Deployment - Android
Stuck in the slow lane
Our process for buiding and releasing our application fell onto the shoulders of just one developer using one configured laptop. It wasn't until he went on holiday and we needed to update the application that we realised this had to change and change fast. This is when we found out about fastlane.
fastlane promises a collection of tools which allow for automating the building and releasing of android and iOS applications. Their actual quote was
fastlane lets you define and run your deployment pipelines for different environments. It helps you unify your app’s release process and automate the whole process. fastlane connects all fastlane tools and third party tools, like CocoaPods and Gradle.
At the time of writing, this isn't entirely true in our opinion. Android support is limited to pushing applications to the Google Play Store and managing the meta information i.e. screen shots, textual descriptions, app icons etc. With the announcement that fastlane is now part of the Fabric.io team the support might catch-up to the level of iOS.
Moving into the Fastlane
We decided to pick one of our Android mobile apps first as this seemed to be a quicker path to getting started with fastlane. We were already using Jenkins as our Continuous Integration Server and it has worked well for us so that was going to be the tool to run our builds.
fastlane requires, at the time of writing, Ruby 2.0.0 as a minimum so that needs to be installed. We decided to installed RVM (Ruby Version Manager) which allows us to have different Ruby environments so we can test newer versions of fastlane as they come out and isolate our working version set.
Jenkins
We already use Jenkins to build all our production code and so decided to stick with what we knew. We installed a new instance of Jenkins to isolate our existing builds. There is a Ruby gem for Jenkins and since Ruby is a requirement for fastlane, we used it.
Install Jenkins:
$sudo gem install jenkins-war
$sudo gem install Jenkins
This last install allows us to control Jenkins from the command line, specifically starting and stopping.
To run an instance of Jenkins which is then available on port 3001:
$jenkins server
Once it's running it creates a .jenkins folder in the current user's home directory to store its configuration files.
To run an instance of Jenkins as a daemon and also to stop it:
$jenkins server --daemon
$jenkins server -k
Our project is maintained in our source control server so we had to configure Jenkins to have access to it. We already had SSH keys for the Jenkins user so we just needed to configure Jenkins to use them.
We added our credentials under the Credentials -> Global credentials -> Add Credentials > Kind (SSH Username with private key).
Android SDK
This is included with the Android Studio application but since we were configuring our server which had no UI installed we downloaded the SDK separately on the command line and installed it.
If you're using Android Studio/SDK Manager checkout the official User Guide:
$wget http://dl.google.com/android/android-sdk_r24.4.1-linux.tgz
This link might be out of date now, so check the Android Downloads page.
Extract the goodness into the current users home directory:
$tar zxvf android-sdk_r24.4.1-linux.tgz
After installing we could then go and install the Android API, Build Tools & Platform Tools.
This gives you a list of all available packages to install:
$android list sdk --all
From the generated list you install packages via the following command:
$android update sdk -u -a -t <package_id>
We had to install amongst others:
-
Google APIs, Android API 23, revision 1
-
Local Maven repository for Support Libraries, revision 28
-
Android Support Library, revision 23.2.1
-
Google Play services, revision 29
-
Google Repository, revision 25
-
Google Play Licensing Library, revision 2
fastlane
Install fastlane with:
$sudo gem install fastlane -NW
To get started with fastlane you must first initialise a project to use it and then create some lanes to run.
Initialising a project is as simple as running the following in the root of your project:
$fastlane init
This will ask some questions about your project and if you want to set up certain things, which you can answer no to and set up later on.
For a full step by step setup refer to the fastlane documentation Getting started with fastlane for Android.
Lanes
- ionic_build_unsigned.sh
- ionic_build_signed.sh
- publish to Crashlytics
- publish to GooglePlay store
- send notification to our slack channel.
- build unsigned release
- build unsigned releases and publish to crashlytics and notify a slack channel
- build signed releases and publish to GooglePlay store and notify a slack channel
Our Fastfile looks like this
lane :build do
lane :crashlytics do
crashlytics(
groups: "*****",
apk_path: "platforms/android/build/outputs/apk/******.apk",
crashlytics_path: "etc/crashlytics-devtools.jar"
)
# Post Slack notification
slack(
channel: "hpi_trade_ci",
default_payloads: [],
message: "A new beta distributed of '******' for Android is now ready on http://fabric.io",
attachment_properties: {
thumb_url: 'https://raw.githubusercontent.com/fastlane/fastlane/master/fastlane/assets/fastlane.png'
}
)
end
# Build, Sign and Publish to Play Store
lane :play_alpha do
skip_upload_metadata: true,
skip_upload_images: true,
skip_upload_screenshots: true,
track: "alpha",
apk: "platforms/android/build/outputs/apk/******.apk"
)
slack(
channel: "******",
default_payloads: [],
message: "A new alpha distributed of ***** for Android is now ready on Google PlayStore https://play.google.com",
attachment_properties: {
thumb_url: 'https://raw.githubusercontent.com/fastlane/fastlane/master/fastlane/assets/fastlane.png'
}
)
end
Configuring Jenkins
Running the fastlane lanes in Jenkins is simply achieved by using the Jenkins 'Execute shell' build step.
We capture all the build artifacts which are built into the platforms/android/build/outputs/apk/ directory.
Clear Road Ahead
We have been running with fastlane for a while and it just takes away the pain of building, delivering and notifying people of new releases. We can concentrate on developing new features without having to break away to create builds. Not only have we rolled this out for our Android builds we have also rolled this out for our iOS builds too.