React Native Developer Series: iOS and Android Fastlane Setup and Certificates

Written by: madelyn

This is Part Two in a four-part developer series by Evan Glazer.

Series Abstract

Finishing the application build processes is normally very slow for many organizations, particularly with mobile platforms that need to use very specific criteria. In this developer series, building an application in React Native won’t be our primary goal; building processes that give us the ability to build, utilize CI/CD mechanisms through a pipeline and deploy (CD) to different environment types for testing and publishing to the app stores in React Native will be the main theme. It will be imperative that we start by outlining the tools and technology we will need to follow in this part. It’s fair to say that React Native is a fast-moving framework and most of the blog posts I have read seemed outdated and lead me down some unnecessary rabbit holes. This post will in time also become outdated, so be aware these instructions were helpful as of:

  • Fastlane 2.137.0

  • React Native 0.59

  • Expo SDK 35

  • XCode 11.0

In part one, we began by setting up our project to read from environment variables and initialized our project with GitHub. We will continue to work through increasing the functionality to inevitably be able to move from a static type of build to a dynamic build process, increasing the build numbers automatically for the application version. We will work toward being able to deploy from our local computer using Fastlane in this article before we introduce remote tools to automate the process with triggers. The following architecture will allow us to take care of development and production environments, which will enable us to push to the app store and beta/test-flight on the iOS and Android stores.

Fastlane Time!

An open source platform aimed at simplifying Android and iOS deployment. fastlane lets you automate every aspect of your development and release workflow.

Fastlane contains numerous tools, but we’ll just be using match, gym, pilot, supply and fastlane itself. To install run the following gem from the command line:

gem install match gym pilot supply fastlane

iOS Implementation

Here we have our bundle identifier as com.version.control and semantic versioning labeled as 1.0.0(1), but this will be different for your specific application to launch to the app store (please change accordingly).

We need to set the Code Signing Identity under Build Settings to the correct identities. For Debug, set it to iOS Developer and Release set it to iOS Distribution.

Fastlane Lanes

Make sure you cd into the iOS folder (cd ios). fastlane init Helping run through the options, I chose to have Fastlane automate some of the files for iOS app store distribution by selecting option #3 – Automate App Store distribution. It will then ask you to add your Apple ID developer credentials after it has obtained your available schemes and app identifier that we just set. After supplying our App Store credentials, it will update the bundle, and then we’re ready to see what was generated. You can also have it generate the application on the store if you don’t want to manually create that later. Let’s cd into our ios directory and then fastlane folder and we should see our Appfile and Fastfile. The Appfile includes information about the ios application:

app_identifier("com.version.control") 

The Fastfile includes information about the build process and what each “lane” will accomplish:

default_platform(:ios)

And now if we try the command fastlane release on the project to test that things are uploading correctly, we should see something like the following:

Development Time!

Let's focus on Code Signing.

When deploying an app to the App Store, a beta testing service or even installing it on a single device, most development teams have separate code signing identities for every member. This results in dozens of profiles including a lot of duplicates. You have to manually renew and download the latest set of provisioning profiles every time you add a new device or a certificate expires. Additionally, this requires spending a lot of time setting up a new machine that will build your app. We’re going to utilize Fastlane's match to create one central repository for the application. Let's start by creating a new Apple ID for the team (e.g. ios-dev@company.com) and use that from now on.

Now we will do match init and begin to provision our certificates

You can continue by adding the certificates for Production by using match appstore and Development by using match development. When you’re finished running those commands, your GitHub repo should look like the following:

We’re getting close but first a re-visit to XCode because now we’ve got those provisioning profiles from match, we need to tell XCode about them as we had turned off Xcode’s ability to automatically manage signing. Select your project target and under the general section select your match AppStore provisioning profile. Now that we have match setup we can begin to alter our lanes so that when we can build with the latest certificates. We will add match to our production (release) and development (beta) lanes. Updates to Fastfile:

default_platform(:ios)

Android Configuration

Before we implement Fastlane into our Android project, it is imperative that we set up our keystore so we can publish to the Google Play Store. We can start by changing directory into our android/app folder by running cd android/app from our project directory. Then we will utilize Keytool; which will help us generate our keystore file – you will want to answer all the questions the tool generates:

keytool -genkey -v -keystore release-key.keystore -alias version-control-alias -keyalg RSA -keysize 2048 -validity 10000

Now we can add to our gradle.properties file the keystore file, alias, and password; which will be used in our android config for signing. Note: you may need to modify these variables if you had used different key names, etc.

gradle.properties:
RELEASE_STORE_FILE=release-key.keystore

Now, let's go to our android config in our build.gradle and modify our signingConfigs.

android {
compileSdkVersion safeExtGet("compileSdkVersion", 28)

compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}

defaultConfig {
applicationId 'com.version.control'
minSdkVersion safeExtGet("minSdkVersion", 21)
targetSdkVersion safeExtGet("targetSdkVersion", 28)
versionCode 1
versionName '1.0.0'

multiDexEnabled true
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
// Deprecated. Used by net.openid:appauth
manifestPlaceholders = [
'appAuthRedirectScheme': 'host.exp.exponent'
]
}
dexOptions {
javaMaxHeapSize System.getenv("DISABLE_DEX_MAX_HEAP") ? null : "8g"
}

signingConfigs {
debug {
storeFile file('../debug.keystore')
}
release {
storeFile file(RELEASE_STORE_FILE)
storePassword RELEASE_STORE_PASSWORD
keyAlias RELEASE_KEY_ALIAS
keyPassword RELEASE_STORE_PASSWORD
}
}
buildTypes {
debug {
debuggable true
ext.enableCrashlytics = false
}
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
consumerProguardFiles 'proguard-rules.pro'
signingConfig signingConfigs.release
}
}

Now let’s make sure we can build our project and assemble the release. First, we need to run expo publish to generate release type configuration files Lets go back into our android directory (cd android) and run ./gradlew assembleRelease. Or you can check by going back into our android project on android studio and change the build variant to release and build and run the application. This should give us a result as below:

Your APK will appear in the android/app/build/outputs/apk folder.

Android Fastlane Time!

First, we need to init fastlane in our android project to create our lanes, etc. It will ask for you to set up Fastlane Supply, but skip this for now as we will set this up in the next steps.

cd android fastlane init

This will create two files: Fastfile in the android directory:

default_platform(:android)

platform :android do

desc "Submit a new Beta Build to Crashlytics Beta"
lane :beta do
gradle(task: "clean assembleDebug")
crashlytics
end

desc "Deploy a new version to the Google Play"
lane :deploy do
gradle(task: "clean assembleRelease")
upload_to_play_store
end
end

Appfile in the Android directory:

# json_key_file()

Time to build and submit to the store!

Supply uploads app metadata, screenshots, binaries and app bundles to Google Play. You can also select tracks for builds and promote builds to production. Before we begin to init supply, we need to set up the JSON key which allows the automation to upload to the store as it creates a key with the role to be able to submit to the store, etc. Setup consists of setting up your Google Developers Service Account: Tip: If you see Google Play Console or Google Developer Console in your local language, add &hl=en at the end of the URL (before any #…) to switch to English.

  • Open the Google Play Console

  • Click the Settings menu entry, followed by API access

  • Click the CREATE SERVICE ACCOUNT button

  • Follow the Google Developers Console link in the dialog, which opens a new tab window: Click the CREATE SERVICE ACCOUNT button at the top of the Google Developers Console

  • Provide a Service account name

  • Click Select a role and choose Service Accounts > Service Account User

  • Check the Furnish a new private key checkbox

  • Make sure JSON is selected as the Key type

  • Click SAVE to close the dialog

  • Make a note of the file name of the JSON file downloaded to your computer

  • Back on the Google Play Console, click DONE to close the dialog

  • Click on Grant Access for the newly added service account

  • Choose Release Manager (or alternatively Project Lead) from the Role dropdown. (Note that choosing Release Manager grants access to the production track and all other tracks. Choosing Project Lead grants access to update all tracks except the production track.)

  • Click ADD USER to close the dialog

Now that we got our JSON Key, we can run fastlane supply init and follow the command prompts. Now we can modify our Fastlane file to have two lanes: Release and Beta; which will tie into the Production track and Beta track in google release management.

default_platform(:android)

What’s Next?

At this point, we have accomplished a method to maintain profiles, certificates, etc. We created two lanes that build the application and uploads to the app store or test flight. However, we’re missing the in-between things that need to happen per build – such as adding increment build numbers and commit the build files to GitHub. In the next parts of this series, we will introduce processes for iOS or Android to implement CI Tools into Fastlane and deploy using AWS to host our pipeline.

Stay up-to-date with the latest insights

Sign up today for the CloudBees newsletter and get our latest and greatest how-to’s and developer insights, product updates and company news!