使用 Fastlane 和 Travis 交付 React Native 应用
原文发布于carloscuesta 的博客
一年前,我写了一篇文章,介绍 Fastlane 如何帮助我们改进React Native应用的发布流程。当时,尽管所有流程都已自动化,但部署 仍然需要我们中的一人拥有一台配置好的机器才能启动。我们可以通过持续集成(CI) 服务器来轻松改进 这个流程。这时,Travis CI就派上了用场!👷🏻♂️
过程
在解释问题所在之前,了解我们部署过程的复杂性非常重要。
简而言之,我们有两个平台:iOS 🍏、Android 🤖,每个平台都编译两个应用程序:Beta 测试应用程序(也称为Canary 🐤)和生产应用程序(🚀)。
基本上每个平台都会按顺序经过一个类似这样的通道👇
现在让我们深入了解部署过程的每一个步骤,以了解我们具体在做什么。
代码签名设置✍️
给原生应用签名真让人头疼😱,尤其是对于来自 JavaScript 生态系统的人来说。证书、配置文件、密钥……开发团队使用它们时必须做到井井有条。
我们通过Fastlane采用了codesigning.guide 的概念。这个概念的核心在于创建一个专门的Git 仓库来存储证书,并在开发团队内部进行分发。我们将iOS和Android 的代码签名文件都存储在一个加密的私有 Git 仓库中,该仓库位于 GitHub 上。
然后,我们的持续集成服务器会在每次部署时克隆代码仓库并安装解密后的证书。在iOS 平台上,持续集成服务器会创建一个OS X 钥匙串,并将证书安装到该钥匙串中。
版本管理🔖
原生构建和存储需要代码版本升级。
每个平台都有自己管理版本号和内部版本号的方式。两者的区别在于,版本号应用作公开的商店编号,用于标识新版本;而内部版本号是一个递增的标识符,每次构建都会增加。
Android 🤖
- 公开版本号:
versionName - 建造数量:
VERSION_CODE
iOS 🍏
- 公开版本号:
CFBundleShortVersionString - 建设数量:
CFBundleVersion和CURRENT_PROJECT_VERSION
这些属性存储在 package.json .plist、.pbxprojpackage.json.properties和.gradlepackage.json 文件中。为了实现自动化版本管理,我们使用package.json 中 的版本号作为公开版本号的权威来源💯。这使我们能够使用命令行工具来管理版本号的更新。npm version
原生构建📦
我们需要配置两台机器来构建和编译我们的本地应用程序。
对于iOS 开发,我们搭建了一个安装了Xcode 的macOS系统,因为这是编译和签名应用程序的唯一途径。对于Android 开发,我们配置了一个Linux系统,其中包含了所有需要的Android Studio 、软件包和工具。
这些机器是由我们的CI创建的,这意味着每次构建都在一个全新的、干净的环境中运行💻。
Beta 测试分发 🐤
为了将应用分发给Beta 测试人员,我们在iOS上使用TestFlight,在Android上使用HockeyApp。我们也尝试过Google Play Beta,但与 HockeyApp 相比,它的应用推送速度太慢了。
门店配送🚀
为了将应用分发到应用商店,我们会将生产版本上传到iOS 的TestFlight和Android的Google Play 商店。发布过程由人工完成。
Sourcemaps 🗺
为了获取易于理解的崩溃和错误信息,我们使用名为Bugsnag的服务。每次部署新版本时,我们都需要将调试符号和源映射上传 到 Bugsnag。 .dSYM
沟通🗣
最后,应用部署完成后,我们需要通知我们的Beta 测试人员、发布经理和开发人员,我们有了新版本。我们使用Slack,并借助一个机器人向特定频道发送提醒。
问题
每次发布 新版本,我们都必须手动启动Fastlane部署通道。这意味着需要人为干预。这是一个耗时的过程,而且经常因为代码签名、环境偏差、软件更新、原生平台依赖等问题而失败。
机器应该运转,人应该思考。
我们最终决定通过自动化所有流程来解决这些问题!
解决方案
解决方案是将这个自动化流程集成到一个系统中,该系统能够持续不断地将我们分店的推送信息master神奇地推送到各个门店🎉,让经理可以自由决定何时发布新品。终于,我们可以彻底放松,享受快乐了!❤️
现在我们将了解我们是如何将Travis和Fastlane集成起来 ,以实现应用程序的自动化部署的👏。
快速通道
我们有两条deployment流程,一条是 Android 流程,一条是 iOS 流程。为了便于解释,我稍微简化了一下流程,以便突出重点。我们首先部署 Android 平台,然后再部署 iOS 平台。
该通道 会收到一个来自 的版本package.json号,正如我之前所说,这使我们能够通过 npm 进行版本控制。
我们首先要做的是更新公开版本 号和内部版本号。在iOS开发方面,我们需要setup_certificates将它们保存到钥匙串中,以便能够对应用进行签名。
之后我们开始canary🐤和production🚀通道。这两个通道负责构建原生应用。
Canary:Beta 测试版本,发布到TestFlight和HockeyApp。Production:生产版本,已发布到TestFlight和Google Play 商店。
然后,我们将所有源映射和调试符号文件上传到Bugsnag。
接下来,我们创建一个Git 分支,用于提交版本更新,并通过lane进行提交commit_and_push_version_bump。之后,在 iOS lane 中,我们将创建的Git 分支合并到lane之上。我们需要提交这些更新,以确保版本与部署保持一致。否则,应用商店会报错,提示上传的版本已存在!mastergit_flow_merge
最后,我们通过Slack沟通这两个部署项目。
Android 🤖
lane :deployment do |version: version|
bump_version_number(version: version)
canary
production
sh 'npm run repositories:upload:android'
commit_and_push_version_bump
slack_notification(platform: 'Android', version: version)
end
iOS 🍏
lane :deployment do |version: version|
setup_certificates
bump_version_number(version: version)
canary
production
sh 'npm run repositories:upload:ios'
commit_and_push_version_bump
git_flow_merge(version: version)
slack_notification(platform: 'iOS', version: version)
end
master所以,这就是我们将分支合并到主分支并执行部署后的 git 日志的样子🙌:
特拉维斯CI
我们使用构建阶段,按顺序分三个步骤运行部署流程。这样,我们就可以仅在测试通过后才将应用程序部署到分支上✅。 master
让我们一起来看看构建阶段👇
每个构建阶段都有其自身的 配置和环境。例如,Deploy iOS一个构建阶段运行在安装了 Xcode 和 Node.js 的macOS 机器Deploy Android上,而另一个构建阶段则使用安装了JDK、AndroidSDK 和 Node.js 的Ubuntu 机器。
测试阶段✅
第一阶段,我们会执行代码检查和测试套件,以确保一切运行正常。如果此阶段出现任何问题,我们会自动停止部署。
- stage: Test and lint ✅
language: node_js
node_js: 8.5.0
install: yarn
script: npm run test:lint && npm run test:unit
Android 阶段🤖
Android 开发阶段会创建一个预装了所有必要软件和依赖项的 Ubuntu 服务器。然后,我们会构建 Canary 测试版 🐤 和生产版 🚀 应用。之后,我们会进行部署。大约 15 分钟 ⏰,我们的 Android 应用即可上线。👏
- stage: Deploy Android 🤖
if: branch = master AND type = push
language: android
jdk: oraclejdk8
android:
components:
- tools
- platform-tools
- android-26
- extra-google-m2repository
- extra-google-google_play_services
before_install:
- nvm install 8.5.0
- gem install bundler
- bundle install
before_script:
- ./internals/scripts/travis/gitconfig.sh
install: yarn
script: npm run deployment:android
iOS阶段🍏
iOS 开发阶段会创建一台已配置好Xcode 和所有必要依赖项 的 macOS 机器。然后我们构建 Canary 版 🐤 和生产版 🚀 应用。之后,我们进行部署。大约 20 分钟 ⏰ 后,我们的 iOS 应用即可发布。👏
- stage: Deploy iOS 🍏
if: branch = master AND type = push
language: node_js
node_js: 8.5.0
os: osx
osx_image: xcode9.2
before_install: bundle install
before_script:
- ./internals/scripts/travis/gitconfig.sh
install: yarn
script: npm run deployment:ios
吸取的教训
- 尽可能避免人为因素,实现一切自动化!
- 原生生态系统很复杂,有时会让人沮丧,你应该接受这一点。我们是 JavaScript 开发人员,所以这并非我们的专长,但有很多资源和文档可以提供帮助。
- 制定流程。
有任何问题吗?请在推特上@crloscuesta 向我提问。
文章来源:https://dev.to/carloscuesta/shipping-react-native-apps-with-fastlane-and-travis-1aea

