第 07 章

GitHub Pages、Actions 與進階應用

GitHub 不只是放程式碼的地方——你可以用 GitHub Pages 免費部署靜態網站,用 Actions 自動化測試與部署流程,還有更多進階功能幫助你提升開發效率。

GitHub Pages(靜態網站部署)

GitHub Pages 讓你直接從 GitHub Repository 部署靜態網站,完全免費。適合個人網站、專案文件、作品集與教學教材。

🆓 完全免費

Public Repo 可免費使用 GitHub Pages,自動提供 username.github.io 網域。

🔄 自動部署

每次 push 到指定分支,GitHub 會自動重新建置並部署你的網站。

🌐 自訂網域

支援自訂網域名稱(Custom Domain),並自動提供 HTTPS 憑證。

啟用 GitHub Pages 的步驟

三種部署方式

根據你的需求選擇最適合的方式。

最簡單的方式——將整個 main 分支的根目錄作為網站。

  1. 在 Repo 中準備好 index.html
  2. 前往 Repo → SettingsPages
  3. Source 選擇 Deploy from a branch
  4. Branch 選擇 main,路徑選 / (root)
  5. 點擊 Save,等待幾分鐘後即可訪問。
# 網站 URL 格式
https://<username>.github.io/<repo-name>/

# 範例
https://alice.github.io/my-portfolio/

適合程式碼與文件分開管理——只部署 docs/ 資料夾的內容。

my-project/
├── src/           ← 程式碼(不會被部署)
├── docs/          ← 網站內容(會被部署)
│   ├── index.html
│   ├── style.css
│   └── guide.html
├── README.md
└── package.json
  1. 將網站檔案放在 docs/ 資料夾中。
  2. Settings → Pages → Branch: main, 路徑: /docs

最靈活的方式——用 GitHub Actions 自訂建置流程。適合需要編譯的框架(如 React、Vue、Jekyll)。

  1. Settings → Pages → Source 選擇 GitHub Actions
  2. GitHub 會建議適合你專案的 workflow 範本。
  3. 或自行建立 .github/workflows/deploy.yml

(詳見本章後半的 Actions 段落。)

GitHub Pages 的限制

項目限制
Repo 大小建議不超過 1 GB
網站大小不超過 1 GB
每月流量100 GB soft limit
建置頻率每小時最多 10 次
支援內容僅靜態內容(HTML/CSS/JS),無法執行後端程式

🔧 實作:部署你的第一個 GitHub Pages 網站

從零到上線的完整流程

# 建立專案
$ mkdir my-site && cd my-site
$ git init

# 建立簡單的網頁
$ cat > index.html <<'EOF'
<!DOCTYPE html>
<html lang="zh-Hant">
<head>
  <meta charset="utf-8">
  <title>我的第一個 GitHub Pages 網站</title>
  <style>
    body { font-family: sans-serif; max-width: 600px; margin: 2rem auto; padding: 0 1rem; }
    h1 { color: #f05033; }
  </style>
</head>
<body>
  <h1>Hello, GitHub Pages!</h1>
  <p>這是我用 Git 部署的第一個網站。</p>
</body>
</html>
EOF

$ git add . && git commit -m "feat: 建立首頁"
# 在 GitHub 建立一個新的 Public Repo(名稱如 my-site)

# 連結遠端並推送
$ git remote add origin git@github.com:你的帳號/my-site.git
$ git push -u origin main
  1. 在 GitHub Repo 頁面 → SettingsPages
  2. Source: Deploy from a branch
  3. Branch: main,路徑: / (root)
  4. 點擊 Save
  5. 等候 1-2 分鐘,頁面上方會出現網站的 URL。
  6. 點擊連結,你的網站就上線了!🎉

GitHub Actions(自動化工作流程)

GitHub Actions 是 GitHub 內建的 CI/CD(持續整合 / 持續部署)平台。它能在特定事件發生時(如 push、PR 建立)自動執行你定義的工作流程——從跑測試、檢查程式碼品質,到自動部署網站或發布套件,全部都能自動完成。

什麼是 CI/CD?

CI(Continuous Integration,持續整合):每次提交程式碼後,自動執行測試,確保新程式碼不會破壞現有功能。

CD(Continuous Deployment,持續部署):測試通過後,自動部署到正式環境,不需人工介入。

flowchart LR A["開發者\npush 程式碼"] --> B["CI\n自動測試"] B -->|通過| C["CD\n自動部署"] B -->|失敗| D["通知開發者\n修正問題"] C --> E["正式環境\n上線"]

為什麼要用 Actions?

  • 減少人為疏忽——自動執行測試,不會忘記跑測試就 merge。
  • 加速交付——程式碼通過測試後自動部署,不需等人操作。
  • 統一標準——自動檢查程式碼風格與品質,團隊協作更一致。
  • 免費使用——Public Repo 完全免費,Private Repo 有免費額度。
  • 生態系豐富——Marketplace 上有超過 20,000 個現成 Action 可以直接使用。

Actions 的六大核心概念

理解 GitHub Actions 的關鍵在於搞清楚六個核心概念的層級關係。下面的架構圖展示了它們如何組合在一起:

flowchart TD EV["🎯 Event(觸發事件)
push / pull_request / schedule / 手動觸發"] EV --> WF["📋 Workflow(工作流程)
.github/workflows/ci.yml"] WF --> J1["⚙️ Job A: build
runs-on: ubuntu-latest"] WF --> J2["⚙️ Job B: deploy
needs: build"] J1 --> S1["Step 1: actions/checkout@v4"] J1 --> S2["Step 2: run: npm install"] J1 --> S3["Step 3: run: npm test"] J2 --> S4["Step 4: actions/checkout@v4"] J2 --> S5["Step 5: 自訂 Action"] J2 --> S6["Step 6: run: deploy.sh"] RN["🖥️ Runner
GitHub 提供的虛擬機"] -.->|執行| J1 RN -.->|執行| J2 style EV fill:#fef3c7,stroke:#f59e0b,color:#000 style WF fill:#dbeafe,stroke:#3b82f6,color:#000 style J1 fill:#dcfce7,stroke:#22c55e,color:#000 style J2 fill:#dcfce7,stroke:#22c55e,color:#000 style RN fill:#fce7f3,stroke:#ec4899,color:#000
一句話理解:當一個 Event 發生時,GitHub 會啟動對應的 Workflow;Workflow 裡有一個或多個 Job;每個 Job 跑在一台 Runner 上,包含若干 Step;而 Step 可以是一行指令,也可以是從 Marketplace 引用的 Action
概念說明類比
Workflow 一個自動化流程,定義在 .github/workflows/ 目錄下的 YAML 檔案中。 一份「自動化劇本」
Event 觸發 workflow 的事件,如 pushpull_requestschedule(定時)。 開演的「鈴聲」
Job workflow 中的一組任務。多個 job 預設平行執行,也可設定依賴順序。 劇本中的「幕」
Step job 中的單一步驟,可以執行指令或使用別人寫好的 Action。 每一幕中的「台詞或動作」
Action 可重用的步驟模組,GitHub Marketplace 上有數千個現成的 Action 可用。 預先排練好的「表演套路」
Runner 執行 workflow 的虛擬機器。GitHub 提供免費的 Ubuntu、macOS、Windows runner。 表演的「舞台」

概念詳解 ① — Workflow(工作流程)

Workflow 是 GitHub Actions 的最上層單位,一個 YAML 檔案就是一個 workflow。每個 Repo 可以有多個 workflow,各自獨立運作。

📁 存放位置

所有 workflow 檔案都放在 .github/workflows/ 目錄下,檔名自訂(如 ci.ymldeploy.yml)。

📄 檔案格式

使用 YAML(.yml / .yaml)格式撰寫,注意縮排很重要——使用空格而非 Tab。

# 一個 Repo 可以有多個 workflow,各司其職:
my-project/
└── .github/
    └── workflows/
        ├── ci.yml          ← 每次 push 時跑測試
        ├── deploy.yml      ← main 分支更新時自動部署
        ├── release.yml     ← 建立 tag 時自動發行
        └── weekly-check.yml ← 每週定時檢查依賴更新

Workflow YAML 的基本結構

# .github/workflows/ci.yml
name: CI Pipeline          # ① workflow 名稱(顯示在 Actions 頁面)

on:                         # ② 觸發條件(Event)
  push:
    branches: [ main ]

jobs:                       # ③ 定義 Job
  test:                     # Job ID(自訂名稱)
    runs-on: ubuntu-latest  # ④ 選擇 Runner
    steps:                  # ⑤ 定義 Steps
      - uses: actions/checkout@v4
      - run: npm test
重點:每個 workflow 檔案只能有一個 name:、一個 on: 和一個 jobs: 區塊。但 jobs: 底下可以定義多個 Job。

概念詳解 ② — Event(觸發事件)

Event 決定了「什麼時候」啟動 workflow。GitHub 支援超過 30 種事件類型,以下是最常用的幾種:

事件類型觸發時機常見用途
push 有人 push 程式碼到指定分支時 跑測試、自動部署
pull_request PR 被建立、更新或重新開啟時 程式碼審查前的自動檢查
schedule 按照 cron 排程定時執行 每日備份、定時更新資料
workflow_dispatch 在 GitHub 網頁上手動點擊觸發 手動部署、除錯用途
release 建立或發布 Release 時 自動打包、發布套件
issues Issue 被建立、標記或關閉時 自動分類、通知

Event 的進階篩選

你可以用 branchespathstypes 等參數縮小觸發範圍,避免不必要的執行:

Event 篩選範例

只在特定條件下才觸發 workflow。

# 只在 push 到 main 或 release/* 分支時觸發
on:
  push:
    branches:
      - main
      - 'release/**'
  pull_request:
    branches:
      - main       # 只有目標為 main 的 PR 才觸發

使用 branches 參數限定觸發的分支。支援 glob 模式(***)。

# 只在 src/ 目錄的程式碼變更時才跑測試
on:
  push:
    paths:
      - 'src/**'
      - 'tests/**'
    paths-ignore:
      - '**.md'        # 修改文件不觸發
      - '.github/**'   # 修改 workflow 不觸發

使用 paths 只在特定目錄有變更時觸發,搭配 paths-ignore 排除不相關的變更。

# 每週一早上 9 點(UTC)自動執行
on:
  schedule:
    - cron: '0 9 * * 1'

# cron 語法:分 時 日 月 星期
# ┌──── 分鐘 (0-59)
# │ ┌──── 小時 (0-23)
# │ │ ┌──── 日 (1-31)
# │ │ │ ┌──── 月 (1-12)
# │ │ │ │ ┌──── 星期 (0-6,0=週日)
# │ │ │ │ │
# * * * * *

# 更多範例:
# '0 0 * * *'    → 每天午夜
# '30 8 * * 1-5' → 週一到週五 08:30
# '0 */6 * * *'  → 每 6 小時
# 在 GitHub 網頁上手動觸發,可帶自訂參數
on:
  workflow_dispatch:
    inputs:
      environment:
        description: '部署目標環境'
        required: true
        default: 'staging'
        type: choice
        options:
          - staging
          - production
      debug:
        description: '啟用除錯模式'
        required: false
        type: boolean
        default: false

workflow_dispatch 讓你可以在 Actions 頁面上按下 Run workflow 按鈕手動觸發,還能傳入自訂參數。

概念詳解 ③ — Job(任務)

Job 是 Workflow 中的「任務單位」。一個 Workflow 可以包含多個 Job,預設會平行(parallel)執行,但也可以用 needs 設定依賴順序。

flowchart LR subgraph "平行執行(預設行為)" direction TB J1["Job: lint
程式碼風格檢查"] J2["Job: test
執行測試"] J3["Job: security
安全性掃描"] end subgraph "依賴執行(needs)" direction TB J4["Job: build
建置專案"] J5["Job: deploy
部署到正式環境"] J4 -->|needs: build| J5 end

Job 的重要屬性

屬性說明範例
runs-on 指定 Runner 的作業系統 ubuntu-latestmacos-latestwindows-latest
needs 定義依賴關係,指定此 Job 必須等哪些 Job 完成 needs: [build, test]
if 條件判斷,符合條件才執行 if: github.ref == 'refs/heads/main'
strategy.matrix 矩陣策略,自動展開多組執行 同時在多個 Node.js 版本上測試
environment 綁定部署環境,可設定審核與 secrets environment: production
outputs 將 Job 的輸出傳遞給下游 Job outputs: { version: ${{ steps.ver.outputs.v }} }

Job 配置範例

從基礎到進階的 Job 設定方式。

jobs:
  # Job 1: 執行測試(先跑)
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci
      - run: npm test

  # Job 2: 建置(test 完成後才跑)
  build:
    needs: test               # ← 等 test 完成
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm run build

  # Job 3: 部署(build 完成後才跑)
  deploy:
    needs: build              # ← 等 build 完成
    runs-on: ubuntu-latest
    steps:
      - run: echo "Deploying..."

使用 needs 建立 test → build → deploy 的依序執行流程。如果 test 失敗,後續 Job 都不會執行。

jobs:
  test:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]
        node-version: [18, 20, 22]
        # 這會自動產生 3×3 = 9 個 Job 組合!
    steps:
      - uses: actions/checkout@v4
      - name: 設定 Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
      - run: npm ci
      - run: npm test

矩陣策略會自動展開所有組合,上面的範例會同時跑 9 個 Job(3 個 OS × 3 個 Node 版本),確保你的程式碼在各種環境都能正常運作。

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm test

  # 只在 main 分支、且 test 通過後才部署
  deploy:
    needs: test
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main' && github.event_name == 'push'
    steps:
      - run: echo "只有 push 到 main 才會跑到這裡"

  # 即使前面的 Job 失敗也要執行的清理工作
  cleanup:
    needs: [test, deploy]
    runs-on: ubuntu-latest
    if: always()              # ← 不管前面是否失敗都執行
    steps:
      - run: echo "清理暫存資源..."

if 條件可以使用 github context(如分支名、事件類型)來決定是否執行。always() 表示無論前面 Job 是否失敗都會執行。

概念詳解 ④ — Step(步驟)

Step 是 Job 中最小的執行單位。每個 Step 依序(sequential)執行,前一個 Step 失敗時,後面的 Step 預設不會繼續。

Step 的兩種類型

run: — 執行指令

直接執行一行或多行 shell 指令,就像你在終端機裡打指令一樣。

steps:
  # 單行指令
  - name: 顯示目錄
    run: ls -la

  # 多行指令(用 | 符號)
  - name: 安裝與測試
    run: |
      npm ci
      npm run build
      npm test

uses: — 使用 Action

引用別人(或官方)已經寫好的可重用 Action,避免自己重寫常見邏輯。

steps:
  # 引用官方 Action
  - name: Checkout 程式碼
    uses: actions/checkout@v4

  # 引用帶參數的 Action
  - name: 設定 Node.js
    uses: actions/setup-node@v4
    with:
      node-version: '20'
      cache: 'npm'

Step 的常用屬性

屬性說明範例
name 步驟名稱,顯示在 Actions 執行日誌中 name: 執行單元測試
run 執行 shell 指令 run: npm test
uses 使用外部 Action uses: actions/checkout@v4
with 傳遞參數給 Action with: { node-version: '20' }
env 設定這個 Step 的環境變數 env: { NODE_ENV: production }
if 條件判斷,符合才執行 if: success()if: failure()
id 步驟 ID,供後續 Step 引用輸出 id: get-version
continue-on-error 即使此步驟失敗,也繼續執行後面的步驟 continue-on-error: true

Step 之間傳遞資料

steps:
  # Step 1: 取得版本號並輸出
  - name: 取得版本號
    id: get-version                  # ← 給這個 Step 一個 ID
    run: |
      VERSION=$(cat package.json | jq -r '.version')
      echo "version=$VERSION" >> $GITHUB_OUTPUT   # ← 寫入輸出

  # Step 2: 使用上一步的輸出
  - name: 顯示版本號
    run: echo "目前版本是 ${{ steps.get-version.outputs.version }}"
    #                       ↑ 透過 steps.{id}.outputs.{key} 讀取
重要:Step 之間使用 $GITHUB_OUTPUT 檔案傳遞資料。格式為 key=value,在下游 Step 用 ${{ steps.{id}.outputs.{key} }} 讀取。

概念詳解 ⑤ — Action(可重用模組)

Action 是 GitHub Actions 生態系的核心——它是可重用的步驟模組,把常見的操作封裝起來,讓你不用從頭寫每一個步驟。

🏪 Marketplace

GitHub Marketplace 上有超過 20,000 個免費的社群 Action,涵蓋測試、部署、通知等各種需求。

✅ 官方維護

actions/ 開頭的 Action 由 GitHub 官方維護,品質穩定、安全性有保障。

🔒 版本鎖定

使用 @v4 指定大版本,確保你的 workflow 不會因為 Action 更新而突然壞掉。

uses 語法格式

# 使用公開的 Action(最常見)
- uses: owner/repo@version        # 格式:帳號/專案@版本
- uses: actions/checkout@v4       # 範例:官方的 checkout
- uses: actions/setup-node@v4     # 範例:官方的 Node.js 設定

# 使用同一個 Repo 中的本地 Action
- uses: ./.github/actions/my-action

# 使用 Docker Hub 上的 Image
- uses: docker://alpine:3.18

最常用的官方 Action

Action用途說明
actions/checkout@v4 拉取程式碼 幾乎每個 workflow 的第一步——把 Repo 的程式碼下載到 Runner 上。
actions/setup-node@v4 設定 Node.js 安裝指定版本的 Node.js,支援快取 npm 依賴。
actions/setup-python@v5 設定 Python 安裝指定版本的 Python,支援快取 pip 依賴。
actions/upload-artifact@v4 上傳產出物 將 build 產物、測試報告等上傳為 Artifact,供其他 Job 或人員下載。
actions/download-artifact@v4 下載產出物 在下游 Job 中下載上游 Job 上傳的 Artifact。
actions/cache@v4 快取依賴 快取 node_modules.pip 等,加速後續執行。
actions/configure-pages@v4 設定 Pages 搭配 deploy-pages 用於 GitHub Pages 部署。
安全建議:使用社群 Action 時,請注意以下幾點:
  • 優先使用 GitHub 官方(actions/)或知名組織維護的 Action。
  • 鎖定版本號(用 @v4 而非 @main),避免不預期的變更。
  • 查看 Action 的原始碼,確認它不會存取你的 secrets 或做不當操作。

概念詳解 ⑥ — Runner(執行環境)

Runner 是實際執行 Job 的虛擬機器。每個 Job 都會在一台全新的 Runner 上啟動,執行完畢後銷毀——這保證了每次執行都是乾淨的環境。

GitHub-hosted Runner

由 GitHub 提供和管理的雲端虛擬機。免安裝、免維護,開箱即用。

  • 自動配置、每次都是全新乾淨的環境。
  • 預裝了常用工具(Git、Node.js、Python、Docker 等)。
  • Public Repo 完全免費,Private Repo 有免費額度。

Self-hosted Runner

在你自己的伺服器上安裝 Runner 軟體,連線到 GitHub 執行 workflow。

  • 適合需要特殊硬體(GPU)或軟體的場景。
  • 可以存取內部網路資源。
  • 需要自行維護和更新。

GitHub-hosted Runner 規格

Runner 標籤作業系統vCPU記憶體儲存空間費率倍數
ubuntu-latest Ubuntu 22.04 / 24.04 4 16 GB 14 GB SSD 1x(基準)
macos-latest macOS 14 (Sonoma) 3 (M1) 7 GB 14 GB SSD 10x
windows-latest Windows Server 2022 4 16 GB 14 GB SSD 2x
費率倍數的意義:以 Private Repo Free 方案每月 2,000 分鐘為例——
  • 使用 ubuntu-latest:可以跑 2,000 分鐘
  • 使用 windows-latest:只能跑 1,000 分鐘(2x 費率,消耗雙倍額度)。
  • 使用 macos-latest:只能跑 200 分鐘(10x 費率)。
建議:除非需要測試 macOS / Windows 環境,否則一律使用 ubuntu-latest 最划算。

Runner 上預裝的常用工具

🔧 開發工具

Git、curl、wget、jq、Docker、Docker Compose

📦 程式語言

Node.js、Python、Ruby、Go、Java、.NET、Rust

☁️ 雲端 CLI

AWS CLI、Azure CLI、Google Cloud CLI、GitHub CLI (gh)

延伸知識:什麼是虛擬機器(VM)?

前面提到 Runner 是一台「虛擬機器」,但虛擬機器到底是什麼?為什麼 GitHub 選擇用 VM 來跑 CI/CD?這個概念不只在 GitHub Actions 中出現——它是現代雲端運算的基石。

虛擬機器的定義

🖥️ 虛擬機器(Virtual Machine)

虛擬機器是透過軟體模擬出來的完整電腦,擁有自己的 CPU、記憶體、硬碟和作業系統。它跑在一台實體電腦(Host)上,但對內部的程式來說,它就像一台獨立的真實電腦。

關鍵技術:Hypervisor(虛擬機器管理程式)——負責在實體硬體上建立和管理多台虛擬機器。

📚 類比理解

把實體伺服器想像成一棟大樓

  • Hypervisor = 大樓的管理員,負責分配空間。
  • 虛擬機器 = 大樓裡的各個獨立公寓,每間都有完整的水電(OS、CPU、RAM)。
  • 公寓之間互不干擾——一間公寓著火,不會影響隔壁。

VM 的運作架構

flowchart TB subgraph HW["實體硬體(Host Machine)"] direction TB CPU["CPU / RAM / 硬碟 / 網路"] end subgraph HV["Hypervisor(虛擬化層)"] direction LR subgraph VM1["VM 1"] OS1["Guest OS
Ubuntu 22.04"] APP1["App A
Node.js 專案"] end subgraph VM2["VM 2"] OS2["Guest OS
Windows Server"] APP2["App B
.NET 專案"] end subgraph VM3["VM 3"] OS3["Guest OS
macOS"] APP3["App C
Swift 專案"] end end HW --> HV style HW fill:#fef3c7,stroke:#f59e0b,color:#000 style HV fill:#dbeafe,stroke:#3b82f6,color:#000 style VM1 fill:#dcfce7,stroke:#22c55e,color:#000 style VM2 fill:#dcfce7,stroke:#22c55e,color:#000 style VM3 fill:#dcfce7,stroke:#22c55e,color:#000
兩種 Hypervisor:
  • Type 1(裸機型):直接裝在硬體上,效能最好。如 VMware ESXi、Microsoft Hyper-V、KVM。雲端服務(AWS、GCP、Azure)都用這種。
  • Type 2(寄宿型):裝在既有 OS 上,方便個人使用。如 VirtualBox、VMware Workstation、Parallels Desktop。

VM vs 容器(Container)

Docker 容器是另一種虛擬化技術,但它和 VM 有根本性的差異:

flowchart TB subgraph LEFT["虛擬機器(VM)"] direction TB HW_L["硬體"] HV_L["Hypervisor"] GOS1["Guest OS"] GOS2["Guest OS"] A1["App A"] A2["App B"] HW_L --> HV_L HV_L --> GOS1 HV_L --> GOS2 GOS1 --> A1 GOS2 --> A2 end subgraph RIGHT["容器(Container)"] direction TB HW_R["硬體"] HOS_R["Host OS"] DOC["Container Engine
Docker"] C1["Container A
App + 依賴"] C2["Container B
App + 依賴"] HW_R --> HOS_R HOS_R --> DOC DOC --> C1 DOC --> C2 end style LEFT fill:#dbeafe,stroke:#3b82f6,color:#000 style RIGHT fill:#dcfce7,stroke:#22c55e,color:#000
比較項目虛擬機器(VM)容器(Container)
隔離程度 完全隔離(各自有獨立 OS) 共用 Host OS 核心,隔離性較低
啟動速度 分鐘級(需開機一整個 OS) 秒級(只啟動應用程式的進程)
資源占用 大(每台 VM 都要一份完整 OS,通常 GB 級) 小(共用 OS,只包含 App + 依賴,通常 MB 級)
可攜性 有限(VM 映像檔通常很大) 優秀(Docker Image 易於分享與遷移)
安全性 高(硬體級隔離,難以突破) 中(共用核心,理論上有逃逸風險)
適用場景 需要完全隔離、不同 OS、高安全性 微服務架構、快速部署、開發環境統一

虛擬機器在現代開發中的角色

☁️ 雲端運算

AWS EC2、Google Compute Engine、Azure VM 本質上都是在賣虛擬機器。你「租」一台 VM,按小時或秒計費。

🔄 CI/CD

GitHub Actions Runner、GitLab Runner、Jenkins Agent 都使用 VM 來提供乾淨的建置環境——就是我們正在學的。

🧪 開發與測試

用 VirtualBox 或 Parallels 在 Mac 上跑 Windows、在 Windows 上跑 Linux,測試跨平台相容性。

🏢 伺服器虛擬化

企業將一台強大的實體伺服器分割成多台 VM,分別跑不同服務(Web Server、Database、Mail Server)。

🔒 安全隔離

在 VM 中開啟可疑檔案或測試惡意程式,即使 VM 被攻陷也不影響 Host。(沙盒 Sandbox 概念)

📸 快照與還原

VM 支援「快照」功能——隨時儲存狀態,出問題時一鍵還原。這在測試環境中非常實用。

為什麼 GitHub Runner 選擇用 VM?

安全性需求

  • GitHub 是公開平台,任何人都可以在 public repo 觸發 workflow。
  • VM 的硬體級隔離確保惡意程式碼無法影響其他用戶。
  • 每次執行完畢,整台 VM 直接銷毀,不留任何痕跡。

一致性需求

  • 每次 Job 都是全新的 VM,保證環境完全相同。
  • 不會因為上一次執行殘留的檔案或設定而產生不可預期的結果。
  • 這就是「用完即丟(Ephemeral)」設計的核心優勢。
補充:雖然 Runner 本身是 VM,但你可以在 Runner 裡面再跑 Docker 容器(Container Job)。這是「VM + Container」的混合架構——VM 負責安全隔離,Container 負責精確的環境控制。在第 08 章會詳細介紹這個進階用法。

六大概念互動關係回顧

學完六大概念後,讓我們用一個完整的範例把它們串起來:

sequenceDiagram participant D as 開發者 participant G as GitHub participant R as Runner (VM) D->>G: git push(Event 觸發) G->>G: 尋找 .github/workflows/ 中符合的 Workflow G->>R: 啟動 Runner(分配虛擬機) R->>R: 執行 Job 1 的 Step 1(checkout Action) R->>R: 執行 Job 1 的 Step 2(run: npm test) R->>R: 執行 Job 1 的 Step 3(run: npm build) R-->>G: Job 1 完成,回報結果 G->>R: 啟動新 Runner 執行 Job 2(needs: Job 1) R->>R: 執行 Job 2 的 Steps... R-->>G: Job 2 完成 G-->>D: 通知:Workflow 執行成功 ✅
# 把六大概念對應到完整範例:
name: Complete CI/CD          # ← Workflow 名稱

on:                            # ← Event
  push:
    branches: [ main ]

jobs:
  test:                        # ← Job
    runs-on: ubuntu-latest     # ← Runner
    steps:                     # ← Steps
      - uses: actions/checkout@v4  # ← Action(可重用模組)
      - run: npm ci                # ← Step(shell 指令)
      - run: npm test

  deploy:
    needs: test                # ← Job 依賴
    runs-on: ubuntu-latest
    if: success()
    steps:
      - uses: actions/checkout@v4
      - uses: actions/configure-pages@v4
      - uses: actions/upload-pages-artifact@v3
        with:
          path: './dist'
      - uses: actions/deploy-pages@v4

撰寫你的第一個 Workflow

Workflow 使用 YAML 格式定義,存放在 .github/workflows/ 目錄下。

範例 Workflow

從簡單到實用的三個範例。

# .github/workflows/hello.yml
name: Hello World

on:
  push:
    branches: [ main ]

jobs:
  greet:
    runs-on: ubuntu-latest
    steps:
      - name: Say Hello
        run: echo "Hello from GitHub Actions!"

      - name: Show Date
        run: date

      - name: Show Git Version
        run: git --version

每次 push 到 main 分支時,這個 workflow 會在 Ubuntu 虛擬機上執行三個指令。

# .github/workflows/test.yml
name: Run Tests

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout 程式碼
        uses: actions/checkout@v4

      - name: 安裝 Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: 安裝依賴
        run: npm ci

      - name: 執行測試
        run: npm test

push 或建立 PR 時自動執行 Node.js 測試。uses 引用的是 GitHub Marketplace 上的現成 Action。

# .github/workflows/deploy-pages.yml
name: Deploy to GitHub Pages

on:
  push:
    branches: [ main ]

permissions:
  contents: read
  pages: write
  id-token: write

jobs:
  deploy:
    runs-on: ubuntu-latest
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup Pages
        uses: actions/configure-pages@v4

      - name: Upload artifact
        uses: actions/upload-pages-artifact@v3
        with:
          path: '.'

      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v4

這是使用 Actions 部署 GitHub Pages 的官方推薦方式。

語法說明
name:workflow 的名稱,會顯示在 GitHub Actions 頁面。
on:定義觸發條件。可以是事件(push、PR)或定時(cron)。
jobs:定義一個或多個 job。
runs-on:指定 runner 的作業系統(ubuntu-latest、macos-latest、windows-latest)。
steps:job 中的步驟列表,依序執行。
uses:使用現成的 Action(格式:owner/repo@version)。
run:直接執行 shell 指令。
with:傳入 Action 需要的參數。
permissions:設定 workflow 的權限(安全性考量)。

Secrets 與環境變數

當 workflow 需要存取 API 金鑰、密碼等敏感資訊時,絕對不能寫在 YAML 檔案中。GitHub 提供了 Secrets 機制來安全地管理這些資訊。

🔐 Secrets(機密)

加密儲存的敏感資訊,設定後只能使用、不能查看原始值。

設定方式:Repo → Settings → Secrets and variables → Actions → New repository secret

# 在 workflow 中使用 Secret
steps:
  - name: 部署到伺服器
    run: ./deploy.sh
    env:
      API_KEY: ${{ secrets.MY_API_KEY }}
      DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }}

🌐 環境變數(Environment Variables)

非敏感的設定值,可以在不同層級設定。

# Workflow 層級(所有 Job 共用)
env:
  NODE_ENV: production

jobs:
  build:
    # Job 層級
    env:
      BUILD_TARGET: web
    steps:
      - name: 建置
        # Step 層級
        env:
          DEBUG: false
        run: npm run build
安全守則:Secrets 在 log 中會自動被 *** 遮蔽。但請注意:不要在 echo 中直接輸出 secret,也不要把 secret 寫入檔案後上傳為 artifact。

Actions 的常見用途

🧪 自動化測試

每次 push 或 PR 自動跑測試,確保程式碼品質。測試不過就不能 merge。

CI 品質保證

🚀 自動部署

測試通過後自動部署到 GitHub Pages、Vercel、AWS 等平台。

CD 部署

📏 程式碼品質

自動執行 ESLint、Prettier 等工具,統一程式碼風格。

Linting 格式化

🏷️ 自動 Release

根據 tag 自動建立 GitHub Release 並產生 changelog。

版本發行

📋 Issue 管理

自動為新 Issue 加標籤、指派人員、回覆範本訊息。

自動化

⏰ 定時任務

用 cron 語法定時執行,例如每天自動備份或更新資料。

排程

其他 GitHub 進階功能

功能說明適用場景
GitHub Codespaces 雲端開發環境,在瀏覽器中直接開啟 VS Code 編輯器,免安裝任何工具。 快速開始開發、教學環境、遠端協作。
GitHub Copilot AI 程式碼助手,在編輯器中即時提供程式碼建議與自動完成。 提升程式碼撰寫效率、學習新語言。
GitHub Discussions Repo 專屬的討論區,像論壇一樣的問答與交流空間。 社群互動、Q&A、功能投票。
GitHub Packages 託管套件(npm、Docker、Maven 等),與 Repo 整合。 發布與管理套件、Docker Image。
GitHub Projects 進階看板工具,支援自訂欄位、自動化規則與多種視圖(表格、看板、時間軸)。 專案管理、Sprint 規劃。
Branch Protection Rules 保護分支的規則:強制 PR 審查、必須通過 CI 測試才能合併。 保護 main 分支穩定性。
Dependabot 自動偵測專案依賴的安全漏洞,並建立 PR 更新到安全版本。 依賴管理、安全維護。

GitHub Actions 的免費額度

方案每月免費額度Storage
Free2,000 分鐘(Linux runner)500 MB
Pro3,000 分鐘1 GB
Team3,000 分鐘2 GB
Enterprise50,000 分鐘50 GB
注意:Public Repo 的 Actions 使用完全免費,不計入額度。上述額度限制僅適用於 Private Repo。macOS 和 Windows runner 的消耗速率比 Linux 高(macOS = 10x,Windows = 2x)。

🔧 動手練習

練習 1:部署 GitHub Pages

  1. 建立一個 Public Repo。
  2. 新增一個簡單的 index.html
  3. 在 Settings → Pages 啟用部署。
  4. 等待幾分鐘,訪問你的網站!
  5. 修改內容 → push → 確認網站自動更新。

練習 2:建立第一個 Workflow

  1. 在 Repo 中建立 .github/workflows/hello.yml
  2. 複製 Hello World 範例的內容。
  3. Commit 並 push。
  4. 在 GitHub Repo → Actions 頁面查看執行結果。
  5. 嘗試修改 workflow 加入更多步驟。

練習 3:矩陣策略測試

  1. 建立一個 Node.js 專案並加入簡單的測試。
  2. 撰寫包含 strategy.matrix 的 workflow。
  3. 設定在 Node 18 與 20 兩個版本上測試。
  4. Push 後在 Actions 頁面觀察多個 Job 平行執行。

練習 4:用 Actions 自動部署 Pages

  1. 在已有 Pages 網站的 Repo 中,Settings → Pages → Source 改為 GitHub Actions
  2. 建立 .github/workflows/deploy-pages.yml
  3. 複製本章的 Deploy Pages 範例。
  4. Push 後確認 Actions 自動部署並更新網站。

本章小結

知識重點

  • GitHub Pages 可以免費部署靜態網站,三種部署方式可選。
  • GitHub Actions 是內建的 CI/CD 平台,用 YAML 定義 workflow。
  • Actions 有六大核心概念:Workflow、Event、Job、Step、Action、Runner。
  • Workflow 是 YAML 檔案,定義自動化流程;Event 是觸發條件。
  • Job 可平行或依序執行;Step 是最小執行單位。
  • Action 是可重用模組;Runner 是執行環境(虛擬機)。
  • Secrets 用於安全管理敏感資訊,環境變數可在不同層級設定。
  • 虛擬機器(VM)透過 Hypervisor 在實體硬體上模擬完整電腦,是雲端運算與 CI/CD 的基石。
  • VM 與容器(Container)互補:VM 提供強隔離,Container 提供輕量快速。
  • Public Repo 的 Actions 免費、Pages 免費。
  • GitHub 還提供 Codespaces、Copilot、Projects 等進階工具。

整門課程回顧

  • Ch01-03:Git 核心(Repo、Init、Commit)。
  • Ch04:GitHub 平台與遠端操作。
  • Ch05:Branch、PR、Issue 協作流程。
  • Ch06:Rebase、Revert、Reset、Stash 進階操作。
  • Ch07:GitHub Pages、Actions、VM 通識與進階應用。
  • Ch08:Runner 進階應用(Docker、Self-hosted、快取與除錯)。
📖 接下來: 你已經掌握了 GitHub Actions 的六大核心概念與 VM 通識知識。 下一章將深入 Runner 的進階應用——Docker 整合、Self-hosted Runner、快取策略與除錯技巧。