Flutter 里的持续部署
通过 Flutter 持续交付的最佳实践,确保你的应用程序交付给你的 Beta 版本测试人员并能够频繁予以验证,而无需借助手动工作流程。
CI/CD 选择
#有许多持续集成 (CI) 和持续交付 (CD) 的工具,帮助自动发布你的应用。
内置 Flutter 的多合一 (All-in-one) 选择:
#使用 Fastlane 与现有工作流程集成
#你可以通过下面的工具使用 fastlane:
这份指南展示了如何让设置 fastlane 以及将其集成到现有应用的测试和持续集成 (CI) 工作流当中去。更多相关的内容,请参考上面这部分的内容。
fastlane
#fastlane 是一个开源工具套件,帮助你自动的打包正式版以及部署你的应用。
本地设置
#建议在迁移到基于云计算的系统之前,先在本地测试其构建和部署流程。你还可以使用本地机器执行连续交付。
-
安装 fastlane
gem install fastlane
或brew install fastlane
。访问 fastlane docs 以获得更多信息。 -
创建一个名为
FLUTTER_ROOT
的环境变量,并将其设置为 Flutter SDK 的根目录。(这是为 iOS 部署的脚本所必需的。) -
创建你的 Flutter 项目,准备就绪后,确保通过如下途径构建项目:
-
flutter build appbundle
; and -
flutter build ipa
.
-
-
初始化各平台的 fastlane 项目:
-
:在
[project]/android
目录中,运行fastlane init
命令。 -
:在
[project]/ios
目录下,运行fastlane init
命令。
-
-
编辑
Appfile
以确保它有应用程序的基本数据配置:-
检查在
[project]/android/fastlane/Appfile
文件中的package_name
是否匹配在 AndroidManifest.xml 中的包名。 -
检查在
[project]/ios/fastlane/Appfile
中的app_identifier
是否匹配 Info.plist 文件中的 bundle identifier。将相应的apple_id
、itc_team_id
和team_id
输入进去。
-
-
设置应用商店的本地登录凭据。
-
按照 Supply setup steps 文档操作,并且确保
fastlane supply init
成功同步了你在 Google Play 商店控制台中的数据。 .json 文件与密码一样重要,切勿将其公开在任何公共源代码控制存储库。 -
iTunes Connect 用户名已经存在于你的
Appfile
的apple_id
字段中,你需要将你的 iTunes 密码设置到FASTLANE_PASSWORD
这个环境变量里。否则,上传到 iTunes/TestFlight时会提示你。
-
-
设置代码签名:
-
参考文档 为应用签名。
-
在iOS上,当你准备使用 TestFlight 或 App Store 进行测试和部署时,使用分发证书而不是开发证书进行创建和签名。
-
在 Apple Developer Account console 创建并下载一个分发证书。
-
打开
[project]/ios/Runner.xcworkspace/
在你的项目设置里选择一个分发证书。
-
-
-
给每个不同的平台创建一个
Fastfile
脚本。-
在 Android 上按照 fastlane Android beta deployment guide 指引操作。你可以简单的编辑一下文件,加一个名叫
upload_to_play_store
的lane
。为了使用flutter build
命令编译aab
,要把apk
参数设置为../build/app/outputs/bundle/release/app-release.aab
。 -
在 iOS 上,按照 fastlane iOS beta 部署指南 指引操作。你可以指定 archive 的路径以避免重复构建。例如:
rubybuild_app( skip_build_archive: true, archive_path: "../build/ios/archive/Runner.xcarchive", ) upload_to_testflight
-
你现在已准备好在本地执行部署或将部署过程迁移到持续集成(CI)系统。
在本地运行部署
#-
构建发布模式的应用:
-
flutter build appbundle
. -
flutter build ipa
.
-
-
在每个平台上运行 Fastfile 脚本。
-
cd android
然后fastlane [你创建的 lane 名称]
. -
cd ios
然后fastlane [你创建的 lane 名称]
.
-
云构建和部署设置
#首先,按照“本地设置”中描述的本地设置部分,确保在迁移到 Travis 等云系统之前,该过程有效。
需要考虑的主要事项是,由于云实例是短暂且不可信的,因此你不能在服务器上保留你的凭据,如 Play Store 服务帐户 JSON 或 iTunes 分发证书。
持续集成 (CI) 系统通常支持加密的环境变量来存储私有数据。你可以使用 --dart-define MY_VAR=MY_VALUE
在构建应用时传递环境变量。
采取预防措施,不要在测试脚本中将这些变量值重新回显到控制台。 在合并之前,这些变量在拉取请求中也不可用,以确保恶意行为者无法创建打印这些密钥的拉取请求。在接受和合并的 pull 请求中,请注意与这些密钥。
-
临时登录凭据。
-
在 Android 上:
-
从
Appfile
中删除json_key_file
并将其存储在 CI 系统的加密变量里。从Fastfile
中直接读取这些环境变量。upload_to_play_store( ... json_key_data: ENV['<variable name>'] )
-
序列化你的上传密钥(例如,使用 base64)并将其另存为加密环境变量。可以可以在安装阶段在 CI 系统上对其进行反序列化
bashecho "$PLAY_STORE_UPLOAD_KEY" | base64 --decode > [path to your upload keystore]
-
-
在 iOS 上:
-
将本地环境变量
FASTLANE_PASSWORD
转而使用 CI 系统的加密的环境变量。 -
CI 系统需要有权限拿到你的分发证书。建议使用fastlane 的 Match 系统在不同的机器上同步你的证书。
-
-
-
建议每次使用 Gemfile 而不是
gem install fastlane
以避免其在 CI 系统上使用的不确定性,以确保 fastlane 依赖关系在本地和云计算机之间稳定且可重现。但是,此步骤是可选的。-
在
[project]/android
和[project]/ios
文件夹中,创建一个Gemfile
包含以下内容:source "https://rubygems.org" gem "fastlane"
-
在两个目录中,运行
bundle update
并将两者的Gemfile
和Gemfile.lock
文件纳入源代码管理。 -
当你在本地运行的时候,请使用
bundle exec fastlane
而不是fastlane
。
-
-
在你的仓库根目录创建一个 CI 测试脚本,例如:
.travis.yml
或.cirrus.yml
。-
有关特定于 CI 的设置,请参见 fastlane CI 文档。
-
分开你的脚本以便能在 Linux 和 macOS 两个平台运行。
-
在 CI 的设置阶段,执行下列内容:
-
通过执行
gem install bundler
确保 Bundler 可用。 -
在
[project]/android
或[project]/ios
目录下分别运行bundle install
命令。 -
确保 Flutter SDK 已经正确了设置在了
PATH
环境变量中。 -
在 Android 平台上,请确保已经设置正确的
ANDROID_SDK_ROOT
环境变量。 -
在 iOS 平台上,你需要为 Xcode 指定依赖 (比如:
osx_image: xcode9.2
)
-
-
在 CI 任务的脚本阶段:
-
根据平台的不同可以运行
flutter build appbundle
或者flutter build ios --release --no-codesign
。 -
然后执行
cd android
或cd ios
命令。 -
最后执行
bundle exec fastlane [name of the lane]
命令。
-
-
Xcode Cloud
#Xcode Cloud 是一项为分发 Apple 平台的持续构建集成并交付,以及测试分发的服务。
需要准备的
#-
Xcode 13.4.1 或更高版本。
-
加入 Apple 开发者计划。
自定义构建脚本
#Xcode Cloud 可以识别 自定义的构建脚本 用于在特定阶段执行额外的任务。同时它还包含了一系列 预定义的环境变量,例如用于你 clone 仓库地址的 $CI_WORKSPACE
。
Post-clone 脚本
#利用 post-clone 运行的自定义构建脚本 Xcode Cloud 按照以下说明克隆你的 Git 仓库:
在 ios/ci_scripts/ci_post_clone.sh
创建一个文件,然后添加下面的内容。
#!/bin/sh
# Fail this script if any subcommand fails.
set -e
# The default execution directory of this script is the ci_scripts directory.
cd $CI_PRIMARY_REPOSITORY_PATH # change working directory to the root of your cloned repo.
# Install Flutter using git.
git clone https://github.com/flutter/flutter.git --depth 1 -b stable $HOME/flutter
export PATH="$PATH:$HOME/flutter/bin"
# Install Flutter artifacts for iOS (--ios), or macOS (--macos) platforms.
flutter precache --ios
# Install Flutter dependencies.
flutter pub get
# Install CocoaPods using Homebrew.
HOMEBREW_NO_AUTO_UPDATE=1 # disable homebrew's automatic updates.
brew install cocoapods
# Install CocoaPods dependencies.
cd ios && pod install # run `pod install` in the `ios` directory.
exit 0
该文件需要加入 git 仓库管理,并给予可执行权限。
git add --chmod=+x ios/ci_scripts/ci_post_clone.sh
工作流配置
#Xcode Cloud workflow 定义了你工作流触发时 CI/CD 处理进程的执行步骤。
要在 Xcode 中创建一个工作流,请参考以下步骤:
-
选择 Product > Xcode Cloud > Create Workflow 以打开 Create Workflow 菜单。
-
选择工作流需要作用的生产应用,然后点击 Next 按钮。
-
下一步,菜单将会展示一个 Xcode 提供的默认工作流的浮层,然后可以通过点击 Edit Workflow 按钮进行定制。
变更分支
#默认 Xcode 建议每次分支变更后都为你仓库的默认分支开始一个全新的构建。
对于你应用的 iOS 变体,你通常会希望 Xcode Cloud 在对你的
Flutter packages 修改了 lib\
中的 Dart 或 ios\
中的 iOS 源文件目录之后,触发你的工作流。
这可以通过使用下列文件和文件夹条件来实现:
下次构建的构建版本数字
#Xcode Cloud 对于新的工作流来说默认的构建版本数字是 1
,然后在每次成功构建后递增。如果你已经在一个已有应用中,使用了一个更高的构建版本数字,你需要配置 Xcode Cloud 使用正确的构建版本数字,只需要简单通过指定 Next Build Number
用于迭代即可。
你可以在 设置 Xcode Cloud 构建下一次的构建版本数字 查看更多信息。
除非另有说明,本文档之所提及适用于 Flutter 的最新稳定版本,本页面最后更新时间: 2024-07-03。 查看文档源码 或者 为本页面内容提出建议。