今日目標
• 理解 CI/CD 基本概念
• 學會使用 GitHub Actions
• 建立自動化測試和部署
• 整合 Git 工作流程
一、什麼是 CI/CD?
CI (Continuous Integration) - 持續整合
CD (Continuous Deployment) - 持續部署
簡單說:
Push → 自動測試 → 自動建置 → 自動部署
為什麼需要 CI/CD?
❌ 沒有 CI/CD:
✅ 有 CI/CD:
二、GitHub Actions 基礎
核心概念
Workflow(工作流程)
├─ Job 1(工作 1)
│ ├─ Step 1(步驟 1)
│ ├─ Step 2
│ └─ Step 3
└─ Job 2(工作 2)
├─ Step 1
└─ Step 2
觸發時機:
name: CI
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
# 1. 下載程式碼
- uses: actions/checkout@v3
# 2. 設定 Node.js
- uses: actions/setup-node@v3
with:
node-version: '18'
# 3. 安裝依賴
- run: npm ci
# 4. 執行測試
- run: npm test
# 5. 執行 Lint
- run: npm run lint
設定步驟
mkdir -p .github/workflows
vim .github/workflows/ci.yml
git add .github/workflows/ci.yml
git commit -m "ci: 新增 CI workflow"
git push
三、常見 CI/CD 範例
範例 1:前端專案(React/Vue)
name: Frontend CI/CD
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
build-and-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '18'
cache: 'npm' # 快取加速
- name: 安裝依賴
run: npm ci
- name: 執行測試
run: npm test
- name: 建置
run: npm run build
- name: 部署到 GitHub Pages
if: github.ref == 'refs/heads/main'
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./dist
範例 2:後端專案(Node.js/Python)
name: Backend CI/CD
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
# 測試多個版本
strategy:
matrix:
node-version: [16, 18, 20]
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
- run: npm ci
- run: npm test
deploy:
needs: test # 測試通過才部署
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: 部署到伺服器
env:
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
run: |
echo "$SSH_PRIVATE_KEY" > key.pem
chmod 600 key.pem
ssh -i key.pem user@server "cd /app && git pull && npm install && pm2 restart all"
範例 3:Docker 建置和推送
name: Docker Build
on:
push:
branches: [main]
tags: ['v*']
jobs:
docker:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: 登入 Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: 建置並推送
uses: docker/build-push-action@v4
with:
context: .
push: true
tags: |
username/app:latest
username/app:${{ github.sha }}
範例 4:自動發布到 npm
name: Publish to npm
on:
release:
types: [created]
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '18'
registry-url: 'https://registry.npmjs.org'
- run: npm ci
- run: npm test
- run: npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
四、進階功能
steps:
矩陣測試(多版本)
jobs:
test:
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
node: [16, 18, 20]
runs-on: ${{ matrix.os }}
steps:
條件執行
steps:
jobs:
deploy:
steps:
- name: 部署到 ${{ inputs.environment }}
run: npm run deploy:${{ inputs.environment }}
五、完整的 CI/CD 流程範例
name: Complete CI/CD
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '18'
cache: 'npm'
- run: npm ci
- run: npm run lint
- run: npm run format:check
test:
needs: lint
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [16, 18, 20]
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- run: npm ci
- run: npm test
- run: npm run test:coverage
# 上傳覆蓋率報告
- uses: codecov/codecov-action@v3
with:
files: ./coverage/lcov.info
build:
needs: test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '18'
cache: 'npm'
- run: npm ci
- run: npm run build
# 上傳建置結果
- uses: actions/upload-artifact@v3
with:
name: build
path: dist/
deploy-staging:
needs: build
if: github.ref == 'refs/heads/develop'
runs-on: ubuntu-latest
environment:
name: staging
url: https://staging.example.com
steps:
- uses: actions/download-artifact@v3
with:
name: build
- name: 部署
run: echo "Deploy to staging"
deploy-production:
needs: build
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
environment:
name: production
url: https://example.com
steps:
- uses: actions/download-artifact@v3
with:
name: build
- name: 部署
run: echo "Deploy to production"
六、GitLab CI/CD
基本設定
stages:
test:
stage: test
image: node:18
script:
- npm ci
- npm test
cache:
paths:
- node_modules/
build:
stage: build
image: node:18
script:
- npm ci
- npm run build
artifacts:
paths:
- dist/
only:
- main
deploy:
stage: deploy
script:
- echo "Deploy to production"
environment:
name: production
url: https://example.com
only:
- main
七、常見問題處理
問題 1:Workflow 沒有執行
□ workflow 檔案在 .github/workflows/ 目錄
□ 檔案是 .yml 或 .yaml 結尾
□ YAML 語法正確(縮排、格式)
□ 分支名稱正確
□ 有權限執行 Actions(Settings → Actions)
問題 2:測試失敗
jobs:
test:
steps:
- run: npm test
env:
DEBUG: '*' # 開啟 debug 模式
# 或在 workflow 設定
- run: npm test -- --verbose
問題 3:權限問題
permissions:
contents: write # 寫入權限
pull-requests: write # PR 權限
issues: write # Issue 權限
jobs:
deploy:
steps:
- name: 部署
run: echo "deploy"
問題 4:Secret 抓不到
steps:
八、最佳實踐
Workflow 組織
.github/workflows/
├── ci.yml # 測試和檢查
├── deploy-staging.yml # 部署到 staging
├── deploy-prod.yml # 部署到 production
├── release.yml # 發布流程
└── cleanup.yml # 清理任務
快速失敗原則
jobs:
test:
strategy:
fail-fast: true
matrix:
node: [16, 18, 20]
steps:
分離關注點
jobs:
lint:
steps:
- run: npm run lint
test:
needs: lint
steps:
- run: npm test
build:
needs: test
steps:
- run: npm run build
jobs:
all:
steps:
- run: npm run lint && npm test && npm run build
4. 使用可重用的 Workflows
on:
workflow_call:
inputs:
environment:
required: true
type: string
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- run: echo "Deploy to ${{ inputs.environment }}"
jobs:
call-deploy:
uses: ./.github/workflows/reusable-deploy.yml
with:
environment: production
九、實戰範例:個人部落格
name: Blog Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
# 1. 下載程式碼
- uses: actions/checkout@v3
# 2. 設定 Node.js
- uses: actions/setup-node@v3
with:
node-version: '18'
cache: 'npm'
# 3. 安裝依賴
- run: npm ci
# 4. 建置網站
- run: npm run build
# 5. 部署到 GitHub Pages
- uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./public
cname: blog.example.com # 自訂網域
十、監控和通知
Slack 通知
jobs:
notify:
runs-on: ubuntu-latest
if: always() # 無論成功失敗都執行
needs: [test, build, deploy]
steps:
- name: Slack 通知
uses: 8398a7/action-slack@v3
with:
status: ${{ job.status }}
text: '部署結果:${{ job.status }}'
webhook_url: ${{ secrets.SLACK_WEBHOOK }}
Email 通知
jobs:
notify:
steps:
- name: Email 通知
if: failure()
uses: dawidd6/action-send-mail@v3
with:
server_address: smtp.gmail.com
server_port: 465
username: ${{ secrets.EMAIL_USERNAME }}
password: ${{ secrets.EMAIL_PASSWORD }}
subject: 'Build Failed: ${{ github.repository }}'
to: developer@example.com
from: CI/CD Bot
body: 'Build failed. Check: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}'
十一、效能優化
lint:
runs-on: ubuntu-latest
steps: [...]
test:
runs-on: ubuntu-latest
steps: [...]
security-scan:
runs-on: ubuntu-latest
steps: [...]
deploy:
needs: [lint, test, security-scan]
steps: [...]
3. 只在需要時執行
on:
push:
paths:
- 'src/' # 只有 src 變更才執行
- 'package.json'
paths-ignore:
- 'docs/' # 文件變更不執行
- '**.md'
十二、安全性整合
name: Security Checks
on: [push, pull_request]
jobs:
security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
# 1. 掃描敏感資訊
- name: Gitleaks
uses: gitleaks/gitleaks-action@v2
# 2. 依賴套件漏洞掃描
- run: npm audit --audit-level=moderate
# 3. 程式碼安全掃描
- uses: github/codeql-action/init@v2
- uses: github/codeql-action/analyze@v2
# 4. Docker 映像掃描
- name: Trivy 掃描
uses: aquasecurity/trivy-action@master
with:
image-ref: 'myapp:latest'
今日重點回顧
✅ 核心概念:
CI/CD 基礎
GitHub Actions
實用範例
進階功能
最佳實踐
立即行動
□ 為你的專案建立第一個 CI workflow
□ 加入自動測試
□ 測試 push 觸發
□ 加入 Lint 檢查
□ 設定自動部署
□ 加入 Secrets
□ 建立多階段流程
mkdir -p .github/workflows
cat > .github/workflows/ci.yml << 'EOF'
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '18'
cache: 'npm'
- run: npm ci
- run: npm test
- run: npm run lint
EOF
git add .github/workflows/ci.yml
git commit -m "ci: add CI workflow"
git push
常見問題 FAQ
Q1: GitHub Actions 要付費嗎?
公開 repo:免費無限制
私有 repo:
建議:
brew install act
act
act -j test
act push
act pull_request
Q3: 如何除錯 workflow?
使用快取
cache: 'npm'
並行執行
多個 jobs 同時跑
條件執行
只在需要時執行
減少安裝
npm ci 比 npm install 快
使用 artifacts
在 jobs 之間傳遞檔案
實用資源
GitHub Actions:
GitLab CI/CD:
學習資源: