Flutter 的持续交付
如何自动化 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 的 bundle identifier 匹配。填写apple_id、itc_team_id、team_id以及您的相应帐户信息。
- 设置您的本地登录凭据以访问商店。
按照 Supply 设置步骤 操作,并确保 fastlane supply init成功同步来自您的 Play Store 控制台的数据。像对待您的密码一样对待 .json 文件,不要将其检入任何公共源代码控制存储库。
您的 iTunes Connect 用户名已在 Appfile的apple_id字段中。使用FASTLANE_PASSWORDshell 环境变量设置您的 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已经构建的 app bundle。
在 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 系统的加密环境变量。您可以在 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 iosbundle 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 中创建新的工作流程,请按照以下说明操作:
-
选择 产品 > Xcode Cloud > 创建工作流程 以打开 创建工作流程 表格。
-
选择工作流程应附加到的产品(应用程序),然后单击 下一步 按钮。
-
下一个表格显示了 Xcode 提供的默认工作流程的概述,可以通过单击 编辑工作流程 按钮进行自定义。
分支更改
#默认情况下,Xcode 建议分支更改条件,该条件会在您的 Git 存储库的默认分支发生任何更改时启动新的构建。
对于您应用的 iOS 版本,您希望 Xcode Cloud 在您修改 Flutter 包或修改 lib\ 和 ios\ 目录中的 Dart 或 iOS 源代码文件后触发您的工作流程,这是合理的。
这可以通过使用以下文件和文件夹条件来实现:
下一个构建编号
#Xcode Cloud 默认将新工作流程的构建编号设置为 1,并在每次成功构建后递增。如果您正在使用具有更高构建编号的现有应用,则需要配置 Xcode Cloud 以在其构建中使用正确的构建编号,只需在您的迭代中指定 Next Build Number 即可。
请查看 设置 Xcode Cloud 构建的下一个构建编号 以获取更多信息。