使用 Flutter 進行持續交付(Continuous Delivery)
遵循 Flutter 的持續交付(Continuous Delivery, CD)最佳實踐,確保你的應用程式能夠頻繁地交付給 Beta 測試者並進行驗證,而無需依賴手動工作流程。
CI/CD 選項
#有多種持續整合(Continuous Integration, CI)與持續交付(Continuous Delivery, CD)工具可用,以協助自動化你的應用程式交付流程。
內建 Flutter 功能的全方位解決方案
#將 fastlane 整合至現有工作流程
#你可以將 fastlane 與以下工具結合使用:
本指南將說明如何設定 fastlane,並將其整合到你現有的測試與持續整合(CI)工作流程中。更多資訊請參閱「Integrating fastlane with existing workflow」。
fastlane
#fastlane 是一套開源工具組,用於自動化應用程式的發佈與部署。
本地端設定
#建議你在遷移到雲端系統之前,先於本地端測試建置與部署流程。你也可以選擇直接在本地機器上執行持續交付。
- 安裝 fastlane
gem install fastlane或brew install fastlane。 請參閱 fastlane docs 以取得更多資訊。 - 建立一個名為
FLUTTER_ROOT的環境變數, 並將其設為你的 Flutter SDK 根目錄。 (這對於部署 iOS 的腳本來說是必要的。) - 建立你的 Flutter 專案,並在準備好後,確保你的專案可以透過
flutter build appbundle;以及
flutter build ipa進行建置。
- 為每個平台初始化 fastlane 專案。
在你的 [project]/android目錄中執行fastlane init。
在你的 [project]/ios目錄中, 執行fastlane init。
- 編輯
Appfile,以確保其中包含你應用程式所需的完整中繼資料。
檢查 package_name在[project]/android/fastlane/Appfile中是否與 AndroidManifest.xml 的套件名稱相符。
檢查 app_identifier在[project]/ios/fastlane/Appfile中是否也與 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 app signing steps。
在 iOS 上,當你準備好使用 TestFlight 或 App Store 進行測試與部署時,請建立並使用發佈(distribution)憑證來簽署,而非開發(development)憑證。- 請在你的 Apple Developer Account console 建立並下載發佈憑證。
open [project]/ios/Runner.xcworkspace/並在目標設定頁面選取發佈憑證。
- 為每個平台建立
Fastfile腳本。
在 Android 上,請參考 fastlane Android beta deployment guide。 你的修改可以很簡單,只需新增一個呼叫 upload_to_play_store的lane。 將aab參數設為../build/app/outputs/bundle/release/app-release.aab, 以使用已建置好的 app bundleflutter build。
在 iOS 上,請參考 fastlane iOS beta deployment guide。 你可以指定歸檔(archive)路徑,以避免重新建置專案。例如:rubybuild_app( skip_build_archive: true, archive_path: "../build/ios/archive/Runner.xcarchive", ) upload_to_testflight
你現在已經準備好可以在本地執行部署,或將部署流程遷移到持續整合(CI)系統。
在本地執行部署
#- 建立 release 模式的應用程式。
flutter build appbundle。
flutter build ipa。
- 在每個平台上執行 Fastfile 腳本。
cd android,然後fastlane [name of the lane you created]。
cd ios,然後fastlane [name of the lane you created]。
雲端建置與部署設定
#首先,請依照「Local setup」章節所述,先完成本地端的設定,確保流程可行,再遷移到如 Travis 這類雲端系統。
主要需要注意的是,因為雲端執行個體是短暫且不受信任的,你不應將 Play Store 服務帳戶的 JSON 憑證或 iTunes 發行憑證等憑證留在伺服器上。
持續整合(CI)系統通常支援加密環境變數來儲存私密資料。你可以在建置應用程式時,透過 --dart-define MY_VAR=MY_VALUE 傳遞這些環境變數。
請特別注意,不要在測試腳本中將這些變數值重新輸出到主控台。 這些變數在 pull request 尚未合併前也不會提供,以確保惡意人士無法建立會輸出這些機密的 pull request。請小心處理你接受並合併的 pull request 中與這些 secrets 的互動。
讓登入憑證成為短暫性(ephemeral)。
在 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" gem "fastlane" - 在兩個目錄中都執行
bundle update,並將Gemfile和Gemfile.lock一併提交到原始碼控制系統。 - 本機執行時,請使用
bundle exec fastlane取代fastlane。
- 在你的
在你的儲存庫根目錄建立 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 appbundle或flutter build ios --release --no-codesign --config-only。 cd android或cd iosbundle exec fastlane [name of the lane]
- 根據平台執行
Xcode Cloud
#Xcode Cloud 是一項持續整合與交付(CI/CD)服務,用於建置、 測試與發佈 Apple 平台上的應用程式與框架。
系統需求
#- Xcode 13.4.1 或更高版本。
- 必須加入 Apple Developer Program。
自訂建置腳本
#Xcode Cloud 支援 自訂建置腳本,可用於在指定時機執行額外任務。它同時包含一組 預設環境變數,例如 $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 工作流程 定義了當你的工作流程被觸發時,在 CI/CD 流程中所執行的步驟。
要在 Xcode 中建立新的工作流程,請依照以下指示操作:
選擇 Product > Xcode Cloud > Create Workflow,以開啟 Create Workflow 視窗。
選擇此工作流程應附加的產品(App),然後點擊 Next 按鈕。
下一個視窗會顯示 Xcode 提供的預設工作流程總覽, 你可以點擊 Edit Workflow 按鈕進行自訂。
分支變更
#預設情況下,Xcode 會建議使用 Branch Changes 條件,當你的 Git 儲存庫的預設分支有任何變更時,會啟動新的建置。
對於你的 App 的 iOS 版本,通常你會希望在修改 Flutter 套件,或是在 lib\ 和 ios\ 目錄下變更 Dart 或 iOS 原始碼檔案後,讓 Xcode Cloud 觸發你的工作流程。
你可以透過以下的 Files and Folders 條件來達成:

下一個建置號碼
#Xcode Cloud 會將新工作流程的建置號碼預設為 1,並在每次成功建置後自動遞增。如果你使用的是已有較高建置號碼的現有 App,你需要在工作流程中指定 Next Build Number,以讓 Xcode Cloud 使用正確的建置號碼。
請參考 設定 Xcode Cloud 建置的下一個建置號碼 以取得更多資訊。