Automating Android App Play Store Publishing via Jenkins
Software development lifecycle is very crucial in software engineering. It will be more challenging once the team grows because there will be engineers, quality assurances, product managers, UX researchers, UI designers, automation tester, and many other roles.
Every stage of software development must be communicated and distributed clearly. For instance, once the regression testing for Android app has been done by the QA, then they will talk to the Android engineers to upload and release the application to Play Store. So, the Android engineers must standby during QA’s regression test, right? And, seems like an effective way to kill the time, right? ‘LOL’
So by looking at these processes, we can define some problems:
- Android engineers are the bottleneck of the release on the software development lifecycle.
- Android engineers must wait for the compile and build process, before waiting for the upload process until it is released on Play Store.
- A non-scalable process as the engineering team grows.
The next question is how to solve these problems? One of the solutions is to build a more automated system and flow. And we can start by building Android automated uploader to Play Store. It will reduce communication dependency between QAs and engineers.
Thus, how to build an Android Play Store Automatic Uploader? Basically, it is as simple as building Production APK and then letting the CI server upload the APK to Play Store.
These are the detailed step-by-step on how to implement Automatic uploader:
1. Create Google Play Credential ID (P12 File)
1.1. Inside the Google Play Store Console of your project, navigate to
Settings
->Developer account
->API Access
:
1.2. Scroll down to
Service Accounts
section, then clickCreate Service Account
button on the bottom.
1.3. There will be a popup for creating the Service Account. Click on
Google API Console
link on the first point.
1.4.
Google API Console
will be shown inService Account
menu, click on+ Create Service Account
.
1.5. Create service account screen will be shown. Fill the
Service account name
and alsoService account description
. TheService account description
will be automatically generated. After that, clickCreate
button on the bottom.
1.6.
Service Account
will be shown in the list, click overflow menu in Actions, then clickAdd Keys
.
1.7. Click
+ Create Key
to create private key. Make sure to also request the.p12 Key File
instead of JSON:
1.8. You will be prompted to download
.p12
file. Save it somewhere. Input a password for that.p12
file.1.9. Once you are done, go back to the Google Play Developer Console and navigate to the
Settings
->API Access
. Make sure the checkboxes forEdit store listing, pricing & distribution
,Manage Production APKs
, andManage Alpha & Beta APKs
are checked for the Google Service account used.
That’s it, you have finished the first step of a system that will make your life so much easier! :)
2. Set Up Release Signing Configs in Gradle
The second step is to set up signing configs in the Gradle. It is used to let Gradle knows all the needed keystore configs to build production APK.
Note: If you don’t have any idea about what keystore is, you can read this article to help you first https://developer.android.com/studio/publish/app-signing
Add this configuration in your app build.gradle
inside android { }
branch:
android {
signingConfigs {
release {
storeFile file(RELEASE_STORE_FILE)
storePassword System.getenv("KEYSTORE_PASSWORD")
keyAlias System.getenv("KEYSTORE_ALIAS")
keyPassword System.getenv("KEYSTORE_PASSWORD")
}
}
}
storeFile
, a path to your production keystore. You can define your path in your gradle.properties
. You can define any path for the keystore file.
RELEASE_STORE_FILE=keystore.jks
storePassword
, your production keystore password. This ‘KEYSTORE_PASSWORD’ will be defined and entered from CI Server, which will be explained later in the next section.
keyAlias
, your production keystore alias. This ‘KEYSTORE_ALIAS’ will be defined and entered from CI Server, which will be explained later in the next section.
keyPassword
, your production keystore password. This ‘This ‘KEYSTORE_PASSWORD’ will be defined and entered from CI Server, which will be explained later in the next section.
3. Create a CI Pipeline
For this Play Store Automatic uploader, we will use Jenkins as our CI Server. So the following steps will be about implementation in Jenkins.
Pre-requisite: Jenkins server has been set up previously!
3.1. Add your production keystore to Jenkins
Go to Credentials
-> System
-> Add Credentials
- Select
Secret file
as credential kind - Select
Global (Jenkins, nodes, items, all child items, etc)
as credential scope. It will make this credential accessible from all nodes and pipeline. - Upload your
keystore.jks
. - Name any unique
ID
for this credential. ThisID
will be the alias used to call from the pipeline later. In this example, I named it asandroid_keystore
. - Input any
Description
of this credential.
3.2. Add your Google Play Credential ID (P12 File) to Jenkins
Go to Credentials
-> System
-> Add Credentials
- Select
Google Service Account from private key
as credential kind. Google Play Key
as your project name.- Select
P12 key
. - Input your generated P12
email address
, and upload your P12key file
that you have generated in section 1.
Click OK, then your P12 file has been set up in your Jenkins! And your Jenkins is now eligible to upload APK to the Play Store.
3.3. Create Jenkins Pipeline
After you’re done with adding credential and authentication files, the next step is to make the Jenkins pipeline to build and upload production APK to Play Store.
Create a Pipeline by clicking in the sidebar on the left. A new screen for pipeline configuration will be opened.
Insert description for the pipeline, and checkingDo not allow concurrent builds
.
Give parameters to this pipeline by checking the This project is parameterized
. Give Password Parameter
for ‘KEYWORD_ALIAS’ and also ‘KEYSTORE_PASSWORD’. These two parameters will be mandatory fields that need to be input by the user when running this pipeline. It will secure the production pipeline, and not be abused by users. These parameters will be used by Gradle in generating production APK, how to integrate it with Gradle has been discussed in section 2.
Another parameter is the String Parameter
for the ‘SELECTED_RELEASE_BRANCH’, to let users input the GIT branch that they want to build.
3.4. Pipeline Script to Build and Upload Production APK to Play Store
After you’re done with the general configuration of the Pipeline, scroll to bottom on the pipeline configuration screen. You will see the `Pipeline script` text box for you to define all the needed processes to do the APK automation.
Now let’s fill that pipeline script!
A. Preparing SDK
def home = sh(script: "echo $HOME",returnStdout: true).trim()
def SDKPath = "$home/Android/SDK"
stage("Preparing SDK"){
// Check SDK Downloaded
def isSDKDownloaded = sh(script: "test -e sdk-tools-linux-4333796.zip && echo true || echo false",returnStdout: true).trim()
if(isSDKDownloaded == "false"){
// Download SDK
sh "wget 'https://dl.google.com/android/repository/sdk-tools-linux-4333796.zip'"
}
// Check if SDK is Extracted
def isExtracted = sh(script: "test -e $SDKPath/tools && echo true || echo false",returnStdout: true).trim()
if(isExtracted == "false"){
sh "mkdir -p $SDKPath"
//Unzip SDK
sh "unzip sdk-tools-linux-4333796.zip -d $SDKPath"
}// Install SDK Tools
sh "yes | $SDKPath/tools/bin/sdkmanager 'build-tools;28.0.3' 'platform-tools' 'platforms;android-27'"sh "ls $SDKPath/licenses"
// See installed And Available SDK
sh "$SDKPath/tools/bin/sdkmanager --list"
// Accept All SDK Licences
sh "yes | $SDKPath/tools/bin/sdkmanager --licenses"
}
What really happens in the script above is about preparing the server computer environment to be ready to build Android SDK. Preparing SDK means download Android SDK, extract, and install it. The following are the steps:
- Define the path of the Android HOME, then use it to define the path of Android SDK.
- Check if the SDK has been downloaded in the slave’s computer, then if the SDK has not been downloaded yet, then we must download the SDK to the computers based on the computer’s OS.
- Extract the SDK in the SDK Path that has been defined previously.
- Install SDK tools that have been extracted, use the
$SDKPath/tools/bin/sdkmanager
path to install the SDK. See installed and available SDK, and accept all the SDK licenses by following the above script.
B. Build Production APK
def selectedBranch = SELECTED_RELEASE_BRANCH
stage('Checkout') {
git branch: selectedBranch, url: 'git@bitbucket.org:styletheory/styletheory-android-dummy-app.git'
// Remove Existing local properties
sh 'rm local.properties ||:'
// Write sdk.dir Path into local properties file
sh "echo 'sdk.dir=$SDKPath' >> local.properties"
}
stage('Setup Tools') {
withCredentials([file(credentialsId: 'android_keystore', variable: 'KEYFILE')]) {
sh "cp \$KEYFILE app/keystore.jks"
}
}
stage('Build Release APK') {
sh "./gradlew clean assembleRelease"
}
This second step is about building the production APK through Gradle command:
- Set the selected GIT branch based on the input user from the parameter.
Checkout
to that branch, remove existing local.properties, and write new local.properties.- Next step is to copy the
android_keystore
that we already saved in Jenkins to a variable calledKEYFILE
. Copy that file onapp/keystore.jks
. The path depends on where you defined it in Gradle, we discussed this in section 2 previously. - Build Production APK, do it by running a command
./gradlew clean assembleRelease
. It will use all the Keystore information that has inputted by the user and also the file that has been copied from Jenkins itself.
C. Upload to Production
stage('Upload to Play Store') {
androidApkUpload googleCredentialsId: 'Google Play Key', apkFilesPattern: '**/*-release.apk', trackName: 'production'
}
stage('Cleanup Credential') {
sh "rm app/keystore.jks"
}
Allow me to explain the above script:
- Use
Google Play Android Publisher
plugin to upload the generated APK to Play Store. If you haven’t installedGoogle Play Android Publisher
plugin, install it onManage Jenkins
->Manage Plugins
->Available
. - After installing this plugin, run command
androidApkUpload
. SpecifygoogleCredentialsId
that we already store in Jenkins (P12 File),apkFilesPattern
of the production APK pattern, and alsotrackName
of the track: it can be alpha, beta, and also production. - After successfully upload the APK to Play Store, don’t forget to Cleanup Credential by removing the keystore file itself from the computer.
That’s all! That’s how you build the automatic APK uploader to Play Store!
Weeks after implementing this automated process, we received many positive feedbacks!
- It boosts up development time. QA doesn’t need to work with Android engineer only to upload the final app! No more bottleneck! Even the QA can compile, build, and upload by themselves.
- It improves productivity! Since Android engineers are not required to wait for the green light from the QAs and upload process to Play Store, they have plenty of time to do something else. They can do tech-improvement, backlog’s stories, or even do unit test for features! It enhances quality in software as well!
It is not perfect yet. There are still improvements to be done in the future! We can connect with GIT flow as well to integrate all the processes of software development. Wait for it in the next article! ☺