Deploying updates (bug fixes, enhancements, or new features) to mobile apps is significantly more complex than it is for web apps. For the web, you commit to a Git repo, deploy the update to your servers or hosting provider, and users will see those updates when they next visit your site or as soon as they refresh.
However, for mobile, you have little control over the official app publication platforms (Google Play and iOS App Store), so there is no guarantee your update will be published immediately. Furthermore, even when updates are published, users will not receive those updates until they upgrade their apps through the app stores. This means that if a user has a mobile app version with a bug, they’ll be stuck with that bug until a new version is released and they upgrade. As a result, the mobile app development life cycle is much less forgiving of bugs.
It is true that even with the best developers and QA testers, you can’t guarantee a bug-free mobile app. Still, you can employ rigorous preventative techniques that make it easier, faster, and more reliable to release updates. Optimizing your mobile app deployment process to production is the surest way to do that.
1. Decide on a regular production release train 🔗
A production release train is the frequency, agreed upon by members of your team and necessary stakeholders, at which they will deploy to production.
Adopting a regular production release train — for example, every second Friday or last day of the month — leads to smaller deployments. This way, it is easier to discover and track bugs, ensuring that users can get timely fixes.
There is no one-size-fits-all approach to deciding on this. Whatever time frame you set should depend on factors like size and proficiency of the team, product backlog, and frequency of feature or bug fix update requests. Overall, Kris Wong, a software architect focusing on mobile app development, suggests that a production deployment cadence of two weeks to one month is a good target.
2. Move from legacy tools to mobile-focused CI/CD tools 🔗
Continuous Integration/Continuous Delivery (CI/CD) is a process of efficiently and frequently delivering apps to users by incorporating automation into the stages of app development.
There are many CI/CD tools available. But a mobile-focused CI/CD tool considers the unique challenges of building for mobile and has mobile-first features that help you build, test, and deploy mobile apps faster and more efficiently.
With a mobile-focused CI/CD tool, you’ll get out-of-the-box functionality for all your mobile development needs on one platform alongside outstanding integration with third-party tools necessary to create workflows for any circumstance. You’ll also get support for all mobile environments, languages, and frameworks (Flutter, React Native, Cordova, Dart, Kotlin, Swift, and Java, to name a few). In addition, this kind of tool offers the flexibility to set up several simulators for parallel testing, cloud device testing, beta testing, or actual device testing seamlessly.
To get started, set up your mobile CI/CD pipeline today with a mobile-focused platform like Bitrise or migrate from a legacy CI/CD tool like Jenkins.
3. Cache app dependencies 🔗
In a mobile CI/CD pipeline, every new build will typically execute in a new virtual machine (VM). As such, new VMs must be set up from scratch every single time.
Downloading dependencies unnecessarily every time you run a build wastes a lot of time. With caching, you can store dependencies during the build to speed up your workflow.
On Bitrise, caching app dependencies is as straightforward as adding the Bitrise.io Cache:Pull Step to download the previous cache and Bitrise.io Cache:Push Step to check the cache and upload it if required. For more details on how to use Bitrise to cache in your mobile app deployment pipelines, take a look at our other posts on the topic:
- Optimizing your workflows
- Tune your Bitrise workflows using cache in steps
- Everything you need to know about caching on Bitrise
4. Run build jobs in parallel on multiple VMs 🔗
As a project expands in size and complexity, so do the requirements from the build process — tons of tests, build steps, and setup tasks. Long build processes slow down development life cycles as developers must wait for build pipelines to complete — however long it takes — before verifying that everything works fine or creating pull requests.
The majority of build jobs (or steps), such as tests, are run sequentially. Hence, each step runs independently and only happens after the preceding one. What if you split a significant, long build process into different steps and executed them all at the same time?
For example, a build with four steps that take one minute each would take four minutes to finish when run sequentially. But what happens if you run all four steps at the same time? The build would only take one minute to complete! This is what running build steps across many virtual machines at the same time (parallelism) does. So, you can, for example, run unit tests on one VM and integration tests on another.
Using Bitrise, you can automatically run builds or steps in parallel with a single trigger using the Bitrise Start Build Step and the Bitrise Wait for Build Step. Here are some articles we’ve written explaining how to run parallel builds on Bitrise:
- Speeding up Android builds by ‘fanning out’ tests on Bitrise
- Speeding up iOS builds by ‘fanning out’ tests on Bitrise
- Starting parallel builds with a single trigger
5. Automate deployment to app stores and testing platforms 🔗
Deploying mobile apps can mean deploying to a testing platform to distribute builds to testers or deploying to official app stores to distribute releases to the public.
The process of deploying and delivering mobile app updates through official app stores cannot be entirely automated since these platforms are third-party and have exclusive authority over whether your program satisfies release standards. Still, you can automate the process of submitting updates to these platforms and other manual steps that precede submission, such as: creating and managing signing certificates, code signing, profile provisioning, versioning, packaging release binaries, metadata, or screenshots.
Automating the deployment process of mobile apps puts time back in the hands of your team and curbs the “human error” risk associated with manually doing repetitive tasks. Instead, they can concentrate on more critical tasks like collecting feedback, spotting bugs, and fixing them.
Bitrise provides several Code Sign Steps and Deploy Steps that you can easily add to your workflow to automate code signing and deployments for both Android and iOS apps. Here are some articles we’ve written to show how to use these Steps to deploy in whatever way you want to.
- How to deploy your Android app to Google Play Store
- Deploying Expo React Native to Appetize
- How to deploy Android and iOS apps to Applivery for your tester or employees
- Deploying iOS apps
6. Deploy experimental features or updates under feature flags 🔗
A feature flag is a Boolean value that specifies whether or not a new feature is enabled. Feature flags help create conditional feature branches in code so that a particular logic is only exposed to particular groups of users at a certain moment.
Native mobile app distribution is slow and high risk because of the manual app approval process. If something goes wrong in any release, users might be stuck with it for hours or even days, during which some may churn. However, thanks to feature flags, you can roll back or turn off updates immediately without having to deploy a new binary or waiting for the approval process to complete.
You can reduce development risks, easily perform A/B testing, and incorporate actual user input by releasing experimental features under feature flags. Granted, this may not work for everyone, but it’s ideal for organizations that cannot afford to take a chance on any problems or have long release cycles.
Implementing feature flags in your code doesn’t have to be a complicated process. You can either build an internal tool for this or use an SDK like LaunchDarkly.
7. Monitor releases for crashes 🔗
You’ve done everything: followed all the right rules, rigorously tested, deployed, and now your updates are live and in the hands of your users. Yet, it doesn’t end there. Mobile apps can crash for a hundred different reasons. Monitoring releases allows you to detect problems before your users spot them and keep track of how your app is functioning. This is vital to improving the user experience and retaining users.
In most cases, you’ll have to use third-party mobile crash reporting software outside of your CI/CD tool of choice. But if you use Bitrise as your mobile CI/CD tool, you won’t have to worry about that.
Trace is Bitrise’s proprietary mobile monitoring solution that integrates easily with your existing Bitrise pipelines. Trace can help you discover, identify, and address issues before users report them — so you can confidently push updates to app stores.
You’ll also be able to track performance, identify which devices are affected, estimate the number of people affected by the crash, visualize sessions to better understand the user experience, and track down the crash’s source. Setting up Trace is simple — configure via Bitrise Step, Gradle, Cocoapods, or SPM. Learn more about Trace and its capabilities.
Mobile CI/CD is the way forward for optimal mobile deployments 🔗
There is a slew of other suggestions that might help you improve the efficiency of your mobile app deployment process. Regardless, the CI/CD technology you use will have a big impact on your success — ideally, a mobile CI/CD solution that empowers you to carry out all of these steps with ease.
Take it from Franz Busch, iOS engineer at Sixt, who says: “Bitrise enabled our teams to ship code to our customers with high confidence.”
This article was originally published on the Bitrise Blog by Peter Meinertzhagen