Deploying a React Native App with Fastlane - Part 1
Deploying to iOS/App Store
This is a part of a series of posts about deploying a React Native application with Fastlane.
- Part 1 - Deploying to iOS/App Store
- Part 1a - Auto-Increment build numbers
- Part 2 - Deploying to Android/Google Play
Since the whole Fastlane and React Native ecosystem is constantly evolving, I’ll try to keep this post up to date to reflect the latest changes. Latest Update: 2016/03/30
Our setup for iOS will look like this:
- One central Apple ID shared across the whole team, used to manage our certificates, provisioning profiles and upload the application to iTunes Connect.
- One git repository containing our encrypted certificates and provisioning profiles
- A single command to do all the heavy lifting and publish our application to TestFlight
For all of this we’ll use the following Fastlane tools:
- match - for creating and syncing our certificates and provisioning profiles
- gym - for building and signing our application
- pilot - for uploading the build to TestFlight
And of course fastlane itself.
First, create a new Apple ID. I highly recommend this if you’re working with a team. If you don’t, you could use your personal ID. In this example, I’ll use
Now you’ll need to add the new Apple ID to your existing Apple Developer organisation and iTunes Connect.
If you haven’t created an app for your project in iTunes Connect yet, please do so now and pick a good bundle ID. We’ll need this later. In this example, I’ll use
Next, create a new git repository in a secure location. Your private certificates will be added to it (encrypted). You can read more about if it’s secure and possible risks here. In this example, I’ll use
So much for the preparations, let’s add everything to our existing project. First install
gem install match gym pilot fastlane
You could also create a
Gemfile for this, so you can be sure everyone is using the same version.
Now create a new directory called
fastlane in your project root and run
match init to create our first config file. Enter the URL of your git repo you’ve created above. Add a few more things to
git_url "https://git.awesome.company/very-secret.git" type "development" shallow_clone "false" app_identifier "com.awesome.project" username "firstname.lastname@example.org"
If you need more information on this see match setup.
Match can now generate the certificates and provisioning profiles. Run
match appstore to create a new cert for signing and publishing to the App Store. Run
match development if you need one for installing the application on your local phone.
Next, we need to create the
Fastfile. Let’s run
fastlane init. You’ll be asked a few question. But everything should be straight forward.
Still we need to make a few changes to the
fastlane_version "1.68.0" default_platform :ios platform :ios do desc "Submit a new Beta Build to Apple TestFlight" desc "This will also make sure the profile is up to date" lane :beta do match(type: "appstore") gym( scheme: "AwesomeProject", project: './ios/AwesomeProject.xcodeproj' ) pilot end end
match(type: "appstore") will make sure you’ve got the latest version of the certificates/provisioning profiles and keep them in sync.
gym(...) will build and sign your application.
pilot will upload the result to TestFlight.
That’s all we need from Fastlane. Have a look at the Fastlane Docs for more actions and information.
But we’re not done yet. Let’s open Xcode and make a few adjustments.
Open your general settings and set the correct bundle identifier and version (you can keep
1.0, but I prefer more semver like versions).
Open your target settings and set the
Code Signing Identity to
iOS Distribution. Open the dropdown for
Provisioning Profile and select
AppDelegate.m and replace
jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.ios.bundle?platform=ios&dev=true"];
#ifdef DEBUG jsCodeLocation = [NSURL URLWithString:@"http://0.0.0.0:8081/index.ios.bundle?platform=ios&dev=true"]; #else jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; #endif
Now the app will look for a file called
main.jsbundle if it’s build for production.
First create a new
react-native bundle --dev false --platform ios --entry-file ./index.ios.js --bundle-output ./ios/main.jsbundle
To publish a new version run:
That’s it! Everything hopefully works and a version of your application should be available via TestFlight soon.
If you got questions or suggestions, drop me a message: @dbanck.