Fultter Build Version
Start typing here...
Flutter Build Version(CI/CD 最佳實踐)
本文整理 Flutter 專案在 CI/CD 中管理 build number(建置版本) 的最佳實踐,目標是:
避免手動修改版本號造成上架失敗
避免 CI 內 commit 回 repo 產生競態條件
確保 iOS / Android build number 單調遞增,符合商店規則
1. Flutter 版本號結構說明
Flutter 使用 pubspec.yaml 中的 version 欄位:
區段 | 說明 |
|---|---|
| Build Name (給人看的版本) |
| Build Number (給商店看的流水號) |
重點原則
build name可人工控制(語意化版本)build number必須持續遞增 (同一個build name下,上傳新建置也必須更大)
2. 為什麼不建議在 CI 內 commit 回 repo 改版本號
過往常見做法:
CI 讀取
pubspec.yamlbuild number +1
commit 回 repo(並排除本次 pipeline)
實務上的問題
平行 pipeline 會產生 競態條件 (兩條都讀到舊號碼 → +1 撞號)
Re-run / Retry 容易撞號或倒退
版本變更混在功能 commit 中,不利 review / rollback
需要額外規則避免無限觸發 CI
👉 結論:不建議 (維護成本高、風險大)。
3. 建議的 CI/CD Build Number 策略(由推薦到次推薦)
✅ 方案 A:使用 CI 系統內建的遞增序號(最推薦)
直接使用 CI 提供的 build 序號作為 Flutter build number。
常見例子:
GitHub Actions:
GITHUB_RUN_NUMBER其他 CI(Azure DevOps / Bitrise / Codemagic):各自提供的 build number env
優點
天然單調遞增
不怕平行建置
不需修改 repo
實作最簡單
👉 團隊首選方案。
⚠️ 方案 B:使用 Git commit 數量
優點
不依賴 CI 平台(可跨平台)
風險
rebase / squash 會改變數量
shallow clone 需注意 fetch depth
多分支併行時可能產生倒退
👉 僅適合 主幹單線開發 或已控管流程的專案。
⚠️ 方案 C:查詢商店最新 build 再 +1
App Store Connect / Google Play API
常搭配 fastlane 使用
優點
與商店狀態 100% 對齊,不會撞號
缺點
需要 API 金鑰與權限
pipeline 複雜度提高
外部服務失敗會影響建置
4. 關於 build_version 套件的評估
build_version 這類套件通常偏向:
將 package version 產生為程式碼(或產生常數)
方便在 App UI 顯示版本資訊
不適合用來解決的問題
❌ build number 自動遞增
❌ App Store / Google Play 的版本管理
可能衍生的成本
引入
build_runner/codegenCI 建置時間、快取複雜度增加
產生檔案是否 commit 的團隊規範問題
👉 建議定位:
版本顯示:可用
CI build number 管理:不建議
5. GitHub Actions(iOS → TestFlight)建議做法
5.1 建議規範
pubspec.yaml的+<build>僅保留 placeholder(例如+1)每次 CI 用
GITHUB_RUN_NUMBER產生 單調遞增 的 build number透過
flutter build ipa的--build-number覆蓋(不回寫 repo)
5.2 工作流程需求
需要一台 macOS runner 來產 ipa
TestFlight 上傳通常建議用 fastlane (
pilot upload),或你團隊既有的上傳方式建議用 GitHub Environments / Secrets 管理憑證、App Store Connect API key
5.3 範例 .github/workflows/ios-testflight.yml
你一定會想調整的幾點
BUILD_NAME:建議由 tag / release / 手動輸入參數決定憑證與簽章:如果你們不是用 fastlane match,要加上 keychain import 與 provisioning 設定
若同時要 Android:可用同一個
BUILD_NUMBER一次產出 aab
6. iOS TestFlight / App Store(build number)注意事項
6.1 同一個版本號(build name)下,build number 必須往上
例如:
1.0.0 (70)上傳過了下一次仍是
1.0.0時,必須用71、72…
這也是最常見的「忘記改 build number → 上傳失敗」原因。
6.2 建議策略
不要靠手動改
pubspec.yaml不要在 CI 回寫 repo 版本
要用 CI 的遞增序號覆蓋
--build-number
6.3 若你們有多條 workflow / 多分支
建議「上傳 TestFlight」只允許從
main(或 release branch)觸發或用 GitHub Environments 做 gate(避免 feature branch 不小心上傳)
7. 團隊建議落地做法(Recommended)
pubspec.yaml
CI/CD 規範
build number 一律由 CI 提供(GitHub Actions:
github.run_number)build 時使用
--build-number覆蓋不在 CI 中 commit 回 repo
App 顯示版本:建議用
package_info_plus讀取即可(或其他純讀取方案)
8. 總結
項目 | 建議 |
|---|---|
Build Name(1.2.3) | 人工控管(語意化版本 / release 流程) |
Build Number(+456) | CI 自動產生(GitHub:run_number) |
CI commit 版本 | ❌ 不建議 |
| 僅用於顯示,不用於遞增 |