前言
GitHub Actions 已經從一個方便的自動化工具,演變成完整的 CI/CD 平台。它把工作流程(workflows)直接綁在 Git 倉庫上,讓代碼的測試、建置、驗證與部署可以在同一個地方自動化完成。本文以實務角度出發,從概念說明到範例、再到最佳實務與安全性考量,逐步帶你把 GitHub Actions 用到位:不只是跑測試,而是把整個交付流程做得穩健、可觀測、可擴展。
一、核心概念快速說明(不要笨重定義)
- Workflow(工作流程):以 YAML 檔放在
.github/workflows/。它定義了觸發時機(on)、要做的工作(jobs)與邏輯。 - Job(工作):工作由多個步驟(steps)組成,在 runner 上執行。每個 job 預設在獨立的 runner(container 或 VM)上執行,job 之間可以並行或依賴。
- Step(步驟):單一執行單位,可以是 shell 指令,也可以是 action(重複使用的封裝)。
- Action:可重複使用的模組(JavaScript、Docker 或 composite action),用來封裝常見任務。
- Runner:執行 job 的主機,分為 GitHub 提供的 hosted runners(Linux/Windows/macOS)或你自建的 self-hosted runners。
- Artifact / Cache:用來在 job 間傳遞檔案(artifacts)或加快依賴安裝(cache)。
- Secrets / Environments:安全儲存機密資訊與環境級別保護(例如需人工審核才可部署到 production)。
理解這些關鍵字就能閱讀任一 workflow,下面開始用實例把它拼起來。
二、從最簡單的 CI 開始:Node.js 範例(一步到位)
一個實際的 Node.js 專案,典型的 CI 流程包含:安裝依賴、執行 lint、跑測試、產生報告並上傳 artifact。這是一個標準範例:
name: CI
on: push: branches: [ "main", "staging" ] pull_request: branches: [ "main" ]
jobs: test: runs-on: ubuntu-latest strategy: matrix: node-version: [16.x, 18.x] steps: - uses: actions/checkout@v4 - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} - name: Install dependencies (cache) uses: actions/cache@v4 with: path: ~/.npm key: ${{ runner.os }}-node-${{ matrix.node-version }}-${{ hashFiles('**/package-lock.json') }} restore-keys: | ${{ runner.os }}-node-${{ matrix.node-version }}- - run: npm ci - run: npm run lint - run: npm test -- --ci --reporter=mocha-junit-reporter - name: Upload test results uses: actions/upload-artifact@v4 with: name: junit-results path: test-results.xml說明要點:
- 使用
strategy.matrix並行在多個 Node 版本上跑測試,驗證相容性。 - 使用
actions/cache快取 npm,顯著減少安裝時間。 upload-artifact可讓後續 job 或 GitHub UI 下載測試報告。
三、把 CI 接上 CD:部署範例(Docker → Registry → K8s / VPS / Serverless)
CI 做完後通常會把產物(artifact / container image)推到 registry,接著觸發部署。以下範例示範建置 Docker 映像並推到 Docker Hub,然後示範如何用另外的 job 或 workflow 做部署。
Build & Push Image
name: Build and Publish Docker Image
on: push: branches: - main workflow_dispatch:
jobs: build-and-push: runs-on: ubuntu-latest permissions: contents: read packages: write steps: - uses: actions/checkout@v4 - name: Set up QEMU uses: docker/setup-qemu-action@v2 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2 - name: Login to DockerHub uses: docker/login-action@v2 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Build and push uses: docker/build-push-action@v4 with: context: . push: true tags: myorg/myapp:${{ github.sha }} platforms: linux/amd64,linux/arm64 - name: Upload image tag artifact uses: actions/upload-artifact@v4 with: name: image-tag path: image-tag.txt部署(例:在另一個 workflow 觸發,或使用 environment 與保護)
部署可在同一 workflow 以 needs: 依賴順序執行,或用 workflow_run 觸發。示例:把映像部署到 Kubernetes(kubectl + k8s manifest):
name: Deploy to K8s
on: workflow_run: workflows: ["Build and Publish Docker Image"] types: - completed
jobs: deploy: if: ${{ github.event.workflow_run.conclusion == 'success' }} runs-on: ubuntu-latest environment: name: production url: https://your-app.example.com steps: - uses: actions/checkout@v4 - name: Download image tag uses: actions/download-artifact@v4 with: name: image-tag - name: Set kubectl uses: azure/setup-kubectl@v4 with: version: '1.26.0' - name: Deploy to k8s env: IMAGE_TAG: ${{ steps.download-artifact.outputs.path }}/image-tag.txt KUBECONFIG: ${{ secrets.KUBE_CONFIG }} run: | kubectl set image deployment/my-app my-app=myorg/myapp:${{ github.sha }} kubectl rollout status deployment/my-app -n default注意事項:
- secrets(例如 DockerHub token、Kubeconfig)不要放在 repo 中,要用 GitHub Secrets。
- environment 可以搭配保護規則(required reviewers)來做準入控制。
- workflow_run 用於把 build 完成後的自動部署分離成不同 workflow,使 CI 與 CD 更清晰。
四、常見 CI/CD 模式與工作流設計建議
- 分層 workflow:把「測試/建置」和「部署」拆成不同 workflow,用
workflow_run串接,降低耦合。 - 短、快、可回覆的 job:把大任務拆成多個小 job(lint、unit tests、integration tests、build),方便並行與重試。
- 只在必要時部署:使用
paths、branch policy 或專門的 release tag 來控制何時部署。 - 使用 artifacts 傳遞建置產物:binary 或 build output 儘量透過 artifacts 保留,部署時直接下載使用。
- Matrix 建構但有限度:Matrix 很方便驗證多環境,但同時啟動過多會增加 runner/費用與配額風險。
- 使用 concurrency 與 cancel-in-progress:避免多次 push 觸發排隊部署,
concurrency能保證同一分支只有一個在跑的 workflow。例:
concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true五、加速 CI 的實務技巧(節省時間就是節省錢)
- 善用 cache(actions/cache):node_modules、pip cache、maven repo、go modules、composer 等都該 cache,但 key 設計要保守(key 包括 lockfile hash)。
- 依賴分層:把依賴安裝放到獨立 job 或預先產出 artifact,以便後續 job 使用。
- 使用 self-hosted runners(有強需求):若需要特定硬體(GPU)或更高效能,self-hosted runner 可降低啟動時間,但需維護安全與穩定。
- 利用 composite actions / reusable workflows:把共通步驟抽成 action 或 reusable workflow,減少重複、提高一致性。
- 按需執行較重測試:把 Unit tests、Integration tests、E2E 分層,PR 時先跑 Unit tests,merge 或 nightly 再跑 E2E。
六、安全性實務(不能偷懶)
- Secrets 管理:所有憑證、token、kubeconfig 一律放入 GitHub Secrets;不要在 workflows 直接 echo secrets(會在 log 洩漏)。
- 環境保護:把 production environment 設為需要人工審核或多重審核(required reviewers)。
- 避免在 PR 中使用寫入權限的 token:
GITHUB_TOKEN有 repo 權限,若有 fork PR,預設會保護性限制;對外部 PR 請小心。 - 最小權限原則:只授予 action 或 runner 需要的權限(用
permissions:限制 scope)。 - 第三方 action 風險:使用 community action 時檢查 source code(不要盲用),prefer 指定具備維護紀錄與信任度高的 action並鎖定版本(不可用
@master)。 - 依賴掃描與秘密掃描:把 Dependabot、secret scanning、或 SCA 工具整合到 workflow 中,提早攔截安全問題。
七、Debug、可觀測性與報告
- 在 workflow 中輸出詳細日誌(但不輸出 secrets):對失敗的 step 使用
run: |方式抓取更多上下文。 - 利用 artifacts 保存 log 與報表:測試報告、coverages、bundle stats 都上傳 artifacts 以便分析與回溯。
- 使用 annotations:GitHub Actions 支援註解(warning/error)直接貼到 Pull Request,改善開發者體驗。
- Metrics 與告警:把關鍵指標(成功率、平均執行時間、失敗趨勢)匯到外部監控(Datadog、Prometheus)以偵測異常。
- 使用
if: failure()與重試策略:針對網路不穩或外部服務的臨時錯誤加入重試(retry loops)或continue-on-error(慎用)。
八、進階功能與常用 patterns
1. Reusable workflows(可重用 workflow)
把常用流水線抽成 reusable workflow,供不同 repo 呼叫,減少維護負擔。
name: Reusable CIon: workflow_call: inputs: node-version: required: truejobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: ${{ inputs.node-version }} - run: npm ci - run: npm test呼叫方:
jobs: call-reusable: uses: your-org/your-repo/.github/workflows/reusable-ci.yml@main with: node-version: 18.x2. Composite Actions(組合 action)
把多個步驟封裝成一個 action(版本控制、可在多個 workflow 重複使用)。
3. Concurrency 與 Workflow Dispatch
workflow_dispatch可手動觸發(常用於 release 或 hotfix)。concurrency能防止重複排隊與浪費 runner。
4. Scheduled Workflows(Cron)
例:每天夜間跑 E2E 測試或定期掃描:
on: schedule: - cron: "0 2 * * *" # 每日 02:00 UTC九、Self-hosted runners:何時才適合?
優點:自訂環境、較低延遲(依網路)、可使用特殊硬體(GPU、專用網卡)、無需排隊受限於 GitHub hosted runner 配額。
缺點:需要維護(OS patch、security)、曝光風險(若 runner 在公網)、必須小心 secrets 管理(避免在 runner 上被盜用)。
實務建議:
- 將 self-hosted runner 放在安全網段(VPC / private subnet)且使用自動化管理(Ansible/Terraform),定期 patch。
- 使用 ephemeral runner(短期啟動、完成即關)降低攻擊面。
十、成本與配額考量
- GitHub-hosted runners 的執行時間會計費(依帳戶類型與 runner OS 不同)。
- 除了 runner 時間,artifact 存儲、package storage 也可能有額外費用。
- 使用 matrix、大量並行 job 會快速增加成本;用
concurrency、job 並行度與 cache 設計來優化使用率。 - 如果大流量 CI(每日數千次 workflow),考慮 self-hosted 或混合策略(部分工作放 public hosted,重度計算放 self-hosted)。
十一、常見問題與排查清單
- Workflow 沒有觸發?
- 檢查
on:設定(push、pull_request、workflow_dispatch、schedule)與 branch 名稱。
- 檢查
- Secrets 不能在 fork PR 中使用?
- 這是預設安全措施,外部貢獻者的 workflow 不會被授權取用 repository secrets。
- Cache 不命中?
- 核心問題是 key 設計;建議 key 包含 lockfile hash(如
package-lock.json)或依需求採分層 key 以提高穩定性。
- 核心問題是 key 設計;建議 key 包含 lockfile hash(如
- artifact 太大 / retention 過短?
- 調整 artifact 的 retentionDays 或清理政策,避免佔用儲存配額。
- 部署失敗且沒有明確錯誤?
- 開啟詳細 log,確保敏感資訊以 masked 方式處理,並把部署步驟拆解成更小步驟便於定位。
十二、實務檢查清單(部署前後必做)
部署前
- 所有敏感資訊已放入 Secrets 且經過審核。
- workflows 使用最小必要權限(
permissions限制)。 - key 的 cache 設計與 purge 流程可控。
- 測試 coverage 與自動化測試門檻設置(PR 必通過測試才能 merge)。
部署中
- 使用 environment 與 required reviewers 控制 production 上線。
- 監控 deploy duration 與 rollback 機制(health check)。
部署後
- Release notes / changelog 自動生成(例如使用 conventional commits + action 產生 release)。
- 觀察 SLO / error rate 與自動化告警。
- 定期清理 artifacts、冷資料與舊 runner。
十三、實戰案例速覽(簡要)
- 小型專案:使用單一 workflow,PR 試跑測試,merge 到
main才 build image 並部署到 Vercel / Netlify(serverless)— 成本低、維護簡單。 - 中型企業:拆分 CI / CD,使用 reusable workflows、environment 保護、並把 E2E 在 nightly 或 staging 執行。
- 高頻交易/高依賴專案:自建 runner、嚴格的權限管理、並把敏感部署步驟放在內部網路的 runner 執行。
十四、總結:把 GitHub Actions 當成團隊的自動化中樞
GitHub Actions 的價值不僅是把單一任務自動化,而是把開發、測試、建置、發佈、監控串成一條可靠的交付鏈。好的 CI/CD 流程能讓你:
- 更早發現錯誤(shift-left)
- 減少人工步驟與人為失誤
- 快速回應市場與使用者需求
- 在必要時快速回滾與回復服務
最後給你一個最實用的 checklist(複製貼上):
- [. ] workflow 有清楚的觸發條件與分支策略
- [. ] secrets 與 environment 已正確設定
- [. ] job 被拆分為可並行與可重試的小步驟
- [. ] cache 與 artifact 設計合理、key 有版本化或 lockfile hash
- [. ] reusable workflows / composite actions 被用於共通流程
- [. ] production environment 有保護與審核流程
- [. ] 日誌、報表、與指標被上傳並納入監控
- [. ] 成本預估與配額檢查已完成
把這些元素落實在你的 GitHub Actions 中,CI/CD 就不再是麻煩的工程,而是你可依賴的交付引擎。
這篇文章是否對你有幫助?
發現錯誤或想改進此文章?
在 GitHub 上編輯此頁