Flutter 里的持续部署
通过 Flutter 持续交付的最佳实践,确保您的应用程序交付给您的 Beta 版本测试人员并能够频繁予以验证,而无需借助手动工作流程。
Follow continuous delivery best practices with Flutter to make sure your application is delivered to your beta testers and validated on a frequent basis without resorting to manual workflows.
fastlane
本指南介绍了如何将开源工具套件 fastlane 与您现有的测试和持续集成(CI)工作流程(比如 Travis 或 Cirrus)整合在一起。
This guide shows how to integrate fastlane, an open-source tool suite, with your existing testing and continuous integration (CI) workflows (for example, Travis or Cirrus).
本地设置
Local setup
建议在迁移到基于云计算的系统之前,先在本地测试其构建和部署流程。您还可以使用本地机器执行连续交付。
It’s recommended that you test the build and deployment process locally before migrating to a cloud-based system. You could also choose to perform continuous delivery from a local machine.
-
安装 fastlane
gem install fastlane
或brew install fastlane
。访问 fastlane docs 以获得更多信息。Install fastlane
gem install fastlane
orbrew install fastlane
. Visit the fastlane docs for more info. -
创建您的 Flutter 项目,准备就绪后,确保通过如下途径构建项目:
Create your Flutter project, and when ready, make sure that your project builds via
-
flutter build appbundle
; 以及 -
flutter build ios --release --no-codesign
.
-
-
初始化各平台的 fastlane 项目:
Initialize the fastlane projects for each platform.
-
:在
[project]/android
目录中,运行fastlane init
命令。In your
[project]/android
directory, runfastlane init
. -
:在
[project]/ios
目录下,运行fastlane init
命令。In your
[project]/ios
directory, runfastlane init
.
-
-
编辑
Appfile
以确保它有应用程序的基本数据配置:Edit the
Appfile
s to ensure they have adequate metadata for your app.-
检查在
[project]/android/fastlane/Appfile
文件中的package_name
是否匹配在 AndroidManifest.xml 中的包名。Check that
package_name
in[project]/android/fastlane/Appfile
matches your package name in AndroidManifest.xml. -
检查在
[project]/ios/fastlane/Appfile
中的app_identifier
是否匹配 Info.plist 文件中的 bundle identifier.Check that
app_identifier
in[project]/ios/fastlane/Appfile
also matches Info.plist’s bundle identifier. Fill inapple_id
,itc_team_id
,team_id
with your respective account info.
-
-
设置应用商店的本地登录凭据。
Set up your local login credentials for the stores.
-
按照 Supply setup steps 文档操作,并且确保
fastlane supply init
成功同步了你在 Google Play 商店控制台中的数据。 .json 文件与密码一样重要,切勿将其公开在任何公共源代码控制存储库。Follow the Supply setup steps and ensure that
fastlane supply init
successfully syncs data from your Play Store console. Treat the .json file like your password and do not check it into any public source control repositories. -
iTunes Connect 用户名已经存在于您的
Appfile
的apple_id
字段中,你需要将你的 iTunes 密码设置到FASTLANE_PASSWORD
这个环境变量里。否则,上传到 iTunes/TestFlight时会提示你。Your iTunes Connect username is already in your
Appfile
’sapple_id
field. Set theFASTLANE_PASSWORD
shell environment variable with your iTunes Connect password. Otherwise, you’ll be prompted when uploading to iTunes/TestFlight.
-
-
设置代码签名。
Set up code signing.
-
在 Android 上有两种签名 key:发布签名和上传签名。最终用户下载的 .aab / .apk 文件使用发布签名。上传签名提供给开发者上传到 Google Play 商店的认证。上传后,Google Play 商店会重新使用发布签名对 .apk 文件签名。
On Android, there are two signing keys: deployment and upload. The end-users download the .apk signed with the ‘deployment key’. An ‘upload key’ is used to authenticate the .aab / .apk uploaded by developers onto the Play Store and is re-signed with the deployment key once in the Play Store.
-
强烈建议使用自动化的云端管理发布签名。更多信息请查看 [Google Play 官方说明][official Play Store documentation。
It’s highly recommended to use the automatic cloud managed signing for the deployment key. For more information, see the official Play Store documentation.
-
按照 密钥生成步骤 创建你自己的上传签名。
Follow the key generation steps to create your upload key.
-
配置 gradle:通过设置
[project]/android/app/build.gradle
文件下的
android.buildTypes.release
,当编译的时候在 release 模式下使用你自己的上传签名。Configure gradle to use your upload key when building your app in release mode by editing
android.buildTypes.release
in[project]/android/app/build.gradle
.
-
-
在iOS上,当您准备使用 TestFlight 或 App Store 进行测试和部署时,使用分发证书而不是开发证书进行创建和签名。
On iOS, create and sign using a distribution certificate instead of a development certificate when you’re ready to test and deploy using TestFlight or App Store.
-
在 Apple Developer Account console 创建并下载一个分发证书。
Create and download a distribution certificate in your Apple Developer Account console.
-
打开
[project]/ios/Runner.xcworkspace/
在你的项目设置里选择一个分发证书。open [project]/ios/Runner.xcworkspace/
and select the distribution certificate in your target’s settings pane.
-
-
-
给每个不同的平台创建一个
Fastfile
脚本。Create a
Fastfile
script for each platform.-
在 Android 上按照 fastlane Android beta deployment guide 指引操作。你可以简单的编辑一下文件,加一个名叫
upload_to_play_store
的lane
。为了使用flutter build
命令编译aab
,要把apk
参数设置为../build/app/outputs/bundle/release/app-release.aab
。On Android, follow the fastlane Android beta deployment guide. Your edit could be as simple as adding a
lane
that callsupload_to_play_store
. Set theaab
argument to../build/app/outputs/bundle/release/app-release.aab
to use the app bundleflutter build
already built. -
在 iOS 上,按照 fastlane iOS beta 部署指南 指引操作。你可以简单编辑一下文件,加一个名叫
build_ios_app
的lane
,并且同时调用export_method: 'app-store'
和upload_to_testflight
。在 iOS 上只有当要编译成 .app 的时候才会用到flutter build
,其他情况用不到。On iOS, follow the fastlane iOS beta deployment guide. Your edit could be as simple as adding a
lane
that callsbuild_ios_app
withexport_method: 'app-store'
andupload_to_testflight
. On iOS an extra build is required sinceflutter build
builds an .app rather than archiving .ipas for release.
-
你现在已准备好在本地执行部署或将部署过程迁移到持续集成(CI)系统。
You’re now ready to perform deployments locally or migrate the deployment process to a continuous integration (CI) system.
Running deployment locally
在本地运行部署
-
构建发布模式的应用:
Build the release mode app.
-
flutter build appbundle
. -
flutter build ios --release --no-codesign
.
这个时候不用签名,接下来 fastlane 会自动签名。
No need to sign now since fastlane will sign when archiving.
-
-
在每个平台上运行 Fastfile 脚本。
Run the Fastfile script on each platform.
-
cd android
thenfastlane [name of the lane you created]
. -
cd ios
thenfastlane [name of the lane you created]
.
-
Cloud build and deploy setup
云构建和部署设置
首先,按照“本地设置”中描述的本地设置部分,确保在迁移到 Travis 等云系统之前,该过程有效。
First, follow the local setup section described in ‘Local setup’ to make sure the process works before migrating onto a cloud system like Travis.
需要考虑的主要事项是,由于云实例是短暂且不可信的,因此你不能在服务器上保留你的凭据,如 Play Store 服务帐户 JSON 或 iTunes 分发证书。
The main thing to consider is that since cloud instances are ephemeral and untrusted, you won’t be leaving your credentials like your Play Store service account JSON or your iTunes distribution certificate on the server.
诸如 Cirrus 之类的持续集成(CI)系统通常支持加密的环境变量来存储私有数据。
Continuous Integration (CI) systems, such as Cirrus generally support encrypted environment variables to store private data.
采取预防措施,不要在测试脚本中将这些变量值重新回显到控制台。 在合并之前,这些变量在拉取请求中也不可用,以确保恶意行为者无法创建打印这些密钥的拉取请求。在接受和合并的 pull 请求中,请注意与这些密钥。
Take precaution not to re-echo those variable values back onto the console in your test scripts. Those variables are also not available in pull requests until they’re merged to ensure that malicious actors cannot create a pull request that prints these secrets out. Be careful with interactions with these secrets in pull requests that you accept and merge.
-
暂时性登录凭据。
Make login credentials ephemeral.
-
在 Android 上:
On Android:
-
从
Appfile
里删除json_key_file
并且在你的 CI 系统里的环境变量。在upload_to_play_store
里使用json_key_data
参数从环境变量读取到Fastfile
。Remove the
json_key_file
field fromAppfile
and store the string content of the JSON in your CI system’s encrypted variable. Use thejson_key_data
argument inupload_to_play_store
to read the environment variable directly in yourFastfile
. -
Serialize your upload key (for example, using base64) and save it as an encrypted environment variable. You can deserialize it on your CI system during the install phase with
序列化您的上传密钥(例如,使用base64)并将其另存为加密环境变量。可以可以在安装阶段在 CI 系统上对其进行反序列化
echo "$PLAY_STORE_UPLOAD_KEY" | base64 --decode > /home/cirrus/[directory # 在 gradle 中定义的文件夹和文件名].keystore
-
-
在 iOS 上:
On iOS:
-
将本地环境变量
FASTLANE_PASSWORD
转而使用 CI 系统的加密的环境变量。Move the local environment variable
FASTLANE_PASSWORD
to use encrypted environment variables on the CI system. -
CI 系统需要有权限拿到你的分发证书。建议使用fastlane 的 Match 系统在不同的机器上同步你的证书。
The CI system needs access to your distribution certificate. fastlane’s Match system is recommended to synchronize your certificates across machines.
-
-
-
建议每次使用 Gemfile 而不是
gem install fastlane
以避免其在 CI 系统上使用的不确定性,以确保 fastlane 依赖关系在本地和云计算机之间稳定且可重现。但是,此步骤是可选的。It’s recommended to use a Gemfile instead of using an indeterministic
gem install fastlane
on the CI system each time to ensure the fastlane dependencies are stable and reproducible between local and cloud machines. However, this step is optional.-
在
[project]/android
和[project]/ios
文件夹中,创建一个Gemfile
包含以下内容:In both your
[project]/android
and[project]/ios
folders, create aGemfile
containing the following content:source "https://rubygems.org" gem "fastlane"
-
在两个目录中,运行
bundle update
并将两者的Gemfile
和Gemfile.lock
文件纳入源代码管理。In both directories, run
bundle update
and check bothGemfile
andGemfile.lock
into source control. -
当你在本地运行的时候,请使用
bundle exec fastlane
而不是fastlane
。When running locally, use
bundle exec fastlane
instead offastlane
.
-
-
在你的仓库根目录创建一个 CI 测试脚本,例如:
.travis.yml
或.cirrus.yml
。Create the CI test script such as
.travis.yml
or.cirrus.yml
in your repository root.-
分开你的脚本以便能在 Linux 和 macOS 两个平台运行。
Shard your script to run on both Linux and macOS platforms.
-
请记住为 macOS 指定具体版本的 Xcode(例如 osx_image: xcode9.2)。
Remember to specify a dependency on Xcode for macOS (for example
osx_image: xcode9.2
). -
有关特定于 CI 的设置,请参见 fastlane CI 文档。
See fastlane CI documentation for CI specific setup.
-
在设置阶段,根据平台,确保以下几点:
During the setup phase, depending on the platform, make sure that:
-
Bundler 可以使用
gem install bundler
。Bundler is available using
gem install bundler
. -
对于 Android 平台,请确保已经设置正确的
ANDROID_SDK_ROOT
环境变量。For Android, make sure the Android SDK is available and the
ANDROID_SDK_ROOT
path is set. -
在
[project]/android
或[project]/ios
目录下分别运行bundle install
命令。Run
bundle install
in[project]/android
or[project]/ios
. -
确保 Flutter SDK 已经正确了设置在了
PATH
环境变量中Make sure the Flutter SDK is available and set in
PATH
.
-
-
在 CI 任务的脚本阶段:
In the script phase of the CI task:
-
根据平台的不同可以运行
flutter build appbundle
或者flutter build ios --release --no-codesign
。Run
flutter build appbundle
orflutter build ios --release --no-codesign
, depending on the platform. -
然后执行
cd android
或cd ios
命令。cd android
orcd ios
. -
最后执行
bundle exec fastlane [name of the lane]
命令。bundle exec fastlane [name of the lane]
.
-
-
参考
Reference
Flutter repo 里的示例应用 Flutter Gallery 使用 fastlane 连续部署。有关 fastlane 实际运行示例,请参阅源代码。另请参阅 Flutter 框架仓库库的 Cirrus 脚本。
The Flutter Gallery Project uses fastlane for continuous deployment. See the source for a working example of fastlane in action. Also see the Flutter framework repository’s Cirrus script.
其他服务
Other services
其他关于如何进行持续交付的服务:
The following are some other options available to help automate the delivery of your application.