Update ๐๐๐๐๐๐๐/๐๐๐/๐๐๐๐๐.๐๐๐๐๐๐ to complete Release pipeline
Part ษชษชษช: Automate App release to Google Play | Story 3 - ๐๐๐๐๐๐๐/๐๐๐/๐๐๐๐๐.๐๐๐๐๐๐ file updates to complete Release pipeline
In the previous posts of this part of the series, we created a Google Play Service account and then configured Gitlab CI/CD variables and .๐๐๐๐๐๐-๐๐.๐ข๐๐ to script the release pipeline automation.
What remains now is to update the ๐๐๐๐๐๐๐/๐๐๐๐๐.๐๐๐๐๐๐ and ๐๐๐๐๐๐๐/๐๐๐/๐๐๐๐๐.๐๐๐๐๐๐ files to complete the pipeline automation setup.
๐๐๐๐๐๐๐/๐๐๐๐๐.๐๐๐๐๐๐ file
As we are going to use Gradle Play Publisher (GPP) to automate the app bundling and release, we need to add that as dependency in the android/build.gradle
file. Open the file in code editor, under buildscript.dependencies
, add classpath
for the GPP as below:
buildscript {
โฆ
dependencies {
classpath("com.android.tools.build:gradle:4.0.0")
classpath("com.github.triplet.gradle:play-publisher:2.8.0")
...
}
}
These are the stable versions as of the writing of this post. Look for the latest versions (GPP and Android build gradle tools) and update accordingly.
With above changes, the file should look something like below ๐
๐ line#16
, we added classpath(โcom.github.triplet.gradle:play-publisher:2.8.0โ)
as one of the dependency.
Also updated the version of com.android.tools.build:gradle
to 4.0.0
: classpath(โcom.android.tools.build:gradle:4.0.0โ)
.
๐๐๐๐๐๐๐/๐๐๐๐๐๐.๐๐๐๐๐๐๐๐๐๐ file
If you have been following this series, in Part II - at the time of manual bundling and publishing of the Android app, we added the Upload keystore file name and its credentials/alias as app level vars android/gradle.properties
.
But now that we have these values moved to to Gitlab CI/CD variables, we can remove those from ๐๐๐๐๐๐.๐๐๐๐๐๐๐๐๐๐.
Open the file ~/.gradle/gradle.properties
or android/gradle.properties
, in code editor, and remove the following variables.
MYAPP_UPLOAD_STORE_FILE=rnTSgitlabCICDExample-upload.keystore
MYAPP_UPLOAD_KEY_ALIAS= rnTSgitlabCICDExample-upload
MYAPP_UPLOAD_STORE_PASSWORD=*****
MYAPP_UPLOAD_KEY_PASSWORD=*****
๐๐๐๐๐๐๐/๐๐๐/๐๐๐๐๐.๐๐๐๐๐๐ file
Next, we will edit the ๐๐๐/๐๐๐๐๐.๐๐๐๐๐๐ file which the gradlew
command would use to create the build, bundle the app and publish the bundle to our Google Play store account. Update ๐๐๐/๐๐๐๐๐.๐๐๐๐๐๐ file as below:
- Just below the top
apply plugin: "com.android.application"
statement in the file, we need to add below line of code to apply GPP plugin:
apply plugin: "com.github.triplet.play"
2. Earlier, in our .gitlab-ci.yml
file, we added steps to read Gitlab-CICD environment variables to a dynamically created json file named globalSettings.json
.
Now in our ๐๐๐/๐๐๐๐๐.๐๐๐๐๐๐ file, we will add a function named getSettings
, to read variables from this globalSettings.json
file. The input parameter to this function would be the setting/variable name. We will use JsonSlurper
utility to parse the json and get and return the value of the setting/variable provided by the input parameter.
For this, first add the below line of code just below the existing import statement in the file ( below import com.android.build.OutputFile
)
import com.android.build.OutputFile
import groovy.json.JsonSlurper // <-- add this new import statement
Now, add a getSetting
function definition below the import statements:
def getSetting(setting) {
def inputFile = file("globalSettings.json")
def settingsJson = new JsonSlurper().parseText(inputFile.text)
return settingsJson[setting]
}
3. Next, update the release
signingConfig as below:
...
android {
...
defaultConfig { ... }
signingConfigs {
debug {
...
}
release {
storeFile file('uploadRelease.keystore')
storePassword getSetting("PLAY_STORE_UPLOAD_KEYSTORE_PASSWORD")
keyAlias getSetting("PLAY_STORE_UPLOAD_KEYSTORE_ALIAS")
keyPassword getSetting("PLAY_STORE_UPLOAD_KEY_PASSWORD")
}
}
}
...
๐in the release
signingConfig, we are now reading the values of our appโs Upload key's storePassword
, keyAlias
and keyPassword
from the globalSettings.json
using the getSetting function we defined above.
Also, the upload keystore storeFile
has been specified as uploadRelease.keystore
. This is the file name that we specified in the .gitlab-ci.yml
script, that will be created dynamically during the pipeline run using the keystoreโs base64 string added in Gitlabโs CICD variables .
4. Make sure you have the above signingConfig specified for release build under buildTypes:
...
android {
...
defaultConfig { ... }
signingConfigs {...}
buildTypes {
release {
...
signingConfig signingConfigs.release
...
}
}
}
...
5. Add below play
section, below the files android
or dependencies
section. This new play
section specifies the configuration that GPP would use when releasing/publishing our app to Google Play store:
...
android {
...
}play {
defaultToAppBundles = true
track = "internal" // 'alpha', 'beta', 'rollout' or 'production'
serviceAccountCredentials = file("serviceAccess.json")
resolutionStrategy = "auto"
}...
defaultToAppBundles
: makes sure to package app as AAB (Android App Bundle) instead of APKtrack
: tells to which release track the bundle is to be published, in this case itโs the internal track ( other options are beta, alpha, production)serviceAccountCredentials
: The location of the Play Store JSON file. This again, as we specified in out.gitlab-ci.yml
file, we are creating dynamically in our pipeline, reading its value from Gitlab CI/CD variable to output toandroid/app/serviceAccess.json
file.resolutionStrategy = "auto"
: automatically updates the appโsversion code
to match the next available number required so itโs published
๐ There are many other useful configuration options GPP provides.
That completes the changes we need to make in android/app/build.gradle
file. With above changes, the file should look something like here ๐
Ok, now we are ready with all the configuration needed on Google play console and code changes needed to allow GPP to publish our app bundle.
Letโs update the release version before we commit and push our changes to Gitlab: yarn version.
The post-version script we added earlier in Part I of the series to our package.json
would automatically update the versions for iOS and Android file and commit the changes.
Push the branch to our Gitlabโs remote repository and create a PR to merge changes to master. Now that we have .gitlab-ci.yml
file in the repository, we would expect the pipeline to trigger when we merge changes to master.
Oops, looks like our first attempt failed.
The error we got is ๐๐ช๐ฏ๐ช๐ฎ๐ถ๐ฎ ๐ด๐ถ๐ฑ๐ฑ๐ฐ๐ณ๐ต๐ฆ๐ฅ ๐๐ณ๐ข๐ฅ๐ญ๐ฆ ๐ท๐ฆ๐ณ๐ด๐ช๐ฐ๐ฏ ๐ช๐ด 6.1.1. ๐๐ถ๐ณ๐ณ๐ฆ๐ฏ๐ต ๐ท๐ฆ๐ณ๐ด๐ช๐ฐ๐ฏ ๐ช๐ด 6.0.1. GPPโs most recent version (2.8.0) needs Gradle version to be โฅ 6.1.1. Thus we need the Gradle version in our React-Native appโs Android project.
Upgrading Gradle version
GPPโs most recent version as of the writing of this post is GPP 2.8.0. This version requires our React-Native appโs Android projectโs Gradle version โฅ 6.1.1 and Android tools build gradle version โฅ 4.0.
Check your React-Native Android project Gradle version from the distributionUrl
in your React-native android projectโs gradle-wrapper-.properties
file ๐
If your Android projectโs Gradle version is < 6.1.1, update it as below:
- Update the distributionUrl in the above file to latest Gradle versionโs zip file like below:
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip
2. Add multiDexEnabled false
to defaultConfig
properties of the android/app/build.gradle
file.
4. On terminal, cd to android folder of your react-nativeโs project
./gradlew wrapper --gradle-version=6.5 --distribution-type=ALL
The above gradlew
command may fail but thatโs okay, its probably because it doesnโt have the values that we are reading from Gitlab CI/CD variables in the app/build.gradle file.
5. Clean the project build
./gradlew clean
Also open the project in android studio, once Build sync completes, clean (Main menu โ Build โ Clean Build
) and rebuild (Main menu โ Build โ Rebuild Build
) the project. Again, the build may still fail because of the unavailability of Gitlab CI/CD variables when building locally, but thatโs okay.
6. Commit and push the changes to the remote branch, merge to master and the pipeline should trigger.
This time the Gitlab pipeline completed successfully, got the appโs build created and published to Google Play.
Check out Google Play console , we should see the new version (1.0.0 that we earlier set using yarn version) be released.
Awesome, we got our React-native Android App build and release pipeline automated using GPP and Gitlab CI-CD.
Now, we can just focus on the development of the app, and when ready with testing the new changes, push and merge the changes to master branch. This would trigger the pipeline to release the new version of app to Internal testing track.
Once the Internal test app version is tested and you feel your app is ready, you can promote the app to Alpha, Beta and finally to production by just click of a button from Google Play console.
Or you can set up additional pipeline jobs/stages in .gitlab-ci.yml
file to publish the app to different tracks. Trigger those pipelines either manually or based on some branch or any other repository triggers.
There you have it! Your step-by-step guide for setting a Gitlab CI-CD pipeline to automate publishing your React-Native app on Google Play.
I hope you would find this series helpful to automate your React-Native appโs Android build and release pipeline.
Thank you!!! Feedback, comments and suggestions are welcome.