Build an Android APK using GitLab for a React Native Application

Prerequisites

Keystore

# Used to generate our keystore
keytool -genkeypair -v -keystore my-key.keystore -alias my-key-alias -keyalg RSA -keysize 2048 -validity 10000
# Used to encode our keystore in base64
base64 my-key.keystore > base64-keystore.txt

App signing

  • Login to Google Play Console
  • Select your application from the list
  • Select “App Releases”
  • Select a track, for example “Internal test” > “Manage”
  • Select “Create Release”
  • Then where it says Let Google manage and protect your app signing key (recommended), Select "Continue"
  • You digitally sign each release using your upload key (upload key being the keystore we just generated) before publishing it on the Play Console.
  • Google Play uses the upload certificate to verify your identity and then re-signs your release using the app signing key for distribution.

GitLab

  • Settings (side menu) > CI/CD > Variables
  • Add Type: Variable, key: ANDROID_KEYSTORE_ALIAS , value: my-key-alias
  • Add Type: Variable, key: ANDROID_KEYSTORE_PASSWORD, value: (whatever password you used)
  • Add Type: Variable, key: ANDROID_KEYSTORE_KEY_PASSWORD, value: (whatever password you used, by default it's the same as the ANDROID_KEYSTORE_PASSWORD)
  • Add Type: File, key: ANDROID_KEYSTORE, value: (copy the contents of base64-keystore.txt)

app/build.gradle

android {
...

signingConfigs {
release {
if (project.hasProperty('MYAPP_RELEASE_STORE_FILE')) {
storeFile file(MYAPP_RELEASE_STORE_FILE)
storePassword MYAPP_RELEASE_STORE_PASSWORD
keyAlias MYAPP_RELEASE_KEY_ALIAS
keyPassword MYAPP_RELEASE_KEY_PASSWORD
}
}
}

buildTypes {
release {
minifyEnabled enableProguardInReleaseBuilds
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
signingConfig signingConfigs.release
}
}

...
}

package.json

  • build-package: Builds our APK file
  • bundle: Bundles all of our react native code into a single file
  • generate-gradle-properties: Creates a gradle.properties file for us in the android folder.
{
"scripts": {
"android-package": "cd android && ./gradlew assembleRelease",
"bundle": "react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.bundle --sourcemap-output android/app/src/main/assets/index.map --assets-dest android/app/src/main/res",
"generate-gradle-properties": "sh generate-gradle-properties.sh > android/gradle.properties",
...
}
...
}
#!/usr/bin/env bash

cat << EOF
android.useAndroidX=true
android.enableJetifier=true
MYAPP_RELEASE_STORE_FILE=my-key.keystore
MYAPP_RELEASE_STORE_PASSWORD=${ANDROID_KEYSTORE_PASSWORD}
MYAPP_RELEASE_KEY_ALIAS=${ANDROID_KEYSTORE_ALIAS}
MYAPP_RELEASE_KEY_PASSWORD=${ANDROID_KEYSTORE_KEY_PASSWORD}
EOF

.gitlab-ci.yml

stages:
- build

...

build:android:package:
stage: build
image: reactnativecommunity/react-native-android
script:
- echo fs.inotify.max_user_watches=524288 | tee -a /etc/sysctl.conf && sysctl -p
- yarn install
- base64 -d $ANDROID_KEYSTORE > android/app/my-key.keystore
- yarn generate-gradle-properties
- yarn bundle
- yarn android-package --no-daemon
artifacts:
paths:
- ./android/app/build/outputs/
...

AAB

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store