Android X , reactNative hermes migration at redBus — A military style operation
Mission objective :
Migrate redBus android app to Android X, and also to upgrade react native to use hermes engine.
- This would ensure that redBus app would be future ready to use the features that are to be shipped by Google in the future
- Hermes : Migrating to hermes would give us a size reduction of about ~3MB
How did we do this?
For fun, we decided to make this a military style operation which consisted of 3 stages
- Mission planning
Stage 1 : Reconnaisance
2 devs, one from native android and 1 from react native set out on a mission to scope the migration. The data that they set to collect were the following
- Quantum of change : How big is the migration going to be ? The number of files that are going to be affected? The number of libraries/modules/sdk’s that are going to need update.
Number of files : ~6500 Files including Java, Kotlin, xml files
2. Libraries/SDK/Module availability: At redBus we use a couple of SDK’s provided by 3rd party vendors. This meant we get in touch with the vendors to see if they have an SDK that is readily AndroidX compatible. Though jetifier could have done the job, it would be good to have the compatible sdk right away.
Number of SDK’s, modules : ~10
3. Tool availability : Devs scoped about the availability of tools that can aid the migration. This also involved looking into articles and learn about other apps that have done the migration (Plaid, Dan Lew’s blog)
1. Android Studio’s Refactor tool
2. Modified Script from https://gist.github.com/dlew/5db1b780896bbc6f542e7c00a11db6a0
3. CSV mapping file that maps old package name to new package name. https://developer.android.com/topic/libraries/support-library/downloads/androidx-class-mapping.csv
4. Jetifier : For converting libraries to Android X at build time
4. Dev process adjustments : While the migration happens, there are other features being developed in parallel by other developers at redBus. The objective was to have minimum number of merge conflicts and less time to resolve the conflicts and less build failures.
5. CI script adjustments : Since tools like jetifier were inolved, we sought to see if there were any adjustments we have to do on the CI machines for successfully building.
6. Validation mechanisms : Once the migration is done, the app should behave as it did before migration. There were a couple of ways we narrrowed upon.
1. Manual testing
2. Robo scripts on Firebase test lab
3. Internal automated end to end tests
4. Instant app sharing on Google Play store to distrubute the app for testing
Stage 2 : Mission Planning
With all the intel obtained from the recon, the team set out to come up with an execution plan to accomplish the migration
- Tooling :
redBus devs tried Android Studio’s refactor tool, but it failed. The IDE (Android Studio) hung and would not respond after sometime, probably due to the number of files that the tool had to process. We tried a couple of times with no luck.
The script worked with some exceptions. And these were easily manageable. The id’s that were present inside the code (android.R.android.support.design was not refactored properly). But these were minimal and could be managed manually.
Jetifier for library migration at run time
Jetifier for migrating react native dependencies
2. Dev process adjustments :
Devs were informed that the migration was on going and there would be changes to the imports and were asked to keep their commits granular.
Either Devs could cherry pick their commits in order or do a direct merge, which ever is faster.
3. Validations :
Intenal tests which had both espresso and Appium to cover end to end app flows was finalised to be used to validate the migration.
4. CI script adjustments :
Since the migration involved jetifier, we had to add,
npm install jetifier
to the CI scripts to take care of migrating react native libraries at build time. The plan was to phase out jetifier as an when the libraries become compatible with AndroidX.
Stage 3 : Execution
Team : 2 Devs
Estimated Time : 5 days
Phase 1 : Code migration
With a plan in place, 2 devs set out to do the migration. One of them ran the scripts that did the migration and resolved the build issues. Once the build was successful both of them ran the tests, played around, ran through as many flows as possible. Phase one of execution was done.
Phase 2 : The conflux . Conflux is a place where one or more tributaries of a river meet and become one.
In redBus’s case, one triburaty is the one where the AndroidX migration happened and the others are the ones where other developers were working on while the migrations happened. There were around 12 branches. It was as good as 13 tributaries were meeting at one point. This is a perfect place for a vortex.
For most developers a rebase, merge worked and there was a bit of change required when imports were involved.
The end to end tests helped us validate that the migration was smooth and was complete.
- There were zero defects when the app got released to playstore. The migration operation was executed with surgical percision.
- The app size reduced by 3 mb(due to hermes engine). Thats a big win