ALL ARTICLES
SHARE

React Native Android Deploys using Fastlane and CircleCI

Robert Amarante
Development
20 min read
React Native Android Deploys using Fastlane and CircleCI

In this article, we will guide you toward a solid automatic Android deployment solution leveraging React Native, Fastlane, and CircleCI. React Native offers an intuitive and responsive user interface and allows us to create apps for multiple platforms from the same code base. Fastlane provides developers with a full set of tools and actions to speed up and automate the mobile release process. Finally, CircleCI completes the solution by seamlessly adding continuous integration into the solution, making the build process simple, automatic, and repeatable. 

Before Setting Up

There are a number of prerequisite steps that must be completed before we can officially begin setting up our solution. Before going any further we need:

  • Someone with an admin role in the google play console who can generate the service account and obtain the play-store-credentials.json. To obtain this file, follow these steps.
  • An app created on Google Play. Follow these steps to create one, if you have not already done so.
  • An environment with Fastlane setup and all the necessary android dependencies installed.
  • Access to the release.keystore file (usually as a good practice this file is in the .gitignore). We’ll show you later how to set the value of this file in an environment variable as well as create the release.keystore via CircleCI. 
  • Permission to use external Orbs in CircleCI

Fastlane Configuration

Go to your Android folder and initiate Fastlane

Getting started with Fastlane is pretty simple. In your android folder, use bash to initiate Fastlane with the following line of code.

Next, follow these steps: 

1. The package-name can be found in the android/app/build.gradle file as applicationId:

Note: If you are using a different applicationId, depending on the flavor of Android being built, you can just set the default one at this point. We’ll cover how to submit multiple flavors later in this article.

2. For the step asking the ‘Path to the JSON secret file’, paste the following: ./Fastlane/playstore-credentials.json.

3. When asked to ‘Download existing metadata and setup metadata management?’, type ‘N’, unless you want to download the metadata. We will not cover that topic in this post, but if downloading the metadata, be sure to remember to add it to the .gitignore file. See this example for more information. Once finished, add your `play-store-credentials.json` to the Fastlane folder that was just created. Then, add this file to the .gitignore file, as we don’t want to have this in our repo.

android/fastlane/play-store-credentials.json

 

Lane Setup

Next, we are going to set up two lanes for automated deployment, one for staging, and another for production. A laneis a group of instructions to be executed in a particular order, similar to a function in JavaScript. Feel free to add as many lanes as desired for your deployment. The process is largely the same for each lane.

Go to your Fastfile (fastlane/Fastfile) and remove all the content inside platform :android do, the remaining file should look like this:

Now, let’s create some lanes! All of them should be created within platform :android doand the end statement.

Staging Lane

 First, we’re going to create a lane called ‘Staging’. It is always best practice to provide a description before the lane definition. 

Inside this staging, add the ‘gradle’ instructions to create the build.

Gradlerequires, which can bundleor assemble. We are going to choose the bundle option. The flavor for our example will be, and the build type will be Debugor Release. Since we are planning to submit to the store, it makes sense to create a Release.

In the next line, add the `upload_to_play_store` command to submit the build to Google Play Store.

Upload_to_play_store requires a track, which can be any of the tracks available on the Google Play Store. For the sake of simplicity, we are using the internaltrack to submit staging builds. Package_nameis optional if you are not using flavors.

If you want to run this command on your machine, it is recommended to do a clean before generating a new build, so add this at the beginning of the staging lane.

When done, your Fastfile should look something like this: 

Production Lane

Creating a lane is largely the same process, regardless of function or purpose. To create a ‘production’ lane, only a few changes need to be made. All you have to do is change the lane name to :production and thepackage_name if you are using flavors. 

CircleCI Config

To introduce continuous integration into our solution, we are going to leverage CircleCI, and more specifically, CircleCI Orbs to improve our deployment solution. An orb is a reusable snippet of code that helps to automate repeated processes, accelerate project setup, and integrate 3rd party tools. CircleCI provides an open registry of published Orbs, making it easy to find and leverage an Orb that suits your needs.  

Looking for React Native Development Experts?
See how our experts can help you
SCHEDULE A MEETING

For our deployment, we will be leveraging the react-native-community’s orb, allowing us to outsource the environment configuration and maintenance. This orb also includes tools for testing, but we will not be using those for this deployment. If interested in end-to-end testing, see this post for more info.

First, create a CircleCI Config.yaml file. 

Add the version, orbs dependencies, then create 3 keywords in that file. Indentation is very important in this file.

Make sure you use the latest version of the Orb!

To verify you have a valid config.yml file, you can run the circleci orb validate .circleci/config.ymlcommand in your root folder.

In the orbs section, we are defining a dependency named ‘rn’, (this alias is used to reference all the predefined tasks in this orb but can be changed to anything you want).

The commandssection is a place to define reusable instructions, typically used by the jobs.

Jobsare detailed sets of instructions to be run in workflows.

Workflowis a place where we can set rules and the order in which jobs are run, for example, ensuring a job is run on a specific branch, or creating dependencies between jobs (such as not running fastlane deployments if tests are failing).

With the above in mind, let’s add some useful commands to our commandssection.

The above install_packages command is used to do a yarn install, and any other operations related to the node_modules.

Create_android_key_files will be used to create the release.keystore and the play-store-credentials.json mentioned earlier in the article.

The create_env_file will be used to generate the .env file, you can ignore this if you are not using env config.

Finally, we have the install_fastlane command, which provides instructions to install the latest fastlane version.

Now, we are ready to use these commands to create the jobs:


Checkout_code uses CircleCI’s checkout command

Create_staging_env_file uses the code>create_env_file command to generate the .env file with staging-specific environment variables.

Create_production_env_file uses the create_env_file command to generate the .env file with production-specific environment variables.

As you might guess from the name, code_testing runs tests on the app.

Fastlane_android_release installs fastlane, and runs a specific lane. Be aware that resource_class: large is being used in this example. If your build can use a less demanding resource class, go for it. Learn more about resource_classes here.  The gradle_options and java_options defined in this job are there to allow the build creation to use more ram and avoid errors when generating the build.

Once these jobs are configured, all we need to do to complete our config.yml file is to define the workflow.

In this example, we’ve created a flatirons_example workflow, where code_testing needs to be successful in order to create the .env files that will later be used by the fastlane command when creating the build.

Using the filtersproperty, you can assign jobs to run on only specific branches.

The requiresparameter allows us to avoid running jobs if another one fails.

Additionally, with the namekey, more legible names can be displayed in the CircleCI dashboard.

CircleCI Environment Variables

As the last stage of our deployment, we will be configuring CircleCI, along with all the necessary environment variables. 

First, let’s go ahead and configure CircleCI by following these instructions.

As we have already created our .circleci/config.yml in the previous steps, we will now select the ‘Fastest: Use the .circleci/config.yml in my repo’ option.

In this example, we have two environment variables that will be used in the app (API_URL_STAGING, and API_URL_PRODUCTION), and others used by the config.yml (ANDROID_ENCRYPTED_KEY_STORE, and GOOGLE_PLAY_SERVICES_UPLOAD_KEY).

API_URL_STAGING and API_URL_PRODUCTION act as the URL for your API depending on the environment. To set these environment variables in CircleCI follow these instructions.

Before we do the same with ANDROID_ENCRYPTED_KEY_STORE and GOOGLE_PLAY_SERVICES_UPLOAD_KEY, we need to obtain the values for them.

To obtain these values, we are going to do a simple base64 encryption to get the file content as a string. Let’s start with the android release.keystore. Run the following command: 

Copy the content of this file, then add it as the ANDROID_ENCRYPTED_KEY_STOREenvironment variable in CircleCI, and delete the file.

Now, do the same with your play-store-credentials.json file.

Copy the content of this file, add it as the GOOGLE_PLAY_SERVICES_UPLOAD_KEY environment variable in CircleCI, and delete the file.

If you want to verify that the encrypted string is the same as within the file, you can decrypt the string, and check that files are the same by using this command:

If “Files do not match” is printed within the console, it means the string content was not correctly input. If nothing is printed, then the string content has been validated.

At this point, you should be able to do an automatic release when merging changes into the staging branch. But there is a major issue, all builds are being submitted with the same versionCode, this can generate conflict and in the majority of cases, the build will not be submitted.

To prevent this issue, in the android/app/build.gradle above the android section, define this function:

Set your versionCode to use this function:

And our deployment solution is good to go!

As a bonus, let’s show you how to have this environment set to send a slack message when the build is successfully created. By adding slackafter upload_to_play_store, and running the following command, a notification will be pushed to Slack upon completion of any build: 

And that’s it, you’ve just configured Fastlane and CircleCI, and can now sit down, relax, drink some coffee, read a book, or whatever floats your boat, until notified by Slack that your build has been completed!

Here you can check a complete guide to React Native and for working with React Native developers.

React Native Development Experts

Flatirons provides React Native development services tailored for your business needs.

Schedule a Meeting

Get the CEO's Take

Handpicked tech insights and trends from our CEO.

E-mail

React Native Development Experts

Flatirons provides React Native development services tailored for your business needs.

Schedule a Meeting

Get the CEO's Take

Handpicked tech insights and trends from our CEO.

E-mail
Robert Amarante
More ideas.
Essentials of Digital Product Design
Business

Learn the Essentials of Digital Product Design

Flatirons

Nov 26, 2024
Ruby on Rails Alternatives
Development

10 Ruby on Rails Alternatives You Should Know About

Flatirons

Nov 20, 2024
Practice EHR Integration
Development

Streamline Your Healthcare Practice with EHR Integration

Flatirons

Nov 18, 2024
React Developer Salary
Development

Unlock Your Potential: React Developer Salary Guide

Flatirons

Nov 16, 2024
rails vs python
Development

Ruby on Rails vs Python: Key Differences

Flatirons

Nov 14, 2024
BCM
Development

Understanding Your Car’s BCM – Key Auto Insights

Flatirons

Nov 14, 2024
Essentials of Digital Product Design
Business

Learn the Essentials of Digital Product Design

Flatirons

Nov 26, 2024
Ruby on Rails Alternatives
Development

10 Ruby on Rails Alternatives You Should Know About

Flatirons

Nov 20, 2024
Practice EHR Integration
Development

Streamline Your Healthcare Practice with EHR Integration

Flatirons

Nov 18, 2024
React Developer Salary
Development

Unlock Your Potential: React Developer Salary Guide

Flatirons

Nov 16, 2024
rails vs python
Development

Ruby on Rails vs Python: Key Differences

Flatirons

Nov 14, 2024
BCM
Development

Understanding Your Car’s BCM – Key Auto Insights

Flatirons

Nov 14, 2024
Essentials of Digital Product Design
Business

Learn the Essentials of Digital Product Design

Flatirons

Nov 26, 2024
Ruby on Rails Alternatives
Development

10 Ruby on Rails Alternatives You Should Know About

Flatirons

Nov 20, 2024
Practice EHR Integration
Development

Streamline Your Healthcare Practice with EHR Integration

Flatirons

Nov 18, 2024
React Developer Salary
Development

Unlock Your Potential: React Developer Salary Guide

Flatirons

Nov 16, 2024
rails vs python
Development

Ruby on Rails vs Python: Key Differences

Flatirons

Nov 14, 2024
BCM
Development

Understanding Your Car’s BCM – Key Auto Insights

Flatirons

Nov 14, 2024
Essentials of Digital Product Design
Business

Learn the Essentials of Digital Product Design

Flatirons

Nov 26, 2024
Ruby on Rails Alternatives
Development

10 Ruby on Rails Alternatives You Should Know About

Flatirons

Nov 20, 2024
Practice EHR Integration
Development

Streamline Your Healthcare Practice with EHR Integration

Flatirons

Nov 18, 2024
React Developer Salary
Development

Unlock Your Potential: React Developer Salary Guide

Flatirons

Nov 16, 2024
rails vs python
Development

Ruby on Rails vs Python: Key Differences

Flatirons

Nov 14, 2024
BCM
Development

Understanding Your Car’s BCM – Key Auto Insights

Flatirons

Nov 14, 2024