結論:GitHub Actions 是 GitHub 內建的 CI/CD 自動化平台,只要在專案根目錄放一個 YAML 設定檔,就能在每次 push、PR 或排程時間自動執行測試、建置與部署——公開 repo 免費且無分鐘上限,私人 repo 每月附 2,000 分鐘免費額度。 它不需要自己架 Jenkins、不需要額外買 CI 服務,2026 年已成為全球最多開發者使用的 CI/CD 工具。
寫程式最討厭的,不是寫 code,而是「重複做那些明明可以自動化的事」:每次 commit 都要手動跑測試?發佈前手動 build?部署到伺服器要 SSH 進去下指令?這些繁瑣流程,正是 CI/CD(持續整合/持續部署)要消滅的——而 GitHub Actions 讓這件事簡單到「放一個檔案就搞定」。
GitHub Actions 是什麼?
一句話:GitHub Actions 是跑在 GitHub 雲端機器上的自動化腳本執行器。你在專案裡放一個 YAML 檔案描述「什麼時候做什麼事」,GitHub 就會在指定的時機(例如有人 push 程式碼、開了 PR、或時間到了),啟動一台全新的虛擬機器執行你的指令。
graph LR
A[開發者 push / 開 PR] --> B[GitHub Actions<br/>讀取 .github/workflows/*.yml]
B --> C[啟動 Runner<br/>Ubuntu / Windows / macOS]
C --> D[Job:依序執行多個 Step]
D --> E{測試通過?}
E -->|是| F[建置 + 部署]
E -->|否| G[標記失敗<br/>通知開發者]五個核心名詞,先記起來
| 名詞 | 說明 | 白話比喻 |
|---|---|---|
| Workflow | 一個自動化流程,就是 .github/workflows/ 裡的一個 YAML 檔案 | 一張「自動化 SOP 表」 |
| Job | Workflow 裡的工作單位,可多個並行或串接 | 一個部門的任務 |
| Step | Job 裡依序執行的每個小步驟(跑指令或呼叫 Action) | SOP 裡的每個動作 |
| Runner | 實際執行任務的虛擬機器(GitHub 代管或自架) | 執行任務的員工 |
| Event | 觸發 Workflow 的事件(push、PR、定時器等) | 啟動 SOP 的「鈴聲」 |
第一個 Workflow:從 Hello World 開始
所有 workflow 都放在專案的 .github/workflows/ 目錄下,檔名隨意(建議用有意義的名字,如 ci.yml、deploy.yml)。建立 hello.yml:
name: Hello Workflow # workflow 名稱(顯示在 Actions 頁籤)
on: [push] # 觸發事件:每次 push 都執行
jobs:
hello: # job 名稱(自訂)
runs-on: ubuntu-latest # 執行環境:最新版 Ubuntu
steps:
- name: 打招呼
run: echo "Hello, most.tw readers!"
把這個檔案 commit 並 push 到 GitHub,打開 repo 的 Actions 頁籤,就會看到 workflow 正在執行。綠勾代表成功——恭喜,你的第一個 CI/CD pipeline 上線了。
事件觸發器:控制「什麼時候跑」
on: 是 workflow 的靈魂。2026 年最常用的觸發方式:
| 觸發器 | 語法 | 典型用途 |
|---|---|---|
| Push | on: [push] | 每次推 code 跑測試 |
| Pull Request | on: [pull_request] | PR 開立/更新時檢查 |
| 定時 | on: schedule: - cron: '0 20 * * *' | 每日定時任務(注意是 UTC) |
| 手動 | on: workflow_dispatch | 從 GitHub 網頁/API 手動觸發 |
| 發版 | on: release: types: [published] | 發佈 Release 時部署 |
| 標籤 | on: push: tags: ['v*'] | 推版號標籤時建置 |
實務上最常搭配過濾器,避免浪費分鐘數——例如「只在 main 分支、且只有改到程式碼時才跑」:
on:
push:
branches: [main] # 只在 main 分支
paths:
- 'src/**' # 只有 src/ 目錄變動才觸發
- '*.py'
pull_request:
branches: [main]
workflow_dispatch: {} # 保留手動觸發能力
💡 時區提醒:
schedule的 cron 一律是 UTC 時間。想每天台灣時間早上 8 點跑,要寫cron: '0 0 * * *'(UTC 0:00 = 台灣 8:00)。2026 年起官方文件也支援在 cron 表達式後直接標註時區,例如cron: '30 5 * * 1-5'搭配timezone: 'Asia/Taipei'的寫法已普遍可用,但傳統 UTC 寫法永遠不會錯。
常用 Action 與 2026 最新版本
Action 是別人寫好的「現成步驟」,用 uses: 呼叫。以下是 2026 年 9 月實測的最新主要版本(建議釘選 major 版本,例如 @v7,GitHub 會自動帶入該系列的次要更新):
| Action | 建議版本 | 用途 |
|---|---|---|
actions/checkout | @v7 | 把 repo 程式碼 checkout 到 Runner(幾乎每個 workflow 第一步) |
actions/setup-python | @v7 | 安裝指定 Python 版本,內建 pip 快取 |
actions/cache | @v6 | 快取相依套件(pip、npm、Hugo 資源等),省 50% 以上時間 |
actions/upload-artifact | @v7 | 把 build 產物上傳保存(預設保留 90 天) |
peaceiris/actions-hugo | @v3 | 安裝指定版本 Hugo,靜態網站 CI 標配 |
標準 Python 測試 workflow 長這樣(setup-python 的 cache: 'pip' 會自動快取相依套件):
name: Python CI
on:
push:
paths: ['**.py', 'requirements*.txt']
pull_request:
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/setup-python@v7
with:
python-version: '3.13'
cache: 'pip' # 自動快取 pip 相依
- run: pip install -r requirements-dev.txt
- run: pytest # 跑測試
- run: ruff check . # 語法檢查(搭配 ruff-action 更省事)
想看 Action 目前最新版本?打開 GitHub Marketplace 搜尋,或直接看 repo 的 Releases 頁面。本站的 Ruff 完整教學 就是 Ruff + GitHub Actions 整合的實戰範例。
Matrix 矩陣:一次測多種版本
想同時測 Python 3.11 / 3.12 / 3.13,不必複製三份 job——用 strategy.matrix 一行搞定:
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.11', '3.12', '3.13'] # 自動展開成 3 個 job
os: [ubuntu-latest, windows-latest] # 多軸:共 6 個 job
steps:
- uses: actions/checkout@v7
- uses: actions/setup-python@v7
with:
python-version: ${{ matrix.python-version }}
- run: pytest
Matrix 很強大,但也會消耗大量分鐘數——私人 repo 請節制使用,並善用 paths 過濾減少觸發次數。
Secrets、環境變數與 GITHUB_TOKEN
- Secrets:在 repo 的 Settings → Secrets and variables → Actions 設定,YAML 用
${{ secrets.XXX }}讀取。GitHub 會自動遮罩 log 中的 secret 值。 - 環境變數:三種 scope——
env:放在 workflow 層(全域)、job 層(該 job)、step 層(該 step 專用)。 - GITHUB_TOKEN:GitHub 自動產生的臨時 token,用來 push、開 issue、發 Release 等。2026 年鐵則:最小權限——沒用到就不要給權限:
name: Release
on:
release:
types: [published]
permissions: # workflow 層級:預設全關
contents: read # 只需要讀取 repo
jobs:
build:
permissions:
contents: write # 這個 job 才放寬到可寫
steps:
- uses: actions/checkout@v7
- run: ./build.sh
⚠️ GITHUB_TOKEN 只在同一 repo 內有效。要部署到 Netlify、推 Docker Hub,請在 Settings → Secrets 存放該服務的 token(例如 Netlify Personal Access Token),再以
${{ secrets.NETLIFY_AUTH_TOKEN }}使用。
免費額度:公開 repo 免費無限,私人 repo 每月 2,000 分鐘
| 方案 | 公開 repo | 私人 repo 免費分鐘 | 超出計費(Linux 2vCPU) |
|---|---|---|---|
| Free | 免費、無上限 | 2,000 分鐘/月 | 約 US$0.008/分鐘 |
| Pro | 免費、無上限 | 3,000 分鐘/月 | 同上 |
| Team | 免費、無上限 | 3,000 分鐘/月 | 同上 |
另外:macOS Runner 分鐘數以 10 倍計費、Windows 以 2 倍計費(跑 1 分鐘扣 10/2 分鐘額度),所以日常測試用 Linux 最划算。若公司有閒置伺服器,也可以自架 Runner(settings → Actions → Runner),完全不吃額度。
實戰:Hugo 靜態網站自動部署到 Netlify
這是本站讀者最需要的場景——把 Hugo 部落格 從「手動 build + 手動上傳」變成「push 就自動發佈」。流程:checkout → 裝 Hugo → build → 上傳到 Netlify:
name: Deploy Hugo to Netlify
on:
push:
branches: [main]
workflow_dispatch: {}
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
with:
submodules: true # 有 theme submodule 一定要開
- name: 安裝 Hugo
uses: peaceiris/actions-hugo@v3
with:
hugo-version: '0.147.0' # 釘選與本地一致的版本
extended: true # 需要 Sass/SCSS 時開啟
- name: Build
run: hugo --minify --gc
- name: 部署到 Netlify
uses: nwtgck/actions-netlify@v3
with:
publish-dir: './public' # Hugo 輸出目錄
production-branch: main
deploy-message: "Deploy from GitHub Actions"
env:
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}
兩個 Secret 先到 Netlify 申請:NETLIFY_AUTH_TOKEN(Netlify 帳號 Settings → Applications → Personal access tokens)與 NETLIFY_SITE_ID(Site settings → Site details → API ID)。之後每次 push 到 main,網站就會自動重新 build 並發佈——本地 build 驗證的習慣還是要保留(本站慣例是 hugo --cleanDestinationDir --minify --gc),CI 是第二道防線,不是唯一防線。
2026 年五大最佳實務與地雷
- 🔒 Action 釘選 commit SHA(供應鏈安全):官方與安全社群現在強烈建議把第三方 Action 釘到完整 commit SHA 而非版本標籤——標籤可以被移動或覆寫,有心人一旦取得 Action repo 的寫入權,就能讓你的 CI 執行惡意程式碼。寫法:
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v7.0.1,並用 Dependabot 自動更新。 - 🚫 避免在
pull_request_target事件下 checkout 不信任程式碼:pull_request_target會用「基底分支的 secret」執行,若你又 checkout 了 PR 的程式碼,等於把 secret 交給任何開 PR 的人——這是 CI 供應鏈攻擊的頭號溫床。需要 secret 又要審 PR,請改用「先審核、後以workflow_dispatch或 comment 觸發」的兩段式設計。 - 🕐 用
concurrency取消重複執行:連續 push 多次時,舊的執行通常沒意義。加上concurrency: { group: ci-${{ github.ref }}, cancel-in-progress: true }讓新 push 自動取消舊 run,省分鐘又省排隊時間。 - 🔑 Secrets 最小化:不要整個雲端金鑰丟進 Secrets——2026 年的最佳解是 OIDC(
permissions: id-token: write+ 雲端角色綁定),讓 Runner 用短命憑證直接跟 AWS/GCP/Azure 換權限,金鑰根本不存在 repo 裡。 - 🐌 快取策略:pip/npm 快取、Hugo
resources目錄快取都能大幅加速;但快取 key 要綁定 lockfile 內容(如hashFiles('**/requirements.txt')),否則相依更新後會一直用到舊快取。
總結
GitHub Actions 的學習曲線比 Jenkins 平滑太多:檔案放對位置、YAML 寫對、Action 選對,一套自動化就完成了。建議照這篇的順序動手做一遍:先跑 Hello World 確認機制,再加測試、加 Matrix,最後接部署——兩小時內你就能擁有自己的自動化發佈流水線。
延伸閱讀
- Hugo 靜態網站生成器:重塑網頁創建的未來
- Ruff 完整教學 2026:Python 最速 Linter 與 Formatter(含 GitHub Actions CI 實戰)
- Caddy 完整教學 2026:自動 HTTPS 網頁伺服器,從 Caddyfile、反向代理到 Docker 部署一次學會
- n8n 完整教學 2026:開源 AI 自動化平台(另一種「自動化」思維)
