CI/CD 自動化部署:用 GitHub Actions + wrangler-action 打造無人值守發布流水線 | Cloudflare 完整教學
上一篇我們把 漸進式部署 講透,你已經能手動完成「上傳、放量、監控、回滾」一整套安全發布。但這些指令每次發布都要手動敲一遍,既繁瑣又容易出錯。這一篇,我們就把它自動化——用 GitHub Actions 搭配官方的
cloudflare/wrangler-action,把「push 程式碼 → 自動 lint/test → 自動部署」串成一條無人值守的流水線。你會學會建立最小權限 API Token、設定CLOUDFLARE_API_TOKEN/CLOUDFLARE_ACCOUNT_IDSecrets、寫出 staging/production 環境分流的完整 workflow,並對比 Cloudflare 原生的 Workers Builds。這是 CF-2 部署工具系列的收尾篇。
前言
上一篇《漸進式部署與版本》,我們用 wrangler versions upload 把新版本上傳到候補區、用 wrangler versions deploy 按百分比做金絲雀放量,出問題時一行 wrangler rollback 一鍵回滾。整套流程很強大,但你有沒有發現一個問題——每一步都要人手動在終端機敲指令。改完程式碼要記得跑測試、記得 deploy、記得挑對環境、記得放量前先記下穩定版 ID……只要有一步靠人腦記憶,就有一步會忘、會錯。
CI/CD(持續整合與持續部署,Continuous Integration / Continuous Deployment) 就是來消除這種「靠人肉紀律」的風險。它的核心理念很簡單:把發布流程寫成程式,讓機器每次都用完全一致的步驟執行。你只要 git push,剩下的 lint、test、build、deploy 全部自動跑完——人不再是流程裡最容易出錯的那一環。
打個比方:上一篇的手動部署像是每天自己開車上班——你得記得加油、看路況、挑路線,偶爾還會迷路或忘東忘西。而 CI/CD 像是搭一條自動駕駛的軌道列車:你把「起點(push)到終點(上線)」的路線一次鋪設好,之後每次都沿著同一條軌道、同樣的速度、同樣的檢查點準時抵達,再也不會因為「今天忘了帶鑰匙」而出包。鋪軌道要花點功夫(寫 workflow),但鋪好之後,每一趟都省心。
在 Cloudflare Workers 的世界,你有兩條軌道可選:
- GitHub Actions +
cloudflare/wrangler-action——高度自訂,你自己寫 workflow YAML,能塞進 lint、test、多環境、審核。 - Workers Builds——Cloudflare 原生 CI,Dashboard 連結 repo 即可,零 YAML、零維護。
讀完這篇,你會掌握:
- CI/CD 的核心流程——
push觸發 → 自動 test → 自動 deploy 的完整心智模型,以及兩條軌道的取捨 - API Token 最小權限——為什麼不能用 Global API Key,以及怎麼建立只能「部署 Worker」的專用 Token
- 完整 workflow 實作——一份可直接用的 GitHub Actions YAML,含 lint/test 前置關卡與 staging/production 環境分流
- 常見坑與最佳實踐——Token 權限過大、Secrets 放錯位置、沒跑測試就部署,以及正確做法
核心概念
CI/CD 是什麼:把發布流程寫成程式
先把兩個詞拆開理解:
- CI(持續整合,Continuous Integration)——每次有人 push 程式碼,自動跑 lint、型別檢查、單元測試,確保新程式碼沒把既有功能弄壞。它是一道「品質關卡」。
- CD(持續部署,Continuous Deployment)——通過 CI 的程式碼,自動部署到目標環境(staging 或 production),確保「能通過測試的程式碼」能自動、一致地上線。
串起來就是一條流水線:
git push
│
▼
① Checkout 程式碼
│
▼
② 安裝相依套件 (npm ci)
│
▼
③ Lint + 型別檢查 + 測試 ← CI 品質關卡,任一失敗就中止
│
▼ (全綠才繼續)
④ wrangler deploy ← CD 自動部署
│
▼
⑤ 上線 (Cloudflare 邊緣網路)
關鍵在於:任一步失敗,整條流水線就中止,不會部署有問題的程式碼。這就是「自動化」比「人肉紀律」可靠的地方——機器不會因為趕時間就跳過測試。
兩條軌道:GitHub Actions vs Workers Builds
Cloudflare Workers 有兩種主流的 CI/CD 做法,先用一張表看清差異:
| 面向 | GitHub Actions + wrangler-action | Workers Builds(原生) |
|---|---|---|
| 設定方式 | 自己寫 .github/workflows/*.yml | Dashboard 連結 repo,零 YAML |
| 自訂程度 | 高(lint/test/多環境/審核全可控) | 低(基本上就是自動 wrangler deploy) |
| 維護成本 | 需維護 YAML | 幾乎零維護 |
| Secrets 管理 | GitHub Secrets | Cloudflare Dashboard |
| 支援 Git 服務 | 任何(GitHub 為主) | GitHub、GitLab |
| 前置步驟(lint/test) | 完全自訂 | 有限 |
| 適合場景 | 有測試、多環境、需審核的團隊 | 只想 push 就上線的個人/小專案 |
怎麼選? 一句話:部署前需要跑 lint/test、要多環境分流、要人工審核 → 選 GitHub Actions;只想 push 就最快上線、不想維護 YAML → 選 Workers Builds。 這篇的實作範例以 GitHub Actions 為主(因為它能示範完整的「test → deploy」流程),文末也會給 Workers Builds 的設定步驟。
運作原理:wrangler-action 在 CI 裡怎麼驗證
在本機,你用 wrangler login 開瀏覽器做 OAuth 授權。但 CI 環境沒有瀏覽器、無法互動,所以要改用 API Token 做非互動式驗證。機制是這樣:
Wrangler 會讀取兩個環境變數——CLOUDFLARE_API_TOKEN(你的 API Token)與 CLOUDFLARE_ACCOUNT_ID(你的帳號 ID)。只要這兩個變數存在,wrangler deploy 就能直接部署,不需要任何互動式登入。而 cloudflare/wrangler-action 進一步把這件事包好:你把 Token 和 Account ID 透過 apiToken / accountId 參數傳給它,它自動幫你設好環境變數、驗證、執行部署。
關鍵術語
cloudflare/wrangler-action:Cloudflare 官方維護的 GitHub Action,封裝 Wrangler 安裝、驗證與指令執行,是 CI 部署 Workers 的標準做法。- API Token:Cloudflare 的細粒度存取憑證,可精確控制權限範圍(相對於萬能的 Global API Key)。
CLOUDFLARE_API_TOKEN/CLOUDFLARE_ACCOUNT_ID:Wrangler 在 CI 中做非互動式驗證所讀的兩個環境變數。- GitHub Secrets:GitHub Repository 層級的加密機密儲存,workflow 用
${{ secrets.NAME }}引用,值不會出現在日誌裡。 - GitHub Environments:GitHub 的部署環境功能,可對 production 設定 Required Reviewers(人工審核關卡)與環境專屬 Secrets。
- Workers Builds:Cloudflare 原生 CI,Dashboard 連結 repo 後每次 push 自動
wrangler deploy。
實作範例
概念齊了,我們從零把一條完整的 CI/CD 流水線建起來。分三個步驟:建立 API Token → 設定 GitHub Secrets → 寫 workflow。
1. 建立最小權限 API Token
第一步,到 Cloudflare Dashboard 建立一個專門給 CI 用的 API Token。切記不要用 Global API Key(它是帳號的萬能鑰匙,洩漏就全盤皆輸)。
操作路徑:Cloudflare Dashboard → My Profile → API Tokens → Create Token → Custom token。
權限設定遵循最小權限原則,只勾必要的:
| 權限類別 | 權限項目 | 說明 |
|---|---|---|
| Account | Workers Scripts → Edit | 部署 Worker 的核心權限(必要) |
| Account | Workers KV Storage → Edit | 若有用 KV,才需要 |
| Account | D1 → Edit | 若有用 D1,才需要 |
| Account | Workers R2 Storage → Edit | 若有用 R2,才需要 |
Account Resources 記得限定到你要部署的那一個帳號,而非 All accounts——這樣就算 Token 洩漏,影響範圍也只限單一帳號。建立後 Cloudflare 只會顯示 Token 值一次,先複製起來。
你也需要 Account ID:在 Dashboard 任一 Worker 或帳號首頁的右側欄可以找到,或用指令查:
# 查看目前登入帳號與 Account ID
npx wrangler whoami
2. 把 Token 存進 GitHub Secrets
絕對不要把 Token 寫死在 workflow YAML 或程式碼裡(那等於公開洩漏)。正確做法是存進 GitHub 的加密 Secrets。
操作路徑:GitHub Repository → Settings → Secrets and variables → Actions → New repository secret,建立兩個:
CLOUDFLARE_API_TOKEN→ 貼上剛剛複製的 Token 值CLOUDFLARE_ACCOUNT_ID→ 貼上你的 Account ID
存進去後,workflow 就能用 ${{ secrets.CLOUDFLARE_API_TOKEN }} 引用,而且這些值永遠不會出現在 CI 日誌裡(GitHub 會自動遮蔽)。
3. 最基本的部署 workflow
先看一份最精簡、能跑的 workflow。在 repo 根目錄建立 .github/workflows/deploy.yml:
# .github/workflows/deploy.yml
name: Deploy Worker
on:
push:
branches:
- main # 推送到 main 分支時觸發
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout 程式碼
uses: actions/checkout@v4
- name: 設定 Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"
- name: 安裝相依套件
run: npm ci
- name: 部署 Worker
uses: cloudflare/wrangler-action@v3
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
command: deploy
逐段講解:
on.push.branches: [main]——觸發條件:只有 push 到main分支才跑這條流水線。actions/checkout@v4——把你的 repo 程式碼拉進 CI runner。actions/setup-node@v4——安裝 Node.js 20,cache: "npm"會快取node_modules,加速後續 run。npm ci——用package-lock.json做乾淨、可重現的安裝(比npm install更適合 CI)。cloudflare/wrangler-action@v3——核心:傳入apiToken與accountId,command: deploy就等同在 CI 裡跑wrangler deploy。
這樣一來,每次你 push 到 main,Worker 就自動部署上線。但這份 workflow 少了品質關卡——沒跑測試就直接部署,這是大忌。下一步補上。
4. 完整 workflow:test → deploy 品質關卡
真正該用的是這份——先 lint、型別檢查、跑測試,全綠了才部署:
# .github/workflows/ci.yml
name: CI/CD
on:
push:
branches:
- main
pull_request: # PR 也跑 CI(但不部署),提早發現問題
jobs:
# ── 第一關:CI 品質檢查 ──
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"
- run: npm ci
- name: Lint 檢查
run: npm run lint
- name: 型別檢查
run: npx wrangler types && npx tsc --noEmit
- name: 執行單元測試
run: npm test
- name: 驗證設定(Dry Run,不實際部署)
uses: cloudflare/wrangler-action@v3
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
command: deploy --dry-run
# ── 第二關:CD 部署(只在 push 到 main 且 test 通過時) ──
deploy:
needs: test # 關鍵:必須 test job 全綠才跑
if: github.ref == 'refs/heads/main' # 只有 push 到 main 才部署
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"
- run: npm ci
- name: 部署至 Production
uses: cloudflare/wrangler-action@v3
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
command: deploy --env production
這份的精髓在兩個地方:
needs: test——deployjob 宣告「我依賴testjob」。GitHub Actions 會先跑test,只有它全綠,才會啟動deploy。任何測試失敗,部署就不會發生。這就是「沒通過測試就不上線」的自動化保證。if: github.ref == 'refs/heads/main'——deploy只在 push 到main時執行;PR 觸發時只跑test(品質檢查),不部署。這讓你在 PR 階段就能提早抓錯,又不會誤把未合併的程式碼推上線。
deploy --dry-run 那步也值得一提:它驗證 wrangler.jsonc 設定與打包是否正確,但不實際部署,很適合放在 PR 檢查裡當「設定守門員」。
5. staging / production 環境分流
實務上你會有兩套環境:develop 分支自動上 staging、main 分支上 production。搭配上一篇提到的 wrangler.jsonc 多環境設定(env.staging / env.production),workflow 這樣寫:
# .github/workflows/deploy.yml
name: Deploy
on:
push:
branches:
- develop # → staging
- main # → production
jobs:
# develop 分支 → staging
deploy-staging:
if: github.ref == 'refs/heads/develop'
runs-on: ubuntu-latest
environment: staging
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"
- run: npm ci
- run: npm test
- name: 部署至 Staging
uses: cloudflare/wrangler-action@v3
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
command: deploy --env staging
# main 分支 → production(需 Environment 審核)
deploy-production:
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
environment: production # 可在此環境設 Required Reviewers
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"
- run: npm ci
- run: npm test
- name: 部署至 Production
uses: cloudflare/wrangler-action@v3
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
command: deploy --env production
重點:
environment: production——這對應 GitHub 的 Environments 功能。你可以到 Repository → Settings → Environments → production 設定 Required Reviewers——這樣每次 production 部署前,GitHub 會卡住等指定的人按核准才繼續。這是「自動化」與「人工把關」的完美折衷:staging 全自動,production 加一道人工閘門。- 兩個 job 用
if依分支分流,command分別帶--env staging/--env production,對上wrangler.jsonc裡定義的環境。
6. 把漸進式部署寫進 CI
還記得上一篇的金絲雀放量嗎?也能自動化。用 workflow_dispatch 做成「手動觸發、可選百分比」的漸進部署:
# .github/workflows/gradual-deploy.yml
name: Gradual Deploy
on:
workflow_dispatch: # 手動觸發
inputs:
percentage:
description: '新版本流量百分比'
required: true
default: '10'
type: choice
options: ['10', '25', '50', '100']
jobs:
gradual-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"
- run: npm ci
- name: 上傳新版本(不立即上線)
uses: cloudflare/wrangler-action@v3
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
command: versions upload --tag ci-${{ github.sha }} --message "CI 部署 #${{ github.run_number }}"
這條流水線把上一篇的 versions upload 搬進 CI:每次手動觸發,就自動上傳一個帶 ci-<sha> 標籤的新版本,你再到 Dashboard 或用 wrangler versions deploy 按選定的百分比放量。這樣「自動化」與「漸進式放量的謹慎」就結合起來了。
7. 替代方案:Workers Builds(原生 CI,零 YAML)
如果你覺得寫 YAML 太麻煩,只想「push 就上線」,用 Cloudflare 原生的 Workers Builds 五分鐘就搞定:
- 前往 Cloudflare Dashboard → Workers & Pages → 你的 Worker → Settings → Builds。
- 連結你的 GitHub / GitLab Repository。
- 設定觸發分支(例如
main→ production)。 - 之後每次 push,Cloudflare 自動幫你跑
wrangler deploy。
它零 YAML、零維護,Secrets 也統一在 Dashboard 管理(不需要建 API Token、不需要設 GitHub Secrets)。缺點是自訂程度低——複雜的 lint/test/多環境/審核流程還是 GitHub Actions 更靈活。你甚至可以混用:staging 用 Workers Builds 圖快,production 用 GitHub Actions 加審核。
常見錯誤與最佳實踐
坑一:API Token 權限過大,甚至直接用 Global API Key。
很多人圖方便,直接把 Global API Key 或一個「什麼都能做」的 Token 丟進 CI。這是最危險的做法——CI 環境的 Secret 洩漏風險本就比本機高(第三方 Action、fork PR、日誌外洩都是破口),而 Global API Key 一旦洩漏,攻擊者能改你的 DNS、刪 Zone、動帳單,整個帳號淪陷。正確做法:遵循最小權限原則,建立 Custom Token,只勾 Workers Scripts → Edit(用到其他資源才按需加),並把 Account Resources 限定到單一帳號。再搭配定期輪換 Token,把風險壓到最低。
坑二:Secrets 放錯位置——寫死在 YAML 或程式碼裡。
把 apiToken: cf_xxxxxxxx 這種真實值直接寫進 workflow YAML、或 commit 進 repo,等於當眾把鑰匙公開——只要 repo 是 public,或有任何人能讀到程式碼,Token 就外洩了。正確做法:所有機密一律存進 GitHub Secrets(Settings → Secrets and variables → Actions),workflow 只用 ${{ secrets.CLOUDFLARE_API_TOKEN }} 引用。GitHub 會自動加密儲存、並在日誌裡遮蔽這些值。Worker 執行期需要的機密(API 金鑰、密碼)則用上一篇教的 wrangler secret put 管理,別跟 CI 的部署憑證混為一談。
坑三:沒跑測試就部署。
只寫 deploy 一步、跳過 lint 與 test,CI/CD 就退化成「自動把 bug 推上線的機器」——比手動還危險,因為你連「部署前瞄一眼」的機會都沒了。正確做法:在 deploy job 前放一道 test 關卡,並用 needs: test 讓部署依賴測試通過。任何 lint 錯誤、型別錯誤、測試失敗,流水線就中止,壞程式碼進不了 production。deploy --dry-run 也可以加進 PR 檢查,提早驗證設定。
坑四:所有環境都全自動,production 沒有人工閘門。
把 production 也設成「push 就自動上線、無人審核」,一旦有人誤合併、或半夜趕工出錯,壞版本就直接全量上線。正確做法:staging 可以全自動圖快,但 production 建議用 GitHub Environments 加 Required Reviewers——部署前卡住等人核准。若要更保險,production 別用 deploy(立即 100% 上線),改用上一篇的 versions upload + 漸進式放量,讓自動化與謹慎並存。
坑五:CI 裡用了會出現在日誌的方式傳 Secret。
在 CI 裡設定 Worker 執行期機密時,若寫成 wrangler secret put KEY --text "值" 或 echo "值" | ... 而沒做好遮蔽,機密可能出現在 CI 日誌裡被看光。正確做法:在 CI 中要設 Worker Secret,從 GitHub Secrets 讀成環境變數再管線輸入(如 echo "$MY_SECRET" | npx wrangler secret put KEY,且 MY_SECRET 來自 ${{ secrets.* }},GitHub 會遮蔽);Wrangler 官方也明確警告永遠不要用 --text 參數直接傳機密值。
坑六:wrangler-action 沒鎖版本,某天 CI 突然壞掉。
wrangler-action 預設會用你專案 package.json 裡的 Wrangler 版本,但若你沒把 Wrangler 列為專案相依、或版本沒鎖,CI 某天可能因為抓到不相容的新版而莫名失敗。正確做法:把 wrangler 用 npm install -D wrangler@latest 加進 devDependencies 並 commit package-lock.json,或在 wrangler-action 用 wranglerVersion 明確指定版本,確保 CI 環境可重現。
最佳實踐小結: 記六條——API Token 只給最小權限(Workers Scripts → Edit、限定單一帳號、定期輪換);機密一律進 GitHub Secrets、絕不寫死在 YAML;部署前用 needs: test 強制先跑 lint/test;production 加 Required Reviewers 人工閘門、或改用漸進式放量;CI 傳機密避免 --text、善用日誌遮蔽;鎖定 Wrangler 版本確保可重現。守住這六條,你的流水線就既自動、又安全。
小結
上一篇《漸進式部署與版本》,我們把手動的安全發布流程——上傳、放量、監控、回滾——完整拆開。這一篇,我們把那套流程自動化,讓機器接手每次都容易忘、容易錯的手動步驟:
- CI/CD 核心流程——
push觸發 → CI 品質關卡(lint / 型別 / test)→ CD 自動部署,任一步失敗就中止,壞程式碼進不了 production。 - 兩條軌道的取捨——GitHub Actions +
cloudflare/wrangler-action高度自訂(lint/test/多環境/審核全可控);Workers Builds 原生零 YAML,適合只想 push 就上線的小專案。 - 最小權限 API Token——建 Custom Token 只勾
Workers Scripts → Edit、限定單一帳號,存進 GitHub Secrets(CLOUDFLARE_API_TOKEN/CLOUDFLARE_ACCOUNT_ID),絕不用 Global API Key。 - 完整 workflow——用
needs: test讓部署依賴測試通過、用if依分支做 staging/production 分流、用environment+ Required Reviewers 對 production 加人工閘門,還能把上一篇的漸進式放量寫進 CI。
到這裡,CF-2 部署工具這一大段——從 wrangler 入門、設定檔、環境與 Secrets、漸進式部署,到這篇的 CI/CD 自動化——就全部收尾了。你已經能把一個 Worker 從本機開發、安全發布,一路自動化到無人值守的生產流水線。
但你可能發現:到目前為止,我們的 Worker 大多是「無狀態」的——處理完請求就忘光一切。真實的應用需要記住資料:使用者的設定、快取、計數器、session……這些該存在哪裡?Cloudflare 提供了一整套邊緣儲存方案,而其中最容易上手、最適合「讀多寫少」場景的,就是 KV(Key-Value)鍵值儲存。下一篇《KV 鍵值儲存入門》,我們就正式進入 CF-3 儲存資料 這一大段,從最基礎的鍵值讀寫開始,帶你把資料留在邊緣。
想先查閱官方對 wrangler-action 與 CI/CD 的完整說明,可以隨時參考 cloudflare/wrangler-action 官方 GitHub 倉庫。CI/CD 自動化這一課已就緒,我們下一篇《KV 鍵值儲存入門》見。