Build an Android React Native App Using GitHub Actions
So, you want to build an Android React Native app using GitHub Actions? I’m glad you asked! In this short article we will go over step by step on how to build your APK directly on GitHub.
Getting Started
First, we will create a new Github Actions Workflow. A workflow is just a YAML file that contains tiggers for when certain jobs (scripts) should run.
Create the file .github/workflows/build-frontend.yml
to begin specifying the
workflow.
You should also add a name for the workflow at the top which will be visible in the GitHub Actions tab.
name: frontend-cd
Workflow Triggers
Triggers define when your jobs will run. We will setup the workflow to build whenever there is a push to main:
on:
push:
paths: [ "Frontend/**" ]
branches: [ "main" ]
Furthermore, notice how I included the filter paths: [ "Frontend/**" ]
, this
is important because it avoid running our build unnecessarily. For example, for
my case, I have both frontend and backend code in the same repo. Thus, having
this filter avoid building the frontend for backend pull requests.
Defining a Job
Setup Steps
jobs:
cd:
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
# Clone the repo on the target machine (ubuntu-latest)
- name: Checkout code
uses: actions/checkout@v4
# Installs Node.js
- name: Set up Node.js
uses: actions/setup-node@v4
# Installs your prjects dependencies as defined in your package.json file
- name: Install dependencies
working-directory: Frontend/DebrisMine
run: npm install
# Install the Android SDK (for building the app)
- name: Setup Android SDK
uses: android-actions/setup-android@v2
# Install the Gradle build tool
- name: Setup Gradle
uses: gradle/gradle-build-action@v2
The schema here is fairly self explanatory. But for completeness, here we only
define one job (named cd
). It runs on an Ubuntu machine, and the job times out
after 20 minutes (useful to avoid unexpected long builds). Notice how each step
has a name, this is the name that will be visible when the action is run:
Build steps
# Optional pre-build step
# Make sure to cd to your android folder though!
- name: Prebuild Android
working-directory: Frontend/DebrisMine
run: |
npx expo prebuild -p android --no-install
cd android && chmod +x ./gradlew
# Building using gradle
- name: Build Android Release
working-directory: Frontend/DebrisMine
run: |
cd android && ./gradlew clean && ./gradlew app:assembleRelease
Since I use expo, I have a prebuild step before building
which generates the android folder for me. If you are not using expo, then
simply ommit this line npx expo prebuild -p android --no-install
, and just cd
into the android folder which you should have pushed to your repo.
Signing steps
All Android apps need to be signed for them to be trusted by your Android device (and Google Play).
# Sets the environment variable BUILD_TOOL_VERSION based on the installed
# Android SDK version (needed for next step).
- name: Setup build tool version variable
shell: bash
run: |
BUILD_TOOL_VERSION=$(ls /usr/local/lib/android/sdk/build-tools/ | tail -n 1)
echo "BUILD_TOOL_VERSION=$BUILD_TOOL_VERSION" >> $GITHUB_ENV
echo Last build tool version is: $BUILD_TOOL_VERSION
# Sign the APK
- name: Sign APK
id: sign_app
uses: r0adkll/sign-android-release@v1
with:
releaseDirectory: $/Frontend/DebrisMine/android/app/build/outputs/apk/release
signingKeyBase64: $
alias: $
keyStorePassword: $
keyPassword: $
env:
BUILD_TOOLS_VERSION: $
To sign the APK you will need to add four secrets to your GitHub repo:
ANDROID_SIGNING_KEY
, ANDROID_SIGNING_ALIAS
,
ANDROID_SIGNING_STORE_PASSWORD
, and ANDROID_SIGNING_KEY_PASSWORD
.
Keytool
comes installed with the JDK. You can create a key using Keytool from the
command line: keytool -genkey -v -keystore my-release-key.keystore -alias
alias_name -keyalg RSA -keysize 2048 -validity 10000
. You can replace
alias_name with anything you’d like, but make sure to remember it, since it will
be the ANDROID_SIGNING_ALIAS
secret. The command line tool will aslo ask for a
store password and a key password (make sure to remember it or note it down
somewhere). Finally, the ANDROID_SIGNING_KEY
is simply the contents of the
generated file: my-release-key.keystore
.
You can add the secrets through the repo settings.
Upload step
The app has been build but it’s still “stuck” on the machine, we need to upload it back to GitHub as an Artifact.
- name: Upload APK Artifact
id: uploadArtifact
uses: actions/upload-artifact@v2
with:
name: app
path: $
Ending Notes
Congrats! If all goes well, you should have automatic builds setup and ready!
You should be able to download the signed APK file for every push to main from the Artifacts sections of a run.