Automating the Android App Distribution process at BookMyShow
Using Android App Bundles, one bash script, and Google's Internal App Sharing API.
We at BookMyShow are changing how our release process works currently, by migrating from APKs to Android App Bundles. While we were changing how our production releases and distribution works, we also decided to simplify how we share builds internally with our QA Team and other developers.
PS: If you haven't heard of Android App Bundles, here's a good resource to read about it — medium.com/google-developer-experts/explori..
Old process walk-through:
Before we changed the process, this is how we distributed builds — Initially, we ran a script to generate APKs locally — this created 5 different APKs w.r.t. various CPU architectures.
This was followed by uploading all the APKs to a newly created Google Drive folder whose link was then shared with QA Team over Slack.
The QA Team would then download the required APK — based on the device architecture — and then proceed to install before starting the testing process.
Too manual & tedious, I know!
Why you should use Bundles?
Android App Bundles is a new format that contains all the app codes and resources dumped into it. It’s uploaded to Google Play and the Play Store generates different APKs for different devices based on device specific features.
This means — smaller on-device APK size — because only resources and code that the device needs are shipped, hence can impact retention due to smaller on-device footprint.
One of the main selling points was — Dynamic Delivery — downloading part of the app only when user wants to access (lazy downloading). This can be useful for some modules which are important to the application, but used rarely.
Another benefit is the fact that it’s easier to share — just share a link and the needed APK can be installed.
How is this secure though?
Google’s Internal App Sharing console gives the owner access to create list of Authorized Uploaders and Testers. Only the whitelisted email IDs can install the app on their device.
What changes in the new process and how could you automate it too?
One script to rule ’em all!
Once a developer is done coding a feature, the developer will initiate a build on the Build Machine (a dedicated server machine which does a fresh pull, compiles the code, and creates a build with the same specifications for everyone) along with passing in some parameters.
- Generates an .aab file depending on the environment (QA or Production).
- Uses some parameters from the Service Account JSON to generate an Access Token from the Auth Token.
- This Access Token is used to generate a JWT (JSON Web Token) which is passed to the API which uploads it to Internal App Sharing.
- The API hit returns a link, which is posted in a specific Slack channel using an Incoming Webhook.
- QA Team can install the app directly from the Play Store link (Internal Sharing Console).
Here’s the script that rules ’em all
A snippet of the bash script
Requirements for Automating App Bundles
Install a JSON parser for terminal or shell commands —
brew install jq
Create a Service Account — through which you can streamline the upload without exposing credentials for the main account. Also, this account should have publishing rights — which can be limited to test publishing too. You will need to download the Service Account JSON and add it to your project.
Google Play Console
Only if you’re the owner of the account — In the Google Play Console, enable the API access for the Google Play Developer API.
Then proceed to Automatic App Signing — upload your keystore(.jks) or a certificate(.pem) file to the Google Play Console so you won’t have to sign artifacts manually.
Here, create a list of Authorized Uploaders and Testers. You can have different lists for both. Make sure you tick the required lists to enable authorization.
Google Play Store
You will need to switch on Internal App Sharing to install via the link. Go to Google Play Store → Settings → About → Tap on Google Play Version 7 times. Toggle on Internal App Sharing.
Create an incoming webhook and configure it to post to a certain Slack channel. This will enable you to share the URL automatically once the AAB is uploaded and you get the link.
PS: You can change which channel you want to post the link in by overriding the channel variable in the POST request data which is consumed by the incoming webhook. For more details on how to post data through incoming webhooks, please follow the official Slack API documentation.
The change in release process meant that we benefited on a few fronts —
Firstly, our app build time (for a completely new build, without any caching) went down by ~70% — this is because with Android App Bundles, it just dumps every resource into the bundle, rather than segregating like for APKs.
Furthermore, we saved ~11% on our app size on device — because of splits based on 3 major fronts — Device Resolution, Device Language, and Device Architecture.
Finally, we saved a lot of manual effort by completely automating the process — once the build is completed, it’s link is uploaded and shared on a specific Slack channel automatically. No manual intervention is needed.
One thing I learned is, if you want to automate something, do it end to end. Partial automation can be helpful but put in the effort to go the extra mile and you'll see amazing results.
Tooltip: You can modify above script to upload the generated Android App Bundle (.aab) to Google Play Store for distributing to users.
Below are some of the links that helped me to achieve the release automation —
- Play Console Help
- OAuth 2.0 for Service Accounts
- Google Play Developer API - Internal App Sharing Artifacts
- Alistair Sykes blog on Medium