Internal testing React Native Android apps
Internal testing on Google Play Console is used for testing new app versions before releasing them to the end users. This post covers the main notes from setting up the app (on the Google Play Console) to automatic uploads.
Prerequisites
- bootstrapped app
- installed Android studio
- verified developer account on Google Play Console
- paid one-time fee (25\$)
Google Play Console setup
Create an app with the essential details, such as app name, default language, and app type, and choose if it is paid or free.
Testers
Add email addresses to the email list.
Release
Signing config
Generate a private signing key with a password using keytool
sudo keytool -genkey -v -keystore my-upload-key.keystore -alias my-key-alias -keyalg RSA -keysize 2048 -validity 10000
Move the generated file to android/app
directory.
Edit ~/.gradle/gradle.properties
to add the following keys and replace the alias and password with the correct values.
MYAPP_UPLOAD_STORE_FILE=my-upload-key.keystoreMYAPP_UPLOAD_KEY_ALIAS=my-key-aliasMYAPP_UPLOAD_STORE_PASSWORD=*****MYAPP_UPLOAD_KEY_PASSWORD=*****
Edit android/app/build.gradle
to add the release signing config, which uses the generated key.
android {...defaultConfig { ... }signingConfigs {...release {if (project.hasProperty('MYAPP_UPLOAD_STORE_FILE')) {storeFile file(MYAPP_UPLOAD_STORE_FILE)storePassword MYAPP_UPLOAD_STORE_PASSWORDkeyAlias MYAPP_UPLOAD_KEY_ALIASkeyPassword MYAPP_UPLOAD_KEY_PASSWORD}}}buildTypes {...release {...signingConfig signingConfigs.release}}}
Versioning
Update versionCode
and versionName
fields in android/app/build.gradle
file before generating the bundle. The version code should be incremented by 1.
android {...defaultConfig {...versionCode 2versionName "1.1.0"...}...
Android App Bundle (aab file)
Generate the Android app bundle with the following command.
cd android./gradlew bundleRelease
android/app/build/outputs/bundle/release/app-release.aab
is the path for the generated file.
Manual uploads
Upload the aab
file and write the release name and notes. The link for downloading the app should be available on the Testers tab.
Automatic uploads
This section configures the necessary steps for the pipeline with Github actions.
Versioning
Version apps with np
and react-native-version
packages running np
script.
// package.json{"scripts": {"np": "np --no-publish","postversion": "react-native-version -t android"},"repository": {"type": "git","url": "<REPOSITORY_URL>"}}
Signing config
Remove the release signing config from android/app/build.gradle
file. An app will be bundled first and signed after that.
Credentials
Get the signing key with the following command and set it as ANDROID_SIGNING_KEY
Github action secret in the Settings → Secrets → Actions page.
cd android/appopenssl base64 < my-upload-key.keystore | tr -d '\n' | tee my-upload-key.keystore.base64.txt
Reuse credentials from ~/.gradle/gradle.properties
file and set them as Github secrets.
- MYAPP_UPLOAD_STORE_PASSWORD → ANDROID_KEY_STORE_PASSWORD
- MYAPP_UPLOAD_KEY_ALIAS → ANDROID_ALIAS
- MYAPP_UPLOAD_KEY_PASSWORD → ANDROID_KEY_PASSWORD
For automatic uploads, create a service account by following the next steps.
- go to Google Play console → Setup → API Access → Google Cloud project, create a Google Cloud project, and link it
- on the same page, go to Credentials → Service accounts heading and click on
Learn how to create service accounts
, follow the mentioned steps- create a service account with a service account user role
- click on Actions → Manage keys button and create JSON key, which will be downloaded
- set downloaded JSON file as
ANDROID_SERVICE_ACCOUNT_JSON_TEXT
Github secret
Pipeline
The following pipeline sets up the necessary tools, does CI checks (linting, testing, audit), generates the app bundle, signs it, and uploads it to the Google Play console.
name: Android Buildon:push:branches:- releasejobs:android-build:name: Android Buildruns-on: ubuntu-lateststeps:- name: Check out Git repositoryuses: actions/checkout@v4- name: Set up JDKuses: actions/setup-java@v3with:java-version: 18distribution: temurin- name: Set up Android SDKuses: android-actions/setup-android@v3- name: Use Node.jsuses: actions/setup-node@v4with:node-version: 20- run: npm ci- run: npm run lint- run: npm test- run: npm audit- name: Make Gradlew Executablerun: cd android && chmod +x ./gradlew- name: Generate App Bundlerun: |cd android && ./gradlew clean && \./gradlew bundleRelease --no-daemon- name: Sign App Bundleid: sign_aabuses: r0adkll/sign-android-release@v1with:releaseDirectory: android/app/build/outputs/bundle/releasesigningKeyBase64: ${{ secrets.ANDROID_SIGNING_KEY }}alias: ${{ secrets.ANDROID_ALIAS }}keyStorePassword: ${{ secrets.ANDROID_KEY_STORE_PASSWORD }}keyPassword: ${{ secrets.ANDROID_KEY_PASSWORD }}- name: Upload App Bundle to Google Playuses: r0adkll/upload-google-play@v1with:serviceAccountJsonPlainText: ${{ secrets.ANDROID_SERVICE_ACCOUNT_JSON_TEXT }}packageName: com.flatmeappreleaseFiles: android/app/build/outputs/bundle/release/*.aabtrack: internalstatus: draftinAppUpdatePriority: 2
Edit the draft release and roll it out.
Troubleshooting
In case of a problem with signatures not matching the previously installed version, uninstall the app with the following commands.
adb devices# adb -s <DEVICE_KEY> uninstall <PACKAGE_NAME>adb -s emulator-5554 uninstall "com.yourapp"If the link for downloading the app installs some old version, clear the cache and data of the Google Play Store app on your device
Course
Build your SaaS in 2 weeks - Start Now