使用 Flutter 进行持续交付
遵循 Flutter 持续交付的最佳实践,确保您的应用程序能够频繁交付给 Beta 测试人员并进行验证,而无需依赖手动工作流程。
CI/CD 选项
#有多种持续集成 (CI) 和持续交付 (CD) 选项可用于帮助自动化您的应用程序交付。
内置 Flutter 功能的一体化选项
#将 fastlane 与现有工作流程集成
#您可以使用 fastlane 与以下工具集成
本指南将展示如何设置 fastlane,然后将其与您现有的测试和持续集成 (CI) 工作流程集成。有关更多信息,请参阅“将 fastlane 与现有工作流程集成”。
fastlane
#fastlane 是一个开源工具套件,用于自动化您的应用程序发布和部署。
本地设置
#建议您在迁移到基于云的系统之前,先在本地测试构建和部署过程。您也可以选择从本地机器执行持续交付。
- 安装 fastlane:
gem install fastlane
或brew install fastlane
。访问 fastlane 文档了解更多信息。 - 创建一个名为
FLUTTER_ROOT
的环境变量,并将其设置为 Flutter SDK 的根目录。(iOS 部署脚本需要此变量。) - 创建您的 Flutter 项目,准备就绪后,确保您的项目可以通过以下方式构建:
flutter build appbundle
;和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 的捆绑包标识符匹配。用您各自的账户信息填写apple_id
、itc_team_id
、team_id
。
- 设置商店的本地登录凭据。
遵循 Supply 设置步骤,并确保
fastlane supply init
成功地从您的 Play Store 控制台同步数据。请将 .json 文件视为您的密码,不要将其提交到任何公共源代码控制仓库。您的 iTunes Connect 用户名已在
Appfile
的apple_id
字段中。设置FASTLANE_PASSWORD
shell 环境变量为您的 iTunes Connect 密码。否则,当您上传到 iTunes/TestFlight 时会弹出提示。
- 设置代码签名。
遵循 Android 应用程序签名步骤。
在 iOS 上,当您准备使用 TestFlight 或 App Store 进行测试和部署时,请使用分发证书而不是开发证书进行创建和签名。
- 在您的 Apple Developer Account 控制台中创建并下载分发证书。
open [project]/ios/Runner.xcworkspace/
并在您的目标设置窗格中选择分发证书。
- 为每个平台创建
Fastfile
脚本。在 Android 上,遵循 fastlane Android Beta 部署指南。您的编辑可以很简单,只需添加一个调用
upload_to_play_store
的lane
。将aab
参数设置为../build/app/outputs/bundle/release/app-release.aab
以使用flutter build
已构建的应用程序包。在 iOS 上,遵循 fastlane iOS Beta 部署指南。您可以指定归档路径以避免重建项目。例如:
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
传递这些环境变量。
请注意不要在您的测试脚本中将这些变量值重新回显到控制台。这些变量在拉取请求中也不可用,直到它们被合并,以确保恶意行为者无法创建打印出这些秘密的拉取请求。在您接受和合并的拉取请求中处理这些秘密时要小心。
使登录凭据具有瞬时性。
在 Android 上
- 从
Appfile
中删除json_key_file
字段,并将 JSON 的字符串内容存储在您的 CI 系统的加密变量中。直接在Fastfile
中读取环境变量。upload_to_play_store( ... json_key_data: ENV['<variable name>'] )
- 序列化您的上传密钥(例如,使用 base64)并将其保存为加密环境变量。您可以在安装阶段通过以下方式在 CI 系统上反序列化它:bash
echo "$PLAY_STORE_UPLOAD_KEY" | base64 --decode > [path to your upload keystore]
- 从
在 iOS 上
- 将本地环境变量
FASTLANE_PASSWORD
移动到 CI 系统上使用加密环境变量。 - CI 系统需要访问您的分发证书。推荐使用 fastlane 的 Match 系统来同步您机器间的证书。
- 将本地环境变量
建议使用 Gemfile,而不是每次都在 CI 系统上使用不确定的
gem install fastlane
,以确保 fastlane 依赖项在本地和云机器之间稳定且可重现。但是,此步骤是可选的。- 在您的
[project]/android
和[project]/ios
文件夹中,都创建一个包含以下内容的Gemfile
:source "https://rubygems.org.cn" gem "fastlane"
- 在两个目录中,运行
bundle update
并将Gemfile
和Gemfile.lock
都提交到源代码控制。 - 在本地运行时,使用
bundle exec fastlane
而不是fastlane
。
- 在您的
在您的仓库根目录中创建 CI 测试脚本,例如
.travis.yml
或.cirrus.yml
。- 请参阅 fastlane CI 文档以获取 CI 特定的设置。
- 将您的脚本分片以在 Linux 和 macOS 平台上运行。
- 在 CI 任务的设置阶段,执行以下操作:
- 确保 Bundler 可用,使用
gem install bundler
。 - 在
[project]/android
或[project]/ios
中运行bundle install
。 - 确保 Flutter SDK 可用并已设置在
PATH
中。 - 对于 Android,请确保 Android SDK 可用且已设置
ANDROID_SDK_ROOT
路径。 - 对于 iOS,您可能需要指定对 Xcode 的依赖(例如,
osx_image: xcode9.2
)。
- 确保 Bundler 可用,使用
- 在 CI 任务的脚本阶段:
- 根据平台,运行
flutter build appbundle
或flutter build ios --release --no-codesign --config-only
。 cd android
或cd ios
bundle exec fastlane [lane 名称]
- 根据平台,运行
Xcode Cloud
#Xcode Cloud 是一个持续集成和交付服务,用于构建、测试和分发 Apple 平台上的应用和框架。
要求
#- Xcode 13.4.1 或更高版本。
- 已加入 Apple Developer Program。
自定义构建脚本
#Xcode Cloud 识别 自定义构建脚本,可用于在指定时间执行额外任务。它还包含一组预定义的环境变量,例如 $CI_WORKSPACE
,它是您克隆仓库的位置。
克隆后脚本
#利用以下说明在 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 工作流程 定义了当您的工作流程被触发时,CI/CD 过程中执行的步骤。
要在 Xcode 中创建新工作流程,请使用以下说明:
选择 Product > Xcode Cloud > Create Workflow 以打开 Create Workflow 工作表。
选择工作流程应附加的产品(应用),然后点击 Next 按钮。
下一个工作表显示 Xcode 提供的默认工作流程概述,可以通过点击 Edit Workflow 按钮进行自定义。
分支更改
#默认情况下,Xcode 建议使用“分支更改”条件,该条件会在 Git 仓库默认分支的每次更改时启动新的构建。
对于您应用的 iOS 变体,您很可能会希望 Xcode Cloud 在您更改 Flutter 包,或修改 lib\
和 ios\
目录中的 Dart 或 iOS 源文件后触发您的工作流程。
这可以通过使用以下文件和文件夹条件来实现:
下一个构建版本号
#Xcode Cloud 默认为新工作流程的构建版本号为 1
,并对每次成功构建进行递增。如果您正在使用现有应用程序且其构建版本号较高,则需要通过在迭代中指定“下一个构建版本号”来配置 Xcode Cloud 使用正确的构建版本号。
有关更多信息,请查阅“为 Xcode Cloud 构建设置下一个构建版本号”。