Fastlane + CircleCI for Android — Part 3

Chan Bo
Open Knowledge
Published in
5 min readMar 18, 2019

Since Part 2 we already finish Fastfile configuration for our example so next we are going to implement CircleCI config.yml file. We will use CircleCI to call Fastlane for build, test and deploy when it’s triggered built.

First thing we should consider is Why have we selected CircleCI as Continuous Integration? Well, actually there is not which CI tools betters than the others. For me, I choose CircleCI because it’s more compatible for me. So if you are likely to use another CI, it’s fine.

Getting Started

Now can start config CircleCI. Right click on root project and create .circleci/config.yml file.

We are ready to start. But first, let me show you how the configuration file will look like:

The file contains the CircleCI version , references , jobs and workflows . If you are not clear, you can look at Android Continuous Integration — CircleCI. Keep in mind that we are using CircleCI and Fastlane with this example. So this CircleCI configuration will have Fastlane inside that.

Unit Test

We will start by creating a job to run unitests.

First of all, the keys starting by * are references. You don’t need to worry about them now. I will show you how to implement them later.

As you can see, we are creating a job called test_unit , and inside that we are setting the Android environment ( *android_config ) and configuring each step. Let’s focus only on the steps for now.

  • checkout : As the name suggests, this will checkout your project source code into the job’s working direcoty.
  • *restore_gradle_cache : This step is very important for performance reasons. It will restore your gradle dependencies folders to avoid downloading them again.
  • *restore_gems_cache : Restores the folders containing gems dependencies so they can be reused.
  • *ruby_dependencies : Because we are using Fastlane so this step will take care of downloading all of its dependencies.
  • *android_dependencies : Downloads all the dependencies that are specified in your gradle file.
  • *save_gradle_cache : This will cache your gradle depencies.
  • *save_gems_cache : This is responsible to cache your gems dependencies.
  • Run unit tests : Run unit test using fastlane
  • store_artifacts : To store your test reports in the CircleCI artifacts.
  • store_test_results : This will store tests result in the CircleCI test results.

For *create_key_properties and *decode_android_key you will see it soon and I will explain it later.

Do you notice that we have $BUILD_FLAVOR and $BUILD_TYPE ? Both are CircleCI environment variable. We use these variable because we have 3 different Build Variants. So if we want to change build_flavor or build_type , we can switch on CircleCI server. To setup CircleCI environment variables:

  1. Go to JOBS or WORKFLOWS > click on setting icon on your project name

2. On BUILD SETTINGS section, click on Environment Variables > Add variable

Instrumentation tests

Now, we will implement a job to run the instrumentation tests remotely in the Firebase Test Lab.

As you might notice, both test_unit and test_instrumentation , steps where we use references are exactly the same.

  • Run instrumentation tests in Firebase Test Lab : This step uses fastlane to assemble your app and run tests in the Firebase TestLab. Then download the test result.
  • Send Debug and Release APK : After test_unit and test_instrumentation pass we can send debug and release apk to slack.
  • store_artifacts : Stores the test results downloaded from Firebase to CircleCI artifacts.

Beta

Now, we will add a new job to deploy app to Google Play Console with beta track.

Again all the environment configuration and the first steps are exactly the same. And we have only one different step ( Deploy to Play Store ) that assembles your app and deploys to Google Play Console with beta track.

Deploy to Playstore

Next, we will create a job to deploy app to Google Play Console with Production track.

With release_deployment job it is almost the same as beta_deployment job, the only different is it uses different lane in Fastlane.

References

References are very useful. They are simply blocks of configurations that we can reference and reuse.

Let’s take a look at the references used in our jobs.

Workspaces

To set up our environment, we firstly set our working directory using the workspace reference. Then, we specify what is the Docker image that we want to use, finally we configure some environment variables.

Use dump terminal to avoid weird output from Gradle.

Explicitly limit the JVM heap size to prevent your container from running out of memory. For free users, each container has 4GB memory available.

Depedencies

Despite that we are using Docker, we still need to download the specific dependencies of our Android Project and also Fastlane Dependencies.

So we create two references ruby_dependencies and android_dependencies , that are responsible for downloading Fastlane and Android dependencies. However, this process can be a little bit slow, so we need to find a strategy to cache our dependencies and use them between jobs and builds.

Cache

To create a cache mechanism for our dependencies, we need three things: define our cache key, restore the caches based on the cache keys and save the dependencies for each cache key.

For that we created two references: gradle_key and gems_key . The unique keys for gradle dependencies and gems. These keys will change every time we change our dependencies so the system can know if it should use the cached dependencies or download new ones.

Two references to restore the cache dependencies: restore_gradle_cache and restore_gems_cache . These references are responsible to get the dependencies from the cached folders if the cache keys remain the same.

And the save_gradle_cache and save_gems_cache references will store the folders of the downloaded dependencies if the cache keys changed.

Workflows

Workflows are another feature in CircleCI 2.0. It lets you run jobs in parallel, specify job dependencies, filter jobs, etc. You can look more detail here.

In the workflow above, we start by executing the job that runs our unit tests ( test_unit). Then we specify the test_instrumentation job that requires the test_unit job to finish running successfully.

If both of the jobs that run the tests terminate without errors, we still have another jobs. But they will only run when we push code to branch beta or master .

That’s all about .circleci/config.yml configurations. But remember we still have another references that I haven’t talk about are *create_keystore_properties and *decode_android_key . So I will show you in the next article. For full .circleci/config.yml , you can found here. If you have any question, please let me know! Thanks.

References

--

--