雲端 CI/CD pipeline 視覺示意 EAS Build 與 OTA 更新部署流程

Expo EAS Build + EAS Update 上架實戰:git push 到 TestFlight 自動化 + OTA 灰度發布防爆 SOP

自由揚AntonyLin
雲端 CI/CD pipeline 視覺示意 EAS Build 與 OTA 更新部署流程
雲端 CI/CD pipeline 視覺示意 EAS Build 與 OTA 更新部署流程

深夜 11 點,產品經理在 Slack 丟訊息:『今天上 production 那版的結帳流程有 bug,10% 訂單付款後沒跳成功頁,能不能緊急修?』如果你的 app 還在 App Store Review 模式——只能祈禱 Apple 24 小時內審完,這一夜就完了。 如果你用的是 EAS Build + EAS Update,事情會非常不一樣:寫個 patch、推上 staging branch、灰度 5% 觀察 30 分鐘、確認沒問題就 100% rollout,前後 1 小時。隔天早上用戶醒來看到的就是修好的版本。

這篇我們把『一個 React Native + Expo app 從 git push 到 TestFlight 再到 OTA 灰度上線』整套流程拆開講,附完整 EAS Workflows YAML、staged rollout SOP 與『發現問題立即回滾』的範本。如果你想對齊更前一步——還沒從 Expo Go 切到 Development Build,可以先看 Expo Go 撞牆了怎麼辦?4 個訊號告訴你該轉 Development Build;本篇預設你已經有 Dev Build。

傳統 App 上架 vs Expo + EAS:兩個世界的差距

先說傳統 native app 上架流程的痛點,這樣後面看 EAS 的解法才有對照——

環節

傳統 RN CLI / Native

Expo + EAS

第一次 build iOS

本機 Mac + Xcode,30-60 分

雲端 EAS Build,瀏覽器看進度

憑證(Provisioning Profile / Signing Cert)

Xcode 介面手動建立、容易過期

EAS 託管 + 自動續期

送 TestFlight

Transporter / Xcode 上傳

`npx testflight` 一行指令

送 App Store

App Store Connect 手動填

EAS Submit 自動填

緊急 bug 修

重新 build + 重新上架 + 等審 24h

EAS Update 推 OTA 5 分鐘上線

回滾

重新跑一次上架流程

Channel 改指 branch 1 秒完成

灰度發布

需自建後端 + feature flag

Rollouts 內建 5% / 25% / 50% / 100%

最關鍵的差距是『改一行 JS 上線』的時間。 傳統流程是 24-72 小時(看 Apple 心情),EAS Update 是 5-15 分鐘。這個量級的差距,會直接改變你產品的 iteration 速度。

EAS 是哪三件工具?分工怎麼切

EAS(Expo Application Services)其實是三個獨立但互相搭配的雲端服務。剛入門很容易把它們混為一談,但分工切清楚會讓你之後寫 CI/CD pipeline 思路清晰很多。

服務

做什麼

什麼時候用

費用結構

EAS Build

雲端 build 你的 .apk / .aab / .ipa

需要新 binary 上 store 或裝測試員手機時

依 build 次數計費,免費 tier 30 次/月

EAS Update

推 OTA JS bundle 給已安裝的 binary

改 JS 程式碼想立即上線(不動 native)

按 MAU 計費,多數中小型 app 免費

EAS Submit

把 build 送上 App Store / Play Store

已 build 完想上架

包含在 Build 的訂閱方案內

出處:Expo Application Services 官方介紹EAS Build 文件

一個常見誤解:EAS Update 不能取代 EAS Build

EAS Update 只能 OTA 推送 JavaScript 跟 asset(圖片、字型)。任何改到原生程式碼的變更——加新的 native module、改 app.json 的 permission、改 Hermes 版本——都必須重新 EAS Build。

判斷方式很簡單:問自己『這個變更會不會動到 app.json 或 package.json 的 native dependencies』。有 → EAS Build;只有 JS 變化 → EAS Update。

完整 EAS Workflows YAML:從 PR 到 production 自動化

EAS Workflows(2025 推出的 CI/CD 服務)讓你在 .eas/workflows/ 放 YAML,git push 之後自動跑 build / submit / update。下面這個範本是我們建議的『PR 到 production』三層管道:

YAML
# .eas/workflows/release.yml
name: release-pipeline
on:
  push:
    branches: [main]

jobs:
  # ---- 第一層:PR 預覽 build ----
  preview_build:
    name: Internal preview build
    type: build
    params:
      platform: android
      profile: preview

  # ---- 第二層:production binary 出貨 ----
  production_build:
    name: Production binary build
    needs: [preview_build]
    type: build
    params:
      platform: all
      profile: production

  # ---- 第三層:自動送 TestFlight + Play Console ----
  submit_to_stores:
    name: Auto submit
    needs: [production_build]
    type: submit
    params:
      platform: all
      profile: production

對應的 eas.json 需要定義對應 profile:

JSON
{
  "build": {
    "preview": {
      "distribution": "internal",
      "android": { "buildType": "apk" }
    },
    "production": {
      "autoIncrement": true,
      "channel": "production"
    }
  },
  "submit": {
    "production": {
      "ios": { "ascAppId": "1234567890", "appleTeamId": "XXXXXXXXXX" },
      "android": { "serviceAccountKeyPath": "./google-service-account.json" }
    }
  }
}

autoIncrement: true 是關鍵——每次 build 自動 +1 buildNumber / versionCode,省得手動改容易漏。channel: production 把這個 binary 鎖在 production channel,之後 EAS Update 推到 production channel 才會被這個 binary 接到。

ℹ️我們怎麼看 EAS Workflows 的設計取向

EAS Workflows 把 build / submit / update 三件事整合成一個 YAML 是很正確的方向——以前你要在 GitHub Actions 自己組 build 步驟、再加 fastlane 送 TestFlight、再加 expo-cli 推 OTA 更新,光是 secrets 管理就要花一天。整合成 YAML 後 secrets 全部在 EAS dashboard 管,credentials 自動續期。我們的判斷是:3 年後絕大多數 React Native 團隊不會自己寫 fastlane,因為 EAS 已經把這層複雜度吃下去了。對中小企業老闆而言這代表『不需要養專責的 mobile DevOps』,整個 release pipeline 一個半職的工程師就能 own。

EAS Update 灰度發布 SOP(5% → 25% → 50% → 100%)

OTA 最大的風險是『一鍵推 100% 出包』。所以 production 推 update 一定要走 staged rollout——分階段觀察、發現問題立刻攔。

Step 1:把要發的更新推到 staging branch

Bash
# 假設目前 production channel 指向 v1 branch
# 我們先把新版本推到 v2 staging branch
npx eas update --branch v2 --message "fix: 結帳成功頁未跳轉 bug"

這時候 production channel 還是指 v1,使用者完全看不到新版。但你可以拿 Dev Build 切到 v2 branch 完整測一遍。

Step 2:把 production channel 改指 v2 + 啟動 rollout

Bash
# 創建一個從 5% 開始的 rollout
npx eas channel:edit production --branch v2 --rollout-percentage 5

5% 的使用者開始收到新版,其他 95% 繼續用舊版。觀察 24-48 小時 crash rate、key metrics(轉換率、停留時間)有沒有崩。

Step 3:階段性放大

Bash
# 觀察沒問題後,逐步放大
npx eas channel:edit production --branch v2 --rollout-percentage 25
# 再觀察 24h
npx eas channel:edit production --branch v2 --rollout-percentage 50
# 最後 100%
npx eas channel:edit production --branch v2 --rollout-percentage 100

每個階段觀察的指標跟時間應該寫進團隊 runbook,不要每次靠 PM 跟工程師臨場討論。我們建議的觀察期:

  • 5% → 等 24 小時,看 crash rate、看 retention day 1。
  • 25% → 等 24 小時,加看 key conversion metric。
  • 50% → 等 24 小時,最後一次質量門。
  • 100% → 推完不等,但持續監控 7 天。

Step 4:發現問題立刻回滾

Bash
# 萬一發現新版 crash rate +30%,立刻把 production channel 切回 v1
npx eas channel:edit production --branch v1 --rollout-percentage 100

Channel 改指 branch 是『一個指令、5 秒生效』——比傳統 release rollback(要重新 build + 上架 + 等審核)快好幾個量級。這就是 OTA 之所以叫『災難復原工具』的原因,不只是『快速發版工具』。

💡回滾判斷的硬指標

我們建議寫進團隊 runbook 的回滾觸發條件:1) 新版 crash rate > 舊版 + 20%;2) 任何 P0 metric 跌幅 > 10%(轉換、登入成功率等);3) 客服在 4 小時內收到 5+ 通同類別客訴。任一條觸發立刻回滾,事後再回頭看根因——『先穩住,再分析』比『邊救火邊 debug』安全很多。

導入 EAS 前 vs 導入後:團隊真實感受到的差異

從幾位 React Native production 工程師的訪談、社群討論與我們在 web 端類似工具(Vercel / Netlify)的經驗,導入 EAS 之後最明顯的變化是:

維度

導入前

導入後

緊急 bug 上線時間

24-72 小時(等審核)

10-30 分鐘(EAS Update)

上架憑證管理

工程師手動,平均一年壞 1-2 次

EAS 自動續期,幾乎不用管

TestFlight 上傳

Transporter,平均 30 分

`npx testflight`,5 分

新人 onboarding 時間

1-2 週(裝 Xcode + 學 fastlane)

1-2 小時

CI/CD 維護成本

工程師每月 8-16 小時

1-2 小時

回滾風險

高(要重 build + 等審)

低(一指令 5 秒)

對中小企業而言,最大的紅利是『不需要養專責 mobile DevOps』——上面這些事一個半職的工程師就能 own。以前要養一位 mobile DevOps 工程師月薪 60-100k,現在工具吃掉這塊複雜度,省下的人事成本是 EAS 訂閱費用的數十倍。

如果你今天要從零導入 EAS:建議的 4 週時間表

下面這個時間表是給已經有 Expo app(在 Dev Build 階段)的團隊,打算把 release pipeline 升級到 EAS Workflows 的——4 週可以完整跑通。

重點

交付物

第 1 週

EAS Build 整起來,跑通 internal preview

可以下載安裝的 dev / preview APK & IPA

第 2 週

EAS Submit 設定,第一次送 TestFlight 跟 Play Console

成功送出第一個 production build

第 3 週

EAS Update 接 production channel,跑第一次 5% rollout

灰度發布的 SOP 寫成 runbook

第 4 週

EAS Workflows YAML 整起來,PR 到 production 全自動

git push 觸發完整 pipeline

整個過程不需要 senior DevOps,但需要工程團隊有一個人負責,每週投入 6-10 小時。如果你的工程團隊規模很小、人都在做 feature,這就是值得考慮外包的情境之一——找做過 5+ 次 EAS pipeline 的人,4 週可以壓到 1-2 週。

ℹ️我們做過這件事

順帶說一下,雖然這篇講的是 mobile app pipeline,但同一條思路(雲端 build + OTA 灰度 + 自動回滾)我們在自己的 Web 產品線上跑了好幾年——30+ 企業客製案落地的過程裡,CI/CD pipeline 的建置幾乎是每個專案的標配。Vercel / Cloudflare Pages 在 Web 端做的事,EAS 在 mobile 端就是同一件。看到這裡,如果你的團隊正在『要不要把 release pipeline 自動化』之間猶豫,我們很樂意 聽你聊聊現況,一起看看你目前的瓶頸在哪、外包大概的範圍跟費用怎麼算。

ℹ️我們怎麼看

App 發版速度 = 產品 iteration 速度。3 年後贏的不會是『某個 app 框架』,會是『把 release pipeline 做到跟改 Google Docs 一樣自然』的那種團隊。對中小企業老闆來說,現在最值得做的一件事是回頭看自己 mobile / web 產品的『改一行程式碼到生效』時間——如果還在用『提交 → 等審核 → 1-3 天』模式,這條 OTA + 灰度 + 自動回滾的工具鏈會是接下來一年最高槓桿的工程投資。先把那條路徑算清楚,技術選型挑哪個之後再說。

💡EAS 灰度發布 SOP runbook 範本下載

我們正在整理一份『EAS 灰度發布 SOP runbook 範本(含回滾觸發條件、每階段觀察指標、團隊溝通模板)』,可以在 我們的部落格資源頁 找最新版(資產製作中,這版可先把本篇『5% → 25% → 50% → 100%』那段抄成內部 runbook)。

QEAS Build 跟在自家機器跑 fastlane / Github Actions build,哪個比較划算?

對中小團隊(每月 build 次數 < 100)EAS 通常比較划算,因為你不用養 Mac CI 機器、不用管 Xcode / fastlane 升級。對大團隊(每月 build > 500、有專責 DevOps)自建 CI 可能單次成本低,但要付專職人力。EAS 免費 tier 每月 30 次 build,多數 MVP / 小團隊免費額度就用不完。

QEAS Update 推 OTA 用戶要重啟 App 才會生效嗎?

預設是『下次冷啟動』生效——也就是用戶關掉 app 再打開的時候。如果想立即生效(例如緊急 bug 修),可以在 app 內用 `Updates.fetchUpdateAsync()` + `Updates.reloadAsync()` 強制套用,但這會打斷使用者體驗,建議只在 critical bug 才用。

QOTA 推完之後,能精確知道哪些用戶收到新版了嗎?

可以。EAS Update dashboard 會顯示每個 update 的 fetch count、apply count、與依 platform / version 切的分布。配合 Sentry / Bugsnag 等監控工具更精準——你可以用『新 update ID』tag 篩 crash report,看新版本是否引入新 bug。

QChannel 跟 Branch 在 EAS Update 裡的差異是什麼?

Channel 是『binary 認得的標籤』——你在 build 時把 channel 寫進 binary,binary 出貨後不能改。Branch 是『JS bundle 的版本軌』——一個 channel 任何時候只指向一個 branch(除非啟動 rollout)。你可以把 channel 想成『機場』,binary 從這個機場進來;branch 是『航班』,channel 把進來的乘客導去其中一個航班。

QEAS Workflows 跟 GitHub Actions 衝突嗎?

不衝突——可以共存。EAS Workflows 專注在 build / submit / update 這條鏈,GitHub Actions 可以負責測試、linting、release notes 自動產生這些 EAS Workflows 不擅長的事。實務上很多團隊兩個都用:GitHub Actions 跑 PR check,EAS Workflows 跑 release pipeline。

Q如果客戶 app 裝在『卡在某個舊版 binary』的手機上,OTA 還能推給他嗎?

可以,只要那個 binary 的 SDK 版本跟你新的 update bundle 相容。EAS Update 會自動檢查 runtime 版本——不相容的 update 不會推給對應 binary,避免推下去之後 crash。所以建議在 app 內加一段邏輯:跑超過 6 個月沒升 binary 的用戶,提示『有新版本,請到 App Store 更新』。

如果你想把這條 pipeline 跑起來

把 EAS Build / Update / Submit 整合到團隊 release pipeline 不難,但細節多——憑證管理、灰度策略、回滾 runbook、監控接線。我們很樂意 聽你聊聊你的情況,一起看你目前卡在哪一步、值不值得外包導入、大概的時程跟預算。這個階段我們陪你想,後面真的要動手再談範圍。

三篇一起讀比較有完整圖像:Expo Go 撞牆了怎麼辦?4 個訊號告訴你該轉 Development Build(入門期)→ Expo SDK 56 + New Architecture 升級實戰(開發期)→ 本篇(上架期)。如果你還在更前一步、還沒決定要不要做 App,可以對照 APP 開發報價 8 萬 vs 80 萬客製化 APP 框架選型完整指南 兩篇老闆視角的選型參考。

分享文章

AUTHOR

自由揚AntonyLin

留言(0)

尚無留言,成為第一個留言的人吧!

需要網站系統架設或軟體開發?

無論是品牌官網、客製化系統還是應用程式,我們的團隊擁有豐富經驗,歡迎聯繫我們,讓專業為您的事業加分。