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
Introduction #
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.
Pre-Setup #
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 ios-dev@awesome.company
.
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 com.awesome.project
.
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 https://git.awesome.company/very-secret.git
Setup #
So much for the preparations, let’s add everything to our existing project. First install match
, gym
, pilot
and fastlane
:
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 fastlane/Matchfile
:
git_url "https://git.awesome.company/very-secret.git"
type "development"
shallow_clone "false"
app_identifier "com.awesome.project"
username "ios-dev@awesome.company"
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/Fastfile
:
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 Other
: $(sigh_com.awesome.project_appstore)
.
Open AppDelegate.m
and replace
jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.ios.bundle?platform=ios&dev=true"];
with
#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.
Deployment #
First create a new main.jsbundle
:
react-native bundle --dev false --platform ios --entry-file ./index.ios.js --bundle-output ./ios/main.jsbundle
To publish a new version run:
fastlane beta
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.