使用 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 的套件識別碼相符。使用您各自的帳戶資訊填寫 apple_iditc_team_idteam_id
  6. 設定您在商店中的本機登入憑證。
    • Android 遵循 Supply 設定步驟,並確保 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 進行測試和部署時,請使用發行憑證(而非開發憑證)建立並簽署。
  8. 為每個平台建立 Fastfile 腳本。
    • Android 在 Android 上,遵循 fastlane Android beta 部署指南。您的編輯可以像新增呼叫 upload_to_play_storelane 一樣簡單。將 aab 參數設定為 ../build/app/outputs/bundle/release/app-release.aab 以使用應用程式套件 flutter build 已建立。
    • iOS 在 iOS 上,遵循 fastlane iOS beta 部署指南。您可以指定封存路徑以避免重新建置專案。例如

      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 [您建立的通道名稱]
    • iOS cd ios 然後 fastlane [您建立的通道名稱]

雲端建置和部署設定

首先,按照「本機設定」中說明的本機設定區段,確保程序在移轉到 Travis 等雲端系統之前運作正常。

要考量的主要事項是,由於雲端執行個體為暫時且不可信,您不會將憑證(例如您的 Play 商店服務帳戶 JSON 或 iTunes 配發憑證)留在伺服器上。

持續整合 (CI) 系統通常支援加密環境變數,以儲存私人資料。您可以在建置應用程式時,使用 --dart-define MY_VAR=MY_VALUE 傳遞這些環境變數。

請小心不要在測試腳本中將這些變數值重新顯示到主控台上。這些變數在合併到 Pull Request 之前,也不可用於 Pull Request,以確保惡意行為者無法建立 Pull Request 來列印出這些機密。小心處理您接受和合併的 Pull Request 中與這些機密的互動。

  1. 讓登入憑證為暫時性。
    • Android 在 Android 上
      • Appfile 中移除 json_key_file 欄位,並將 JSON 的字串內容儲存在 CI 系統的加密變數中。直接在 Fastfile 中讀取環境變數。
        upload_to_play_store(
          ...
          json_key_data: ENV['<variable name>']
        )
        
      • 將上傳金鑰序列化(例如,使用 base64)並儲存為加密的環境變數。您可以在安裝階段使用以下指令在 CI 系統上取消序列化
        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 建立一個檔案,並新增以下內容。

#!/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 中建立新的工作流程,請使用下列說明

  1. 選取 產品 > Xcode Cloud > 建立工作流程 以開啟 建立工作流程 頁面。

  2. 選取工作流程應附加的產品 (應用程式),然後按一下 下一步 按鈕。

  3. 下一個頁面顯示 Xcode 提供的預設工作流程概觀,並可按一下 編輯工作流程 按鈕自訂。

分支變更

預設 Xcode 會建議分支變更條件,針對 Git 儲存庫預設分支的每個變更啟動新的建置。

對於應用程式的 iOS 變體,您希望 Xcode Cloud 在您變更 Flutter 套件後,或修改 lib\ios\ 目錄中的 Dart 或 iOS 原始檔後觸發工作流程,這是合理的。

這可以使用下列檔案和資料夾條件來達成

Xcode Workflow Branch Changes

下一個建置編號

Xcode Cloud 將新工作流程的建置編號預設為 1,並在每次建置成功時遞增。如果您使用的是建置編號較高的現有應用程式,您需要設定 Xcode Cloud 使用正確的建置編號來建置,方法是簡單地在您的迭代中指定 下一個建置編號

查看 設定 Xcode Cloud 建置的下一個建置編號 以取得更多資訊。