Automate React Native builds with GitHub Actions

Rémi Gallego
3 min readFeb 19, 2020

Without Fastlane or third-parties

Since 2019, GitHub supports CI/CD natively through its feature GitHub Actions. With its easy YAML configuration, huge community support and fair pricing, it has become a solution of choice for automating tests and deployments in Continuous Integration pipelines.

React Native does cooperate well with tools like Fastlane or Bitrise, which allows setting up near-zero-configuration CI/CD pipelines without too much hassle, but we can see that using GitHub for DevOps needs will help to reduce both decentralization and friction points, by focusing our whole mobile development workflow into one single platform.

Setting up our first CI job

First of all we need to create our .github/workflows/ folder which will serve as the point of entry for our CI jobs. For our first workflow file ci.yml we can keep it simple for now and create a job install-and-test that will install npm dependencies and run all tests against our React Native project every time we push to master.

name: Build Android and iOSon:
push:
branches:
- master
jobs:
install-and-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install npm dependencies
run: |
npm install
- name: Run tests
run: |
npm test

And that's it! Right in the Actions tab on our project repository, the job will be run at every push, making sure we get a screen score at every step of the process.

Automating the Android build

Android release builds are signed with a keychain, so in order to make a release build with our CI setup, we need to pass a password to our signing logic before we try to compile our Android build. This is done through Secrets, a feature that we can use to store our keychain password that we will call KEYSTORE_PASSWORD and pass it on to our job.

Here we append our second job, that needs the first job install-and-test to execute and pass before wasting time trying to build it.

build-android:
needs: install-and-test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install npm dependencies
run: |
npm install
- name: Build Android Release
run: |
cd android && ./gradlew assembleRelease -PMYAPP_UPLOAD_STORE_PASSWORD='${{ secrets.KEYSTORE_PASSWORD }}' -PMYAPP_UPLOAD_KEY_PASSWORD='${{ secrets.KEYSTORE_PASSWORD }}'
- name: Upload Artifact
uses: actions/upload-artifact@v1
with:
name: app-release.apk
path: android/app/build/outputs/apk/release/

The last part of that job will simply upload the generated apk file so it is retrieved through the GitHub interface!

Automating the iOS build

In order to make managing code signing and certificate easier, it is recommended to use a self-hosted runner that already manages our certificates and provisioning profiles. Other solutions might include using Fastlane or encrypting our signing files ourselves like in this article.

Creating an iOS build requires slightly different steps that Android too, as we need to install pod dependencies first.

The script below will output an ad-hoc build.

build-ios:
needs: install-and-test
runs-on: [self-hosted, macos]
steps:
- uses: actions/checkout@v2
- name: Install npm dependencies
run: |
npm install
- name: Install pod dependencies
run: |
cd ios && pod install
- name: Build app
run: |
xcodebuild -workspace myapp.xcworkspace -scheme myapp archive -archivePath myapp.xcarchive -allowProvisioningUpdates
xcodebuild -exportArchive -archivePath ./myapp.xcarchive -exportPath . -exportOptionsPlist myapp/Info.plist
mv myapp.ipa ../myapp.ipa
- name: Upload Artifact
uses: actions/upload-artifact@v1
with:
name: myapp.ipa
path: ios/build/

There we go, our React Native builds are automatically generated using GitHub's own CI/CD workflow!

--

--