Member-only story
A Simple Continuous Deployment of a React Native App to Apple’s App Store
We will create a Github Action to build and deploy a React Native mobile application automatically using Fastlane to the Apple App Store.
Pre-Requisites
- A react-native application that builds successfully.
- An active Apple Developer Account with the app previously deployed to it (although it is possible to make the first deploy automatically we will be assuming its already deployed here).
- An App Store Connect API Key that will be used to authenticate requests to your App Store Connect from the CICD server without a password.
- Configure Match with Github to manage your distribution certificates. Match will securely store your certificates encrypted in a separate Github repository so it can be accessible from any machine including the worker running the CICD.
- A Github Personal Access Token with read/write permission to your private repositories which should include the one where Match is saving your distribution certificates.
Overview
We will be using Github Actions to run a deploy script automatically upon creating a Github Release of a new version of a ReactNative app to the iOS store.
Step 1: Configure Fastlane
To ease integration with the App Store upload APIs we will be using Fastlane to build and upload our application. Fastlane needs to be configured locally before running it in our CI. For installation instructions on your local machine see here. To configure Fastlane, run fastlane init
from inside the ios
application directory and follow the on-screen instructions.
Edit the ios/fastlane/Fastfile
to include a deploy lane as shown below:
default_platform(:ios)
platform :ios do
desc "Deploy Production and Staging to TestFlight"
lane :deploy_all_to_testflight do
# =======================================================
# Step 0: If running on the CICD we need to create a custom keychain
if ENV['CI']
@api_key = app_store_connect_api_key(
key_id: ENV["APP_STORE_CONNECT_KEY_ID"],
issuer_id: ENV["APP_STORE_CONNECT_ISSUER_ID"],
key_content…