Optimizing the react-native development process with Bitbucket and bitrise.io
In our company we are developing a lot of cool react-native projects. Since we started to work with react-native, we were searching for the best way to optimize our development process.
After some time, we ended up using Bitbucket, some integrations and a very cool service called bitrise (bitrise.io). This is a SaaS build service platform, which is specialized on apps.
We are using this development process for all of our apps, from small internal apps to large apps for external customers with millions of downloads.
How does or process work?
First of all, we are using feature branches on our Bitbucket git repository. For those who don’t know this workflow, you can read about it here: https://www.atlassian.com/git/tutorials/comparing-workflows/feature-branch-workflow
Every time a pull request is created against our master branch, the first level of our bitrise integration kicks in. We automatically check for code quality and run our tests. This is done by an automatically triggered bitrise workflow.
This first workflow is very simple. We have written a short script in our package.json, which triggers three steps.
We are using flow as type checker, but this would work with Typescript as well. We run the flow command first, to check that there are no type errors in the pull request.
The next thing we run is ESLint. We use it to find errors and to ensure a consistent code style. This makes merging a lot easier.
At the moment, we are using jest for unit testing. Our code coverage is only around 40% so this is a step, which I would want to get a lot further. But even with that low code coverage it can help detecting changes and problems. Like always, testing is a matter of time and if you have tight deadlines, tests are the first things to get dumped (which I know — they shouldn’t).
This is how our workflow looks like in bitrise. We clone the repository, install the libraries via npm and run our “test-complete” command. Pretty simple!
If there is any error during this check, the developer who opened the pull request has to resolve this, before a reviewer even looks at the code. This saves a lot of time during the review process.
Further ideas for automated pull request review
We want to go some additional steps on this automation ladder. We are testing some automated code quality tools like www.deepcode.ai to find out if we get some additional benefits from that integration. If it does, I will write another article about our learnings with that service.
AWS Device Farm
Another thing we are testing at the moment are Appium tests on AWS Device Farm. Appium is a test automation framework, which allows us to test native apps like an end user. We just write our click paths and the app gets automatically tested. AWS Device Farm is an AWS service, where we can run apps on real devices in the cloud. We are combining this two things, to achieve automated tests on real devices. The cool thing is, there is also a bitrise integration for AWS Device Farm. We can upload our tests automatically, run them and wait for the results in bitrise. If the tests complete without an error, we report this back to Bitbucket and tell the reviewer, that the pull request is “ready to review”. Otherwise, the developer, who opened the pull request gets the information, that he has to fix some things before the review will be started.
Unfortunately there are some problems left with this process. In some random cases the Appium tests stop working on AWS Device Farm, even if they should work. Most of the time, Appium does not find a button to click it, even if it is there. This makes it kind of unusable for automation, but we are confident to solve this issues in the near future.
Automated builds for the customer
After our automated tests and a manual code review and test, the pull requests are merged in the master branch by the reviewer. The app has to work well at this stage, because this is where the next bitrise workflow starts. Every time a pull request is merged in the master branch, we increment the build number, create an android build of the app, upload it to Firebase App Distribution and inform the customer that he can test. This allows us to get feedback as fast as possible.
This process has another very positive point. Every reviewer knows, that he has to be sure, that everything works before merging into the master branch. The app goes directly to the customer. So there was a significant rise in quality assurance during the review process.
We have different release cycles on our apps. On some of our apps, we release every 14 days, others only all three to six months. But the process is the same for all apps.
We merge the releasable code in a “release branch”. This triggers two workflow on bitrise (iOS release + Android release). This basically runs all our tests again, builds the app and uploads it to the AppStore and GooglePlay. There are some other automated tests like fetching the most recent content and translation files for the build, build sourcemaps for our bugsnag (another cool service for another article).
As you can see, there are a lot of steps, which have be done on every release. To automate this steps does not only save a lot of time, it also reduces potential mistakes, which can occur when doing all this steps manually.
We are always trying out new things and check how we could improve our process. At the moment this works quite fine for us, only automated e2e testing on real devices is an unsolved problem.
Feel free to contact me if you have any questions or input on this. I’d love to discuss any other ideas and get new input.