Shipping Fast With Continuous Deployment
This article discusses the importance of automating the deployment process for React Native mobile apps. It highlights the benefits of continuous deployment, provides insights into setting up automation using tools like fastlane and App Center, and explores the advantages of automating app submissions to app stores.
Automation of the critical pieces of the development lifecycle can help you improve the overall development speed and security. The shorter the feedback loop, the faster your team can iterate on the product, which ultimately translates into greater user satisfaction. You can enjoy all of these benefits if you automate the deployment of your React Native mobile app – and in this article, we’ll tell you how to do that.
In other blog posts based on The Ultimate Guide to React Native Optimization, we touch on the following stability-related topics:
- Continuous Integration (CI) in improving React Native apps
- Over-The-Air (OTA) updates
- Making your app consistently fast with DMAIC and Reassure
- Running tests for key pieces of your app
- Profiling React Native apps with iOS and Android tools
Be sure to check them out. Now let's jump into the main topic.
Why should you care about Continuous Deployment in the first place
Testing and development are only some of the activities that you have to perform when working on a digital product. Another important step is the deployment – building and distributing the application to production. Most of the time, this process is manual.
The reason for that is simple - the deployment takes time to set up and is far more complex than just running tests in the cloud. For example, on iOS, Xcode configures many settings and certificates automatically. This ensures better developer experience for someone who’s working on a native application. Developers who are used to such an approach often find it challenging to move the deployment to the cloud and set up such things as certificates manually.
The biggest downside of the manual approach is that it takes time and doesn’t scale. In a consequence, teams that don’t invest in the improvements to this process end up releasing their software at a slower pace.
What is Continuous Deployment (CD)?
Continuous Deployment is a strategy in which software is released frequently through a set of automated scripts.It aims at building, testing, and releasing software with greater speed and frequency.The approach helps reduce the cost, time and risk of delivering changes by allowing for more incremental updates to applications in production.
With manual deployment, you’re not shipping new features and fixes as quickly as you should.
Building and distributing your application manually slows down your development process regardless of your team size. Even in small product teams of around five people, automated build pipelines make everyone’s work easier and reduce unnecessary communication. This is especially important for remote companies.
Continuous Deployment also allows you to introduce standards and best practices focused on improving the overall performance of the application, such as leveraging Hermes to optimize app startup time. With all the steps required for the deployment in a single place, you can ensure that all releases are done the same way and enroll company-wide standards.
Ship to users with a CD setup that makes the build and generates the changelog
When it comes to automating the deployment of mobile applications, there are two ways to go.
One way is to write a set of scripts from scratch by interacting with <rte-code>xcode<rte-code> and <rte-code>gradle<rte-code> directly. Unfortunately, there are significant differences between the tooling of Android and iOS and not many developers have enough experience to handle this automation. On top of that, iOS is much more complicated than Android due to advanced code signing and distribution policies. And as we have said before, if you are doing it manually, even Xcode cannot help you by doing its magic.
Another way is to use a pre-existing tool in which the developers have handled the majority of use cases. Our favorite one is fastlane - a set of modular utilities written in Ruby that let you build your iOS and Android applications by writing a set of instructions in a configuration file.
After you have successfully built your binaries, it is time to deploy them to their destination. Again, you can either upload the files to a desired service (e.g. App Store) manually or using a tool that will take care of that for you. For the same reasons as before, we prefer to use an existing solution - in this case, AppCenter by Microsoft.
AppCenter is a cloud service with tooling for the automation and deployment of your application. Its biggest advantage is that many of the settings can be configured from the graphical interface. It is much easier to set up the App Store and Play Store deployments this way, rather than working with uploads from the command line.
Yet another way to automate deployment that we'd like to call out is EAS Submit, a cloud service created by Expo with first-class support for submitting React Native applications. It provides a fast workflow to easily submit your application to both stores. When used with EAS Build, it also offers automatic submissions out of the box.
For the purpose of this article, we will use fastlane and AppCenter in CircleCI pipelines to fully automate the process of app delivery to the final users.
Note: Describing the ins and outs of the setup would make this article too long. That’s why we have chosen to refer only to the specific documentation. Our goal is to provide you with an overview, and not a step-by-step guide, since the final config will be different for each project.
Setting up fastlane
Before going into the details for Android and iOS, you have to make sure that the fastlane has been installed and configured on our devices.
Next, you have to run the init command within the React Native project. We will run the <rte-code>fastlane<rte-code> command twice, from each native folder. This is because React Native is actually two separate apps at a low-level.
As a result, this command will generate setup files in both <rte-code>ios<rte-code> and <rte-code>android<rte-code> folders. The main file in each folder would be called Fastfile and it’s where all the lanes will be configured. In <rte-code>fastlane<rte-code> nomenclature, a <rte-code>lane<rte-code> is just like a workflow - a piece that groups low-level operations that deploy your application.
Low-level operations can be performed by calling <rte-code>actions<rte-code> – predefined <rte-code>fastlane<rte-code> operations that simplify your workflow. We will show you how they function in the next section.
Setting up fastlane on Android
Now that you have successfully set up fastlane in our projects, you are ready to automate the deployment of our Android application. To do so, you can choose an Android specific action - in this case <rte-code>gradle<rte-code>. As the name suggests, Gradle is an action that allows you to achieve similar results as with Android Gradle used standalone.
Our lane uses <rte-code>gradle<rte-code> action to first clean the build folder, and then assemble the APK with signature based on passed params.
You should be able to run lane build by implementing:
Note: Don’t forget to set environment variables to access the keystore. These are RELEASE_STORE_PASSWORD and RELEASE_KEY_PASSWORD; they have been set in the example presented above.
Setting up fastlane on iOS
With Android build automated, you’re ready to move to iOS now. iOS is a bit more complex due to the certification and provisioning profiles. They were designed by Apple to increase the security. Fortunately, <rte-code>fastlane<rte-code> ships with a few dedicated <rte-code>actions<rte-code> that help us overcome these complexities.
You can start with the <rte-code>match<rte-code> action. It helps in managing and distributing iOS certificates and provisioning profiles among your team members. You can read about the idea behind <rte-code>match<rte-code> in the code signing guide concept. Simply put, <rte-code>match<rte-code> takes care of setting up your device in a way that it can successfully build an application that will be validated and accepted by the Apple servers.
Note: Before you move any further, make sure that your init matches your project. It will generate the required certificates and store them in a central repository where your team and other automation tools can fetch them.
Another action that you could use apart from <rte-code>match<rte-code> is <rte-code>gym<rte-code>. <rte-code>Gym<rte-code> is similar to Gradle action in a way that it actually performs the build of your application. To do so, it uses the previously fetched certificates and signs settings from <rte-code>match<rte-code>.
You should be able to run lane build by running the same command as for Android:
This should produce an iOS application now too.
Deploying the binaries with App Center
Now that you have automated the build, you are able to automate the last part of the process - the deployment itself. To do so, you could use App Center, as discussed earlier in this guide.
Note: You have to create an account in the App Center, apps for Android and iOS in the dashboard and generate access tokens for each one of them. You will also need a special Fastlane plugin that brings an appropriate action to your toolbelt. To do so, run `fastlane add_plugin appcenter.`
Once you are done with configuring your projects, you are ready to proceed with writing the <rte-code>lane<rte-code> that will package the produced binaries and upload them to the App Center.
That’s it! Now it is time to deploy the app by executing deploy lane from your local machine.
Integrating your pipeline with CircleCI
Using all these commands, you are able to build and distribute the app locally. Now, you can configure your CI server so it does the same on every commit to <rte-code>main<rte-code>. To do so, you will use CircleCI – the provider we have been using throughout this guide.
Running fastlane on CI server usually requires some additional setup. Refer to the official documentation to better understand the difference between settings in local and CI environments.
To deploy an application from <rte-code>CircleCI<rte-code>, you can configure a dedicated <rte-code>workflow<rte-code> that will focus on building and deploying the application. It will contain a single job, called <rte-code>deploy_ios<rte-code>, which will execute our <rte-code>fastlane<rte-code> command.
Pipeline for the Android will look quite similar. The main difference would be the executor. Instead of a macOS one, a docker react-native-android Docker image should be used.
Note: This is just a sample usage within CircleCI. In your case, it may make more sense to define filters and dependencies on other jobs to ensure the deploy_ios is run in the right point in time.
You can modify or parametrize the presented lanes to use them for other kinds of deploys, for instance for the platform-specific App Store. To learn the details of such advanced use cases, get familiar with the official fastlane documentation.
Before using EAS Submit to submit to the app stores, you need a developer account for each store to generate signing credentials for your React Native application.
Generating app-signing credentials
Whether or not you have experience with generating app-signing credentials, you can use EAS CLI to do the heavy lifting for you. The CLI will handle the app-signing credentials process.
For Android, you’ll need to generate a keystore for your app. Run the following command to begin:
The CLI will now prompt you with a series of questions. Select <rte-code>Android<rte-code> when asked for the platform, and then select <rte-code>production<rte-code> as the build profile. The keystore can be generated by selecting <rte-code>Keystore: Manage everything needed to build your project<rte-code> and <rte-code>Set up a new keystore<rte-code>. The generated keystore is stored securely on EAS servers.
For iOS, select iOS as the platform when prompted by the CLI. It will generate a provisioning profile and a distribution certificate by signing into your Apple Developer account. This will prepare your <rte-code>production<rte-code> build to submit it for review. You can run the following command without specifying any build profile name if the default <rte-code>production<rte-code> profile is present in the <rte-code>eas.json<rte-code> file:
After the build is complete, you will be able to download the app binaires for each platform. Downloading the binary is required for the Android submission process.
The Android submission process
After building your production build with EAS Build, to submit your app to the Google Play Store, you will need to:
- Create a Google Service Account and download its JSON private key. You can learn about this step in this guide.
- Once you have downloaded the JSON private key, provide its path in your <rte-code>eas.json<rte-code> file:
- Manually upload your app for the first time. This is a limitation of the Google Play Store API.
- The <rte-code>eas build<rte-code> command from the previous section will help you generate an app binary that you can directly upload to the Play Storetart start the submission process, run the command:
The command will lead you step by step through the process of submitting the application. It will ask you to select a binary to submit. After creating the Android build from the previous section, you can just select the new build.
It will also display a summary of the provided configuration and begin the submission process. After the submission process is complete, the build will be visible through the Google Play Console.
The iOS submission process
After building your production build with EAS Build, to submit your app to the Apple App Store, you will need to run the following command:
The command will lead you step by step through the process of submitting the app. It will prompt you to:
- Log in to your Apple Developer account and select your team. You can also provide this information in <rte-code>eas.json<rte-code> by setting the appleId and appleTeamId fields under the submit production submission profile. The Apple ID password has to be set with the <rte-code>EXPO_APPLE_PASSWORD<rte-code> environment variable.
- Select a binary to submit. After creating the iOS build from the previous section, you can just select the new build.
- It will display a summary of the provided configuration and begin the submission process. After the submission process is complete, the build will be visible on the App Store Connect website.
As a developer, you can save time when your app deployment process has evolved to the point where the app is automatically submitted to the app stores once a production build completes.
EAS Build gives you automatic submissions out of the box with the <rte-code>--auto-submit<rte-code> flag. This flag tells EAS Build to pass the build along to EAS Submit upon completion. The flag will also try to use a submission profile with the same name as the selected build profile. If you don’t have a custom build profile, you can select and use the default production profile for creating a build and submitting it to the app stores.
When you run <rte-code>eas build --auto-submit<rte-code> you will be provided with a link to a submission details page, where you can track the progress of the submission. You can also find this page at any time from the Submissions section of the Expo dashboard for your project, and it is also linked from your submitted build’s detail page.
How Continuous Deployment benefits your business
In a nutshell, short feedback loop along with nightly or weekly builds let you verify features faster and ship critical bugs more often. With automated deployment you no longer waste your time on manual builds and sending the artifacts to test devices or app stores. Your stakeholders are able to verify features faster and shorten the feedback loop even further. With regular builds you will be able to catch or ship fixes to any critical bugs with ease. If your app could use a performance boost, check out our React Native development services and give us a shout.