TL;DR , how I want my APK signing to work:
- No credentials/keystore in the repository.
- Build and sign it locally using the keystore (not checked into version control) with configuration using environment variables as part of the general build process.
- Build it on MS App Center using their Branch Configuration for keystore upload and configuration.
I followed the official React Native instructions to create a keystore file.
However, I did not want to manage a global gradle config in my home directory and rather go with usual environment variables.
What will happen?
Uploading sensitive data to the repository is out of the question, so the only possibility is to use the upload feature of the Branch Configuration.
This setup will enable you to build signed APKs locally using
./gradlew assembleRelease
.
It will not try to sign the APK if no keystore path is set in the environment variables but print a warning instead. This is important, because MS App Center will sign the APK in a second step, after the build, using the keystore and credentials you set in the branch configuration.
I really did not get the documentation that describes the different ways how to sign an APK on App Center and it took me a while to figure out how this works.
Setting environment variables
Assume your keystore file is located in your React Native project at:
android/app/myapp-dev.keystore
You need to set the following environment variables:
ORG_GRADLE_PROJECT_MYAPP_RELEASE_STORE_FILE=myapp-dev.keystore
ORG_GRADLE_PROJECT_MYAPP_RELEASE_KEY_ALIAS=myapp-alias
ORG_GRADLE_PROJECT_MYAPP_RELEASE_STORE_PASSWORD=your-password
ORG_GRADLE_PROJECT_MYAPP_RELEASE_KEY_PASSWORD=your-password
I usually use direnv to do this.
ORG_GRADLE_PROJECT_
is a prefix that will tell grade to include these environment variables as properties, the prefix will be stripped in this process.
Configure Gradle
Edit android/app/build.gradle
to include the signing in this way:
signingConfigs {
release {
if (project.hasProperty('MYAPP_RELEASE_STORE_FILE')) {
storeFile rootProject.file("app/" + project.findProperty('MYAPP_RELEASE_STORE_FILE') ?: "ANDROID_STORE_FILE_NOT_SET")
storePassword project.findProperty('MYAPP_RELEASE_STORE_PASSWORD') ?: "ANDROID_STORE_PASSWORD_NOT_SET"
keyAlias project.findProperty('MYAPP_RELEASE_KEY_ALIAS') ?: "ANDROID_KEY_ALIAS_NOT_SET"
keyPassword project.findProperty('MYAPP_RELEASE_KEY_PASSWORD') ?: "ANDROID_KEY_PASSWORD_NOT_SET"
}
}
}
And also the call in the release buildType:
buildTypes {
release {
//...
if (project.hasProperty('MYAPP_RELEASE_STORE_FILE')) {
signingConfig signingConfigs.release
} else {
println '-------------------------------------------------'
println 'The MYAPP_RELEASE_STORE_FILE property was not set!'
println 'This release will not be signed by gradle!'
println '-------------------------------------------------'
}
}
}
Configure App Center
That’s it!
Many thanks to: Gustav, Muneeb and the nice tech support from Microsoft support for their hints and patience! 🙏