React Native, git submodules and CI/CD
So, just like any other startup, we are growing, fast and rapidly.
Our clients are increasing their demands and so is the load on us developers. There came a time when we realised our basic testing mechanism is no longer suited well for such intensive demands and we need to setup a a proper QA process.
Yes, it was a rough terrain for a young startup, but eventually we emerged with flying colours, but this chapter is to be opened some other time.
Coming back to the hustle of QA, we needed to deliver our android builds to for every weekly sprint, and soon we realised this is something we really really need to automate as asking a developer to dedicate 10 minutes of his day time just for creating builds was not efficient plus we all know developers are lazy.
So, all we needed was an android build setup on our CI/CD pipeline, and hence the learning began.
You may be wondering, android build and CI/CD its not that complex, we have tones of articles and pre-implementation which we can find online? Yes that is true but what we couldn’t find a proper package caching mechanism for our submodules which were quite heavy and were causing a lot of issues over every build. At the end, we just hacked it with a generalized thought process and now I am writing this to add a new article to tones and tones of other previously existing articles. It would be fun 😉😉
I have previously worked with CI/CD for another project of ours and hence had most of the required things pre-setup. ( Ah, who I am kidding to, I copy pasted the code, isn’t that what we all do ? 😉 )
I broke down my requirements into a few steps and with many-many build failures I ended up with the correct cirlce ci config and boom the wonder was done, our job was cut short by 10 minutes on a weekly basis and all it took were 2 sleepless nights and a few cups of coffee . (sorry I lost count 😁😁)
So, we needed a setup like this
... filters ...
... requirement on node_build ...
... filters ...
... sub parts [ dev / staging / prod ] ...
Easy right?, Lets dive in each part
We needed our packages to be restored from cache, installed and saved in cache, pretty standard process.
For this, we created the job like this:
- run: yarn --cwd ./submoduule/random_name
- run: yarn install --network-concurrency 1
Does this one makes sense? Lets through some light on a few shortcuts we have
restore_yarn_cache: This is a short cut / alias we have in out config which restores the yarn cache in of the node_modules we have in our root directory
save_yarn_cache: This is a short cut / alias we have in out config which saves the yarn cache in of the node_modules we have in our root directory, which is then restored using restore_yarn_cache in the subsequent build(*)
You guys are smart, you would now surely be able to interpret restore_submodule_yarn_cache and save_submodule_yarn_cache.
Our android build had a few sub requirements
- We wanted 3 different builds,
dev, staging and release
- We wanted the build to work only on specific branches
- We wanted build job to start work only after node_build was complete
- We also needed the artifact ie we needed to download the apk from circle ci itself.
I would be discussing only about the staging build here in the article as you would be able to build your way up from here to your other requirements, or else, you would be acting just like me, copy pasting and changing the names 😁😁
So our staging build worklfow looked something like this:
To add some context to this strange code block:
1. Our workflow’s job name is android_build_staging and hence the job should be of the same name.
2. We needed our job to execute after the node_build process only, which is defined above.
3. We need the workflow to be executed only if the branch name matched the regex: /^staging\/v/gm
So, lets talk about how our android_build_staging looked
- run: yarn config set script-shell /bin/bash
- run: yarn ci:create-release-key
- run: yarn build:apk "staging"
So there are 2 things in particular which needs attention:
yarn ci:create-release-key: We are using this command to decrypt the release keystore
yarn build:apk: it’s an all general build command we have for building android, which accepts an argument of environment type
So this basically sums up all the explanation of config, here below you can find the entire code.