React Native Release
NOTE: This plugin is being reworked fit into the larger ecosystem of React Native Release. What you see here may be out of date while we get everything finalized.
Simplify releases for your React Native apps. This plugin contains many actions to help you with your release workflow.
It helps cut a new beta
or release
version of your app:
- Authenticates and stores an encrypted App Store Connect session that is later used for TestFlight and App Store operations
- Prompts the user for a
major/minor/patch
version bump - Bumps the version of the iOS and Android app appropriately
- Creates a tag
- Handles hotfix releases
- Handles merging version bumps and hotfixes back to the appropriate branches
It encrypts, and on CI, decrypts values from a standalone "context" git repository:
- Android keystore file (including helping you generate one)
- Google Play Credentials to upload to the Play Store
- Fastlane config ENV variables
- App ENV variables (API_URL, feature flags, etc)
Philosophies
Use Fastlane Match
Certificates and provisioning profiles should be created and managed by Fastlane Match
Builds Run on CI
We support local builds for projects, but they should only be used in emergency situations.
CI uses a machine user
This is a best practice.
ENV vars are managed through React Native Release
We do this for portability and ease of configuration. Outside of the ENV vars to configure CRYPTEX, you shouldn't have to add ENV vars to CI.
For App ENV vars, we provide some additional functionality via namespaces. Valid namespaces are alpha
, beta
, release
, and empty (root). Root ENV vars are "global". Namespaced variables are merged into the Root ENV vars at build time via the decrypt_app_vars
action. This allows you to easily overwrite ENV vars for specific types of builds, all without configuring separate targets and schemes in XCode.
The main branch and tagging flow looks like this (note this may be out of date. Revisit after workflow updates):
If a hotfix is required the flow looks like this (note this may be out of date. Revisit after workflow updates):
Here's what it looks like in action:
(this example uses "release": "bundle exec fastlane run react_native_release"
as a yarn script)e
Prerequisites
Ensure your project confirms to Semantic Versioning
Projects using React Native Release should use Semantic Versioning. At the very least, you need major, minor, and patch numbers in your version.
iOS
Use agvtool
to get and set a version across your project. From the ios
directory, do the following:
-
agvtool what-marketing-version
to see your current version -
agvtool new-marketing-version 0.1.0
to set a new version
Android
- Set
versionName
inapp/build.gradle
. (versionName "0.1.0"
)
❗ If you don't complete these steps, releases will fail. ❗
Installation
This project is a fastlane plugin. Since React Native projects contain both iOS
and Android
apps, we need to install the plugin in multiple places:
Install plugin into fastlane folders
- In the root of your project. This is used to run release commands over the entire project.
fastlane add_plugin react_native_release
- In
./android/fastlane
fastlane add_plugin react_native_release
- In
./ios/fastlane
fastlane add_plugin react_native_release
Add or update .env files
We leverage .env
files in a number of different places.
<root>/fastlane/.env
:
KEY | TYPE | DESCRIPTION |
---|---|---|
CRYPTEX_GIT_URL | String | The repository where the hashed session token will be stored. Ensure this repository before running the release script! (You can leverage the same repository you use for Fastlane Match) |
CRYPTEX_PASSWORD | String | The secret key used to encrypt/decrypt the FASTLANE_SESSION value. |
CRYPTEX_SKIP_DOCS | Boolean | Force the underlying encryption plugin to skip README generation. |
<root>/android/fastlane/.env
:
KEY | TYPE | DESCRIPTION |
---|---|---|
ANDROID_KEY_PASSWORD | String | The password generated from generate_android_keystore or a manual keystore command.` |
ANDROID_KEY_ALIAS | String | The alias for the keystore |
CRYPTEX_GIT_URL | String | The repository where the hashed session token will be stored. Ensure this repository before running the release script! (You can leverage the same repository you use for Fastlane Match) |
CRYPTEX_PASSWORD | String | The secret key used to encrypt/decrypt the FASTLANE_SESSION value. |
CRYPTEX_SKIP_DOCS | Boolean | Force the underlying encryption plugin to skip README generation. |
<root>/ios/fastlane/.env
:
KEY | TYPE | DESCRIPTION |
---|---|---|
MATCH_GIT_URL | String | The repository used for Fastlane match. Typically the same as CRYPTEX_GIT_URL |
MATCH_PASSWORD | String | The password used to encrypt / decrypt Fastlane Match certs and profiles |
GYM_WORKSPACE | String | The name of the workspace file (Myproject.xcworkspace) |
GYM_SCHEME | String | The scheme to build within the workspace (Myproject) |
GYM_OUTPUT_NAME | String | The name of the .ipa file to output (Myproject) |
CRYPTEX_GIT_URL | String | The repository where the hashed session token will be stored. Ensure this repository before running the release script! (You can leverage the same repository you use for Fastlane Match) |
CRYPTEX_PASSWORD | String | The secret key used to encrypt/decrypt the FASTLANE_SESSION value. |
CRYPTEX_SKIP_DOCS | Boolean | Force the underlying encryption plugin to skip README generation. |
Note: In followup releases, we will add a react-native-release init
script to generate these for you.
Setup CI
Step 1. If you've already setup Fastlane Match, skip this section. Each provider is different, but conceptually you'll want to:
- Create a machine user account on your source code provider (GitHub or BitBucket) and invite that account to both the mobile and certs repo.
- Enable CI on the main mobile repository by pressing "Follow" or "Build"
- In an Incognito tab, log into your CI provider with the machine user account.
- Add a user key instead of the default deploy key. This will allow CI to auth as the machine user and gain access to both the mobile repo and the context repo.
Step 2. Add the following to your CI environment variables:
- CRYPTEX_GIT_URL=(your context repo ssh git url)
- CRYPTEX_PASSWORD=(your context repo password)
- CRYPTEX_VERBOSE=true
- CRYPTEX_DIGEST=sha256 (note: if you have a pre-existing setup, you should set this to md5 - see hjanuschka/fastlane-plugin-cryptex#10)
Configuring builds to upload to TestFlight and AppStore Connect on CI
To upload builds to TestFlight or AppStore Connect, CI will need to restore a previously generated session. While possible to use an Application Specific Password to upload builds, it will not have the additional permissions required for other TestFlight / App Store operations. As such, we require generating a session.
Example
See /example to see how to use the plugin. (TODO)
Run tests for this plugin
To run both the tests, and code style validation, run
rake
To automatically fix many of the styling issues, use
rubocop -a
Issues and Feedback
For any other issues and feedback about this plugin, please submit it to this repository.
Troubleshooting
If you have trouble using plugins, check out the Plugins Troubleshooting guide.
Using fastlane Plugins
For more information about how the fastlane
plugin system works, check out the Plugins documentation.
About fastlane
fastlane is the easiest way to automate beta deployments and releases for your iOS and Android apps. To learn more, check out fastlane.tools.