Skip to main content

Flutter 的持续交付

遵循 Flutter 的持续交付最佳实践,确保您的应用程序能够频繁地交付给测试人员并在频繁的基础上进行验证,而无需依赖手动工作流程。

CI/CD 选项

#

有多种持续集成 (CI) 和持续交付 (CD) 选项可用于帮助自动化应用程序的交付。

具有内置 Flutter 功能的一体化选项

#

将 fastlane 与现有工作流程集成

#

您可以将 fastlane 与以下工具一起使用:

本指南介绍如何设置 fastlane,然后将其与您现有的测试和持续集成 (CI) 工作流程集成。更多信息,请参阅“将 fastlane 与现有工作流程集成”。

fastlane

#

fastlane 是一款开源工具套件,用于自动化应用程序的发布和部署。

本地设置

#

建议您在迁移到基于云的系统之前在本地测试构建和部署过程。您也可以选择从本地计算机执行持续交付。

  1. 安装 fastlane gem install fastlanebrew install fastlane。访问 fastlane 文档 获取更多信息。
  2. 创建一个名为 FLUTTER_ROOT 的环境变量,并将其设置为 Flutter SDK 的根目录。(这是 iOS 部署脚本所需的。)
  3. 创建您的 Flutter 项目,准备好后,确保您的项目可以通过以下方式构建:
    • Android flutter build appbundle;以及
    • iOS flutter build ipa
  4. 为每个平台初始化 fastlane 项目。
    • Android 在您的 [project]/android 目录中,运行 fastlane init
    • iOS 在您的 [project]/ios 目录中,运行 fastlane init
  5. 编辑 Appfile 以确保它们包含您应用的足够元数据。
    • Android 检查 [project]/android/fastlane/Appfile 中的 package_name 是否与 AndroidManifest.xml 中的包名称匹配。
    • iOS 检查 [project]/ios/fastlane/Appfile 中的 app_identifier 是否也与 Info.plist 的 bundle 标识符匹配。使用您各自的帐户信息填写 apple_iditc_team_idteam_id
  6. 设置您在应用商店的本地登录凭据。
    • Android 按照 供应设置步骤 操作,并确保 fastlane supply init 成功同步来自您 Play 商店控制台的数据。将 .json 文件视为您的密码,不要将其检入任何公共源代码控制存储库中。
    • iOS 您的 iTunes Connect 用户名已在您的 Appfileapple_id 字段中。使用您的 iTunes Connect 密码设置 FASTLANE_PASSWORD shell 环境变量。否则,上传到 iTunes/TestFlight 时会提示您输入密码。
  7. 设置代码签名。
    • Android 按照 Android 应用签名步骤 操作。
    • iOS 在 iOS 上,当您准备好使用 TestFlight 或 App Store 进行测试和部署时,请使用分发证书而不是开发证书创建和签名。
      • 在您的 Apple 开发者帐户控制台 中创建并下载分发证书。
      • open [project]/ios/Runner.xcworkspace/ 并选择目标设置窗格中的分发证书。
  8. 为每个平台创建一个 Fastfile 脚本。
    • Android 在 Android 上,请按照 fastlane Android 测试版部署指南 操作。您的编辑可以像添加一个调用 upload_to_play_storelane 一样简单。将 aab 参数设置为 ../build/app/outputs/bundle/release/app-release.aab 以使用 flutter build 已构建的应用包。

    • iOS 在 iOS 上,请按照 fastlane iOS 测试版部署指南 操作。您可以指定存档路径以避免重建项目。例如:

      ruby
      build_app(
        skip_build_archive: true,
        archive_path: "../build/ios/archive/Runner.xcarchive",
      )
      upload_to_testflight

您现在可以准备在本地执行部署或将部署过程迁移到持续集成 (CI) 系统。

在本地运行部署

#
  1. 构建发布模式应用程序。
    • Android flutter build appbundle
    • iOS flutter build ipa
  2. 在每个平台上运行 Fastfile 脚本。
    • Android cd android 然后 fastlane [您创建的 lane 名称]
    • iOS cd ios 然后 fastlane [您创建的 lane 名称]

云构建和部署设置

#

首先,按照“本地设置”中描述的本地设置部分进行操作,确保在迁移到 Travis 等云系统之前该过程有效。

主要需要考虑的是,由于云实例是短暂且不受信任的,因此您不会将 Play 商店服务帐户 JSON 或您的 iTunes 分发证书等凭据留在服务器上。

持续集成 (CI) 系统通常支持加密的环境变量来存储私有数据。您可以在构建应用程序时使用 --dart-define MY_VAR=MY_VALUE 传递这些环境变量。

注意不要将这些变量值重新回显到测试脚本中的控制台中。在合并到主分支之前,这些变量在拉取请求中也是不可用的,以确保恶意行为者无法创建打印这些秘密信息的拉取请求。请谨慎处理您接受和合并的拉取请求中与这些秘密相关的交互。

  1. 使登录凭据成为短暂的。

    • Android 在 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 在 iOS 上:
      • 移动本地环境变量 FASTLANE_PASSWORD 以在 CI 系统上使用加密的环境变量。
      • CI 系统需要访问您的分发证书。建议使用 fastlane 的 Match 系统来同步您跨机器的证书。
  2. 建议使用 Gemfile,而不是在每次 CI 系统上使用不确定的 gem install fastlane,以确保 fastlane 依赖项在本地和云机器之间稳定且可重现。但是,此步骤是可选的。

    • 在您的 [project]/android[project]/ios 文件夹中,创建一个包含以下内容的 Gemfile
      source "https://rubygems.org"
      
      gem "fastlane"
    • 在这两个目录中,运行 bundle update 并将 GemfileGemfile.lock 都检入源代码控制。
    • 在本地运行时,使用 bundle exec fastlane 代替 fastlane
  3. 在您的存储库根目录中创建 CI 测试脚本,例如 .travis.yml.cirrus.yml

    • 请参阅 fastlane CI 文档 了解 CI 特定的设置。
    • 将脚本分成碎片以便在 Linux 和 macOS 平台上运行。
    • 在 CI 任务的设置阶段,执行以下操作:
      • 使用 gem install bundler 确保 Bundler 可用。
      • [project]/android[project]/ios 中运行 bundle install
      • 确保 Flutter SDK 可用并在 PATH 中设置。
      • 对于 Android,请确保 Android SDK 可用且已设置 ANDROID_SDK_ROOT 路径。
      • 对于 iOS,您可能需要指定对 Xcode 的依赖项(例如,osx_image: xcode9.2)。
    • 在 CI 任务的脚本阶段:
      • 运行 flutter build appbundleflutter build ios --release --no-codesign,具体取决于平台。
      • cd androidcd ios
      • bundle exec fastlane [lane 名称]

Xcode Cloud

#

Xcode Cloud 是一款持续集成和交付服务,用于构建、测试和分发适用于 Apple 平台的应用程序和框架。

要求

#

自定义构建脚本

#

Xcode Cloud 识别 自定义构建脚本,这些脚本可用于在指定时间执行其他任务。它还包含一组 预定义的环境变量,例如 $CI_WORKSPACE,它表示已克隆存储库的位置。

克隆后脚本

#

利用克隆后自定义构建脚本,该脚本在 Xcode Cloud 克隆您的 Git 存储库后运行,请按照以下说明操作:

ios/ci_scripts/ci_post_clone.sh 中创建一个文件并添加以下内容。

sh
#!/bin/sh

# 如果任何子命令失败,则使此脚本失败。
set -e

# 此脚本的默认执行目录是 ci_scripts 目录。
cd $CI_PRIMARY_REPOSITORY_PATH # 将工作目录更改为已克隆存储库的根目录。

# 使用 git 安装 Flutter。
git clone https://github.com/flutter/flutter.git --depth 1 -b stable $HOME/flutter
export PATH="$PATH:$HOME/flutter/bin"

# 为 iOS (--ios) 或 macOS (--macos) 平台安装 Flutter 工件。
flutter precache --ios

# 安装 Flutter 依赖项。
flutter pub get

# 使用 Homebrew 安装 CocoaPods。
HOMEBREW_NO_AUTO_UPDATE=1 # 禁用 homebrew 的自动更新。
brew install cocoapods

# 安装 CocoaPods 依赖项。
cd ios && pod install # 在 `ios` 目录中运行 `pod install`。

exit 0

此文件应添加到您的 Git 存储库中并标记为可执行文件。

git add --chmod=+x ios/ci_scripts/ci_post_clone.sh

工作流程配置

#

Xcode Cloud 工作流程 定义了触发工作流程时在 CI/CD 过程中执行的步骤。

要在 Xcode 中创建新的工作流程,请按照以下说明操作:

  1. 选择产品 > Xcode Cloud > 创建工作流程 以打开 创建工作流程窗口。

  2. 选择工作流程应附加到的产品(应用程序),然后单击 下一步 按钮。

  3. 下一个窗口显示 Xcode 提供的默认工作流程概述,可以通过单击 编辑工作流程 按钮进行自定义。

分支更改

#

默认情况下,Xcode 建议使用“分支更改”条件,该条件会为 Git 存储库默认分支的每次更改启动新的构建。

对于您的应用的 iOS 版本,合理的做法是希望 Xcode Cloud 在您更改 Flutter 包或修改 lib\ios\ 目录内的 Dart 或 iOS 源文件后触发您的工作流程。

这可以通过使用以下文件和文件夹条件来实现:

Xcode 工作流程分支更改

下一个构建编号

#

Xcode Cloud 将新工作流程的构建编号默认为 1,并在每次成功构建后递增。如果您使用的是具有更高构建编号的现有应用程序,则需要配置 Xcode Cloud 以使用其构建的正确构建编号,只需在迭代中指定 下一个构建编号 即可。

查看 设置 Xcode Cloud 构建的下一个构建编号 了解更多信息。