Start Building for Free
CircleCI.comAcademyBlogCommunitySupport

Deploy Android applications

8 months ago6 min read
Cloud
Server v3.x
On This Page

In this how-to guide, you will learn how to automatically deploy your Android app through CircleCI with Fastlane.

Introduction

To complete this tutorial, you will need the following:

  • An Android project, built using Gradle.

  • Your Android project set up in CircleCI. If this is your first time setting up a project in CircleCI, refer to our Quickstart guide for a walkthrough.

  • Fastlane installed and granted access to Google Play Store using credentials from your Google Developers service account. You may follow the instructions to install, set up, and configure Fastlane supply in the Fastlane Android setup documentation.

This tutorial also walks you through how to use the Android orb for deployment. You are not required to be familiar with the Android orb for this tutorial, but we recommend reading the Orb introduction page if you have not used CircleCI orbs before. Alternatively, this tutorial also shows you how to deploy your project without using the orb.

1. Configure Fastlane for deployment to Google Play Store

To configure Fastlane for deployment, you will need to configure tasks and update the Play Store lane.

a. Configure tasks

Navigate to your fastlane directory and open Fastfile. This file is used to configure the tasks you can execute with Fastlane. If you open the file, you will observe four different blocks:

  • before_all: This is where you specify instructions to be performed before a lane is executed.

  • lane: This is where you define an actual task you want to perform, such as deploying to the Play Store. You can define as many lanes as you want.

  • after_all: This block is called when the executed lane was successful.

  • error: This block will be called if an error occurs in any of the other blocks.

b. Update Google Play Store lane

The Fastfile already comes with a playstore lane that generates a release build and deploys it to the Play Store. You will modify this lane. In the Fastfile, update the playstore lane like so:

lane :playstore do
    gradle(task: "bundle")
    upload_to_play_store(
      track: 'internal',
      release_status: 'draft'
    )
  end

This lane will run gradle bundle and generate an app-release.aab (Android App Bundle), and then deploy the bundle to the internal track of your project in the Google Play Console.

2. Prepare your app for deployment

To prepare your app for deployment, you will need to add a release signing configuration to your app-module build.gradle file. This enables Fastlane to use the same keystore you used in generating earlier releases of your app to also generate subsequent releases.

a. Add signingConfigs snippet

Add the following signingConfigs snippet to your app-module build.gradle file:

android {
  signingConfigs {
        release {
            keyAlias keyStoreProperties['releaseKeyAlias']
            keyPassword keyStoreProperties['releaseKeyPassword']
            storeFile file(keyStoreProperties['releaseKeyStore'])
            storePassword keyStoreProperties['releaseStorePassword']
        }
      }
    ...
  }

b. Update buildTypes

Update the buildTypes section of your build.gradle file:

buildTypes {
    release {
        signingConfig signingConfigs.release
        ...
    }
}

With this, you have configured the app to use a specific keystore. Next, you will create functions in your build.gradle file to help you generate build numbers for your app versions.

c. Add snippet before Android section

Add the following snippet just before the android section of your app-module build.gradle file:

ext.versionMajor = 1
ext.versionMinor = 0
ext.versionPatch = 1
ext.versionClassifier = null
ext.isSnapShot = false
ext.minSdkVersion = 21

private Integer generateVersionCode() {
    return ext.minSdkVersion * 10000000 + ext.versionMajor * 10000 +
            ext.versionMinor * 100 + ext.versionPatch
}

private String generateVersionName() {
    String versionName = "${ext.versionMajor}.${ext.versionMinor}.${ext.versionPatch}"

    if (ext.versionClassifier == null) {
        if (ext.isSnapShot) {
            ext.versionClassifier = "SNAPSHOT"
        }
    }

    if (ext.versionClassifier != null) {
        versionName += "-" + ext.versionClassifer
    }

    return versionName
}

In this snippet, you added variables that hold your app version values. You then added two methods, generateVersionCode and generateVersionName to generate the version code and version name based on how the app version value changes. This helps to give your app a unique and progressive way of generating your version code when you modify your app versions.

Note that you will need to update at least one parameter of the version for every deployment. Fastlane fails if a version code is reused.

d. Update properties in defaultConfig

Update the following properties in the defaultConfig section of the build.gradle file:

defaultConfig {
    versionName generateVersionName()
    versionCode generateVersionCode()
    // ... Leave others as is

}

Now your Android app is able to be bundled and deployed on your local machine.

3. Set up CircleCI deployment

To set up CircleCI deployment, you will need to take a few security measures.

a. Convert your keystore to base64

You need to convert your keystore to base64 to safely access it in CircleCI. You can do this conversion in the terminal using the following command:

$ base64 your_key_store

Save the output somewhere easily accessible for the next step.

b. Set environment variables

Next, you need to set environment variables for deployment through CircleCI.

Open your Android project in the CircleCI web app and select Project Settings. Navigate to Environment Variables and add the following variables:

  • $BASE64_KEYSTORE - Your base64 keystore, generated in the previous step

  • $GOOGLE_PLAY_KEY - The contents of your api.json file, generated from the Fastlane install before starting this tutorial

  • $RELEASE_KEY_ALIAS - Your key alias

  • $RELEASE_KEY_PASSWORD - Your key password

  • $RELEASE_STORE_PASSWORD - Your keystore password

c. Import keystore properties

Add the following snippet to your build.gradle file. This allows you to import your keystore properties from a keystore.properties that will be generated at runtime.

def keyStorePropertiesFile = rootProject.file("keystore.properties")
def keyStoreProperties = new Properties()
keyStoreProperties.load(new FileInputStream(keyStorePropertiesFile))

android {
...
}

Now, you need to configure .circleci/config.yml to decrypt your keystore, generate keystore.properties, and create the Google Play API key at runtime.

If you have not already done so, create a .circleci folder in the root of your project repository. Inside the .circleci folder, create a config.yml file.

4. Set up your configuration

You can set up your configuration with the Android orb, or without the Android orb.

a. Set up configuration with the Android orb

Using the Android orb gives you two options for deploying to the Google Play Store. You can either use the deploy-to-play-store job from the orb, or run each command individually in a job.

b. Set up configuration without the Android orb

If you would prefer to not use the Android orb, you can follow the configuration directions below.

  1. Decrypt keystore from base64

    Add the following command to your deployment job in .circleci/config.yml to decrypt your keystore from the base64 environment variable set earlier ($BASE64_KEYSTORE).

    run:
      name: Decode Android key store
      command: echo $BASE64_KEYSTORE | base64 -d | tee keystore android/app/keystore > /dev/null
  2. Generate a keystore.properties file

    Next, you need to generate a keystore.properties file in order to publish your work to the Google Play Store.

    To do so, you need to create another environment variable named $RELEASE_KEYSTORE, that points to the location of the decrypted keystore.

    Add the following command to your deployment job:

    run:
      name: Create keystore.properties
      command: cd android && printf 'releaseKeyAlias=%s\nreleaseKeyPassword=%s\nreleaseKeyStore=%s\nreleaseStorePassword=%s' \
      $RELEASE_KEY_ALIAS $RELEASE_KEY_PASSWORD $RELEASE_KEYSTORE $RELEASE_STORE_PASSWORD > keystore.properties
  3. Create Google Play API key

    Finally, you need to create your Google Play API key from your api.json You have already saved the value with an environment variable $GOOGLE_PLAY_KEY, so you can refer to this variable and write the api.json file at runtime, instead of uploading it to a remote repository.

    Add the following command to the job:

    run:
      name: Create Google Play key
      command: echo $GOOGLE_PLAY_KEY > google-play-key.json
  4. Deploy your app

    To now deploy your app, you need to add your Fastlane steps. To do this you only need to add a command that runs fastlane my_deployment_lane; in this case, the command looks like this:

    run: fastlane playstore

    Fastlane recommends using Bundler in this step. If you choose to use Bundler, you will need to add another step to install Bundler:

    run: sudo gem install fastlane

    Then, replace the run: fastlane playstore step with run: bundle exec fastlane playstore.

Next steps


Suggest an edit to this page

Make a contribution
Learn how to contribute