React Native是创建移动应用程序的最流行的基于JavaScript的框架之一。它通过实现创建在iOS和Android上运行的跨平台应用,削减了整个应用开发的整体复杂性和所需时间。
但是,为了建立一个React Native应用并将其发布,开发者必须首先签署证书,编译和更新版本,然后将构建的应用提交给相应的平台iOS的App Store和Android的Google Play。
在这篇文章中,我们将演示如何利用GitHub Actions和fastlane来自动完成这些繁琐的任务。
这篇文章将帮助你自动完成用React Native构建的iOS和Android应用的构建、测试和发布。
什么是fastlane?
fastlane是一个帮助iOS和Android开发者自动化耗时操作的解决方案。这个平台有助于通过持续部署提供高质量的应用程序,而不影响开发人员日常工作的速度和敏捷性。
fastlane除了提供Ruby命令行工具外,还提供本地Gradle(Android)和Xcode(iOS)插件。它管理的任务包括注册App Store和Google Play、向商店发布应用程序、部署测试版软件、Firebase Crashlytics等。你已经拥有的任何CI系统也会在fastlane中发挥作用。
设置fastlane
在我们开始之前,有一些系统要求必须在本地安装。
fastlane被官方支持在macOS上运行;Linux和Windows只被fastlane部分支持,因为Xcode等工具只在macOS上工作。
fastlane可以用Homebrew for macOS安装:
brew install fastlane
或者,用RubyGems安装macOS、Linux和Windows:
sudo gem install fastlane # Make sure ruby is already installed
有两种方法可以将fastlane添加到React Native项目中:
- 在Android和iOS各自的文件夹中单独使用
fastlane init命令;fastlane会自动检测平台,请求任何必要的信息,并配置平台 - 在React Native项目的根部创建一个
fastlane文件夹,并在其中添加一个Fastfile文件。然后,为iOS和Android手动配置它
我们将在本文中使用第二种方法。
为Android配置fastlane
让我们先为Android配置fastlane。
如前所述,我们将在项目的根部创建一个fastlane 文件夹,并在该文件夹中添加一个Fastfile 文件。我们将在iOS和Android上使用这个相同的Fastfile 文件。
在做其他事情之前,让我们检查并清理一下 Git 分支。我们将为Android的发布设置两个通道,一个用于beta测试,一个用于最终发布。
首先,我们将定义一个安卓平台,像这样:
platform :android do
desc "Release for the Android beta"
lane :beta do
increment_version_code('app_project_dir': './andriod/app')
gradle(task: 'clean', project_dir: './andriod')
gradle(task: 'bundle', bundle_type: 'Release', project_dir: './andriod')
supply(track: 'beta', abb: './andriod/app/build/outputs/apk/app-beta-release.apk')
end
desc "Release for the Android production"
lane : release do
increment_version_code(app_project_dir: './android/app')
increment_version_name(app_project_dir: './android/app', bump_type: 'patch')
gradle(task: 'clean', project_dir: './android/')
gradle(task: 'bundle', bundle_type: 'Release', project_dir: './andriod', properties: {
"android.injected.signing.store.file" => ENV['ANDROID_KEYSTORE_FILE'],
"android.injected.signing.store.password" => ENV['ANDROID_KEYSTORE_PASSWORD'],
"android.injected.signing.key.alias" => ENV['ANDROID_KEYSTORE_ALIAS'],
"android.injected.signing.key.password" => ENV['ANDROID_KEYSTORE_PASSWORD']
})
supply(track: 'production', aab: './android/app/build/outputs/bundle/release/app_release.aab', release_status: 'draft')
end
end
接下来,我们将为测试版创建一个发布通道,并添加一组要执行的操作。
我们将在下一步利用Gradle来清理构建。接下来,我们将执行Gradle bundle来构建一个APK或AAB。
作为最后一步,我们将利用CI工具供应,将元数据、截图、二进制文件和应用捆绑提交给Google Play。
接下来将以与测试版相同的方式创建Android应用发布通道;此时,我们将添加Keystore和Google凭证,以便发布。
注:。 fastlane的供应工具只有在你在Google Play上成功发布了你的Android应用后才能发挥作用。
为iOS配置fastlane
现在,让我们为iOS配置fastlane。在我们开始之前,Xcode和macOS是用fastlane发布iOS应用程序的先决条件。
我们将为iOS发布设置两个通道,一个用于TestFlight,一个用于App Store发布:
platform :ios do
private_lane :update_version do
app_store_version = get_app_store_version_number(bundle_id: 'rnFastlane')
plist_version = get_version_number_from_plist(xcodeproj: './ios/rnFastlane.xcodeproj')
if Gem::Version.new(plist_version.to_f) == Gem::Version.new(app_store_version.to_f)
increment_version_number_in_plist(xcodeproj: './ios/rnFastlane.xcodeproj', bump_type: 'minor')
else
increment_version_number_in_plist(xcodeproj: './ios/rnFastlane.xcodeproj', bump_type: 'patch')
end
end
private_lane :testflight_build do
increment_build_number_in_plist(xcodeproj: './ios/rnFastlane.xcodeproj', target: 'rnFastlane')
gym(scheme: 'rnFastlane', workspace: './ios/rnFastlane.xcworkspace')
end
private_lane :distribution_build do
increment_build_number_in_plist(xcodeproj: './ios/rnFastlane.xcodeproj', target: 'rnFastlane')
create_keychain(
name: ENV['KEYCHAIN_NAME'],
password: ENV['KEYCHAIN_PASSWORD'],
default_keychain: true,
unlock: true,
timeout: 3600,
add_to_search_list: true)
match(
type: 'app-store',
keychain_name: ENV["KEYCHAIN_NAME"],
keychain_password: ENV["KEYCHAIN_PASSWORD"],
readonly: true,
shallow_clone: true,
verbose: false)
gym(
scheme: 'rnFastlane',
workspace: './ios/rnFastlane.xcworkspace',
export_method: 'ad-hoc',
output_directory: "./build",
configuration: 'Release',
output_name: "rnFastlane.ipa"
clean: true
export_options: {
method: 'app-store',
provisioningProfiles: {
'rnFastlane' => ENV["sigh_#{options[:app_identifier]}_app-store_profile-name"],
}
})
end
desc "Release for the iOS beta"
lane :beta do
testflight_build
upload_to_testflight(username: ENV['APP_STORE_EMAIL'] app_identifier: 'rnFastlane')
commit_version_bump(message: 'bump build')
push_to_git_remote
end
desc "Release for the iOS production"
lane :release do
distribution_build
deliver
commit_version_bump(message: 'bump build')
push_to_git_remote
end
end
增加版本号
下一步是为更新版本添加一个私有通道。
我们将使用
get_app_store_version_number 和get_version_number_from_plist 插件方法,从App Store和plist文件中获取版本。这使得使用increment_version_number_in_plist 方法增加次要和补丁碰撞类型的版本号。
设置证书和配置配置文件
现在,我们将使用match 来设置证书和供应文件。match 包含在iOS应用程序的fastlane中,它用于代码签名。通过match ,整个开发团队可以使用一个单一的代码签名身份。
在添加match ,我们需要创建一个私有的GitHub仓库来存储证书。然后,我们可以用以下命令安装match 。
fastlane match init

接下来,我们需要添加一个私有仓库,如上图所示,以存储证书。在fastlane 文件夹下生成一个Matchfile 。一旦match 设置完成,我们就可以为开发和App Store创建证书和配置文件。
fastlane match appstore
# for the appstore
fastlane match development
# for the development
当上面的命令被执行时,它将把证书添加到私有仓库中。
构建iOS应用程序
另一个fastlane功能。 [gym](https://docs.fastlane.tools/actions/gym/)将用于构建iOS IPA应用程序。gym ,也将有助于自动部署和分发测试版软件。
上传构建结果
现在是时候上传我们的构建。我们将在TestFlight上传时使用upload_to_testflight ,在App Store提交时使用deliver 。deliver 服务是fastlane的一部分;它被用来向App Store上传元数据和IPA。
用GitHub Actions自动化工作流程
GitHub Actions是GitHub的一项新功能,可以轻松地在云端创建和运行工作流程。我们将设置GitHub Actions,使Android和iOS发行版的构建和发布工作流程自动化。
首先,我们将为iOS和Android添加两个独立的工作流程。在项目的根层,我们将创建一个.github 文件夹;在这个文件夹下,我们将创建另一个名为workflows 的文件夹。然后,我们将为iOS版本添加ios_release.yml ,为Android版本添加android_release.yml 到.github > workflows 文件夹。
mkdir .github && cd .github && mkdir workflows && cd workflows && touch andriod_release.yml && touch ios_release.yml
定义GitHub Actions工作流程
我们将定义GitHub Actions的工作流程,像这样:
on:
push:
tags:
- 'android*'
当我们添加一个包含android 关键字的标签时,Android 版本的构建将开始,如上文所定义。下面是一个例子:
git tag -a 'versions' -m "andriod release"
为Android发布工作流程定义了两个作业,一个是测试版,一个是Google Play版。
接下来,我们将定义最新版本的Ubuntu虚拟机来运行GitHub Actions的工作流程:
name: Build and deploy Android release
on:
push:
tags:
- 'android*'
jobs:
testFlight-build:
name: android-beta-build
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [12.x]
steps:
- uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: Checkout to git repository
uses: actions/checkout@v2
- name: Install dependencies
run: |
yarn install
- name: Install Fastlane
uses: actions/setup-ruby@v1
with:
ruby-version: 2.6
- name: Install npm dependencies
run: |
yarn install
- name: Install Fastlane
run: |
bundle install
bundle update fastlane
- name: Build and upload to TestFlight
run: |
bundle exec fastlane android beta
env:
ANDROID_KEYSTORE_FILE: ${{ secrets.ANDROID_KEYSTORE_FILE }}
ANDROID_KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }}
ANDROID_KEYSTORE_ALIAS: ${{ secrets.ANDROID_KEYSTORE_ALIAS }}
ANDROID_KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }}
release-build:
name: Android-release-build
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [12.x]
steps:
- uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: Checkout to git repository
uses: actions/checkout@v2
- name: Install dependencies
run: |
yarn install
- name: Install Fastlane
uses: actions/setup-ruby@v1
with:
ruby-version: 2.6
- name: Install npm dependencies
run: |
yarn install
- name: Install Fastlane
run: |
bundle install
bundle update fastlane
- name: release-build
run: |
bundle exec fastlane android release
env:
ANDROID_KEYSTORE_FILE: ${{ secrets.ANDROID_KEYSTORE_FILE }}
ANDROID_KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }}
ANDROID_KEYSTORE_ALIAS: ${{ secrets.ANDROID_KEYSTORE_ALIAS }}
ANDROID_KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }}
在上面的代码中,我们定义了一系列的步骤,这些步骤是由GitHub市场提供的或由社区支持的预定义动作。
我们在接下来的一系列事件中加入了安装npm依赖项、添加所需的Node.js版本和安装fastlane的步骤,如上面的代码所示。
最后,我们为测试版和发布版的工作运行fastlane构建。我们还使用GitHub Actions Secrets来定义构建工作流程中需要的环境变量。
为Github Actions创建和存储秘密
加密的秘密允许我们存储敏感信息。我们可以把我们的环境变量、密钥和密码作为加密的秘密添加到GitHub repo中。仓库的秘密将被放在 repo 上的任何工作流程所访问。
要添加秘密,请进入 repo 的设置菜单。在Secrets>Actions部分(左侧导航),点击New repository secret按钮(右上角)来添加新的秘密。
为Android和iOS应用程序添加秘密,在整个过程中需要在上传前正确签署你的应用程序:

定义iOS的工作流程
如前所述,我们通过在.github > workflows 文件夹下创建一个不同的ios release.yml 文件来分离iOS和Android版本。当我们添加一个包含ios 关键词的标签时,iOS版本的构建将开始。
下面是一个例子:
git tag -a 'versions' -m "ios release"
对于iOS版本,我们将指定两个作业:一个用于TestFlight版本,一个用于App Store版本。
接下来,我们将定义最新版本的macos-latest 虚拟机来运行iOS发布的GitHub Actions工作流:
name: Build and deploy iOS release
on:
push:
tags:
- 'ios*'
jobs:
testFlight-build:
name: iOS-testFlight-build
runs-on: macos-latest
strategy:
matrix:
node-version: [12.x]
steps:
- uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: Checkout to git repository
uses: actions/checkout@v2
- name: Install dependencies
run: |
yarn install
- name: Install Fastlane
uses: actions/setup-ruby@v1
with:
ruby-version: 2.6
- name: Install npm dependencies
run: |
yarn install
- name: Install Fastlane
run: |
bundle install
bundle update fastlane
- name: Build and upload to TestFlight
run: |
bundle exec fastlane ios beta
env:
APPLE_ID: ${{ secrets.APPLE_ID }}
APP_STORE_EMAIL: ${{ secrets.APP_STORE_EMAIL }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
IOS_DISTRIBUTION_CERTS_GITHUB_URL: ${{ secrets.IOS_DISTRIBUTION_CERTS_GITHUB_URL }}
MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
release-build:
name: iOS-testFlight-build
runs-on: macos-latest
strategy:
matrix:
node-version: [12.x]
steps:
- uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: Checkout to git repository
uses: actions/checkout@v2
- name: Install dependencies
run: |
yarn install
- name: Install Fastlane
uses: actions/setup-ruby@v1
with:
ruby-version: 2.6
- name: Install npm dependencies
run: |
yarn install
- name: Install Fastlane
run: |
bundle install
bundle update fastlane
- name: Build and upload to TestFlight
run: |
bundle exec fastlane ios beta
env:
APPLE_ID: ${{ secrets.APPLE_ID }}
APP_STORE_EMAIL: ${{ secrets.APP_STORE_EMAIL }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
IOS_DISTRIBUTION_CERTS_GITHUB_URL: ${{ secrets.IOS_DISTRIBUTION_CERTS_GITHUB_URL }}
MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
现在,我们定义一系列的步骤来安装npm依赖项,添加所需的Node.js版本,并在接下来的一系列事件中安装fastlane,如上面的代码所示。
最后,我们为TestFlight版本运行fastlane构建。我们使用GitHub Actions Secrets来定义构建工作流程中需要的环境变量。
总结
在这篇文章中,我们演示了如何在React Native项目中设置fastlane。一起使用fastlane和GitHub Actions可以简化iOS和Android应用的构建和发布,并改善构建、测试和发布分布的部署管道。