Some checks failed
CD Pipeline / deploy (push) Failing after 59s
- 建立 Gitea Actions CD pipeline (.gitea/workflows/cd.yaml) - 部署模式: rsync Python 檔案至 188 → docker restart (volume mount) - Dockerfile/requirements 變動時自動重建 Docker image - 部署通知: Telegram (開始/成功/失敗) - 健康檢查: https://mo.wooo.work/health (最多 5 次重試) - 同步最新 CLAUDE.md / ADR-008 / memory (2026-04-19) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
661 lines
18 KiB
Markdown
661 lines
18 KiB
Markdown
# MOMO Pro System - CI/CD 機制評估報告
|
||
|
||
## 執行摘要
|
||
|
||
本文件評估 MOMO Pro System 導入 CI/CD(持續整合/持續部署)機制的建議方案。
|
||
|
||
**現況分析**:
|
||
- 部署方式:手動執行 `deploy.sh` 腳本(使用 gcloud 命令)
|
||
- 版本控制:本地 Git 倉庫,尚未設定遠端倉庫
|
||
- 測試覆蓋:無自動化測試套件
|
||
- 部署環境:GCP VM (asia-east1-a), e2-standard-2
|
||
|
||
**建議方案**:GitHub Actions(推薦)或 GitLab CI
|
||
|
||
---
|
||
|
||
## 1. 平台選擇評估
|
||
|
||
### 1.1 GitHub Actions(推薦)✅
|
||
|
||
**優點**:
|
||
- 與 GitHub 原生整合,無需額外設定
|
||
- 每月 2,000 分鐘免費額度(私有倉庫)
|
||
- 公有倉庫完全免費
|
||
- 豐富的 Marketplace Actions 可重用
|
||
- 文件齊全,社群活躍
|
||
- 支援 Self-hosted Runners(可在 GCP VM 上運行,節省成本)
|
||
|
||
**缺點**:
|
||
- 需要將程式碼推送到 GitHub
|
||
- 超過免費額度後需付費($0.008/分鐘)
|
||
- 相對 GitLab CI,功能較精簡
|
||
|
||
**適用場景**:
|
||
- 開源或小型團隊專案
|
||
- 需要快速上手的 CI/CD 解決方案
|
||
- 預算有限,希望最大化利用免費額度
|
||
|
||
**成本估算**:
|
||
- 免費額度:2,000 分鐘/月(私有倉庫)
|
||
- 每次 CI/CD 執行約 5-10 分鐘
|
||
- 預計每月約 100-200 次部署 → **完全免費**(使用 Self-hosted Runner)
|
||
|
||
---
|
||
|
||
### 1.2 GitLab CI
|
||
|
||
**優點**:
|
||
- 可以 Self-hosted(完全控制)
|
||
- 內建 Container Registry
|
||
- 更強大的 Pipeline 配置功能
|
||
- 免費版功能豐富
|
||
- 每月 400 分鐘免費額度(私有倉庫,GitLab.com)
|
||
|
||
**缺點**:
|
||
- Self-hosted 需要額外維護
|
||
- GitLab.com 免費額度較少(400 分鐘)
|
||
- 學習曲線較陡峭
|
||
- 如果使用 GitLab.com,需要遷移程式碼
|
||
|
||
**適用場景**:
|
||
- 大型企業專案
|
||
- 需要更複雜的 Pipeline 流程
|
||
- 已有 GitLab 基礎設施
|
||
|
||
**成本估算**:
|
||
- GitLab.com 免費額度:400 分鐘/月
|
||
- Self-hosted:需額外 VM 資源(約 $20-50/月)
|
||
|
||
---
|
||
|
||
### 1.3 建議結論
|
||
|
||
**推薦 GitHub Actions**,理由:
|
||
1. 免費額度充足(2,000 分鐘 + Self-hosted Runner 無限制)
|
||
2. 與 GitHub 生態系統整合度高
|
||
3. 學習成本低,快速上手
|
||
4. 可在現有 GCP VM 上運行 Self-hosted Runner,完全免費
|
||
|
||
---
|
||
|
||
## 2. CI/CD Pipeline 設計
|
||
|
||
### 2.1 Pipeline 階段規劃
|
||
|
||
```
|
||
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
|
||
│ Trigger │ -> │ Build │ -> │ Test │ -> │ Deploy │
|
||
│ (Git Push) │ │ (安裝依賴) │ │ (自動測試) │ │ (部署到GCP) │
|
||
└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
|
||
```
|
||
|
||
### 2.2 建議的 Workflow
|
||
|
||
#### 階段 1:程式碼檢查(Linting & Security)
|
||
- **觸發條件**:Pull Request 或 Push 到 main/develop
|
||
- **執行內容**:
|
||
- Python 語法檢查(flake8 / pylint)
|
||
- 安全漏洞掃描(bandit)
|
||
- 程式碼格式檢查(black)
|
||
- **目標**:確保程式碼品質和安全性
|
||
- **執行時間**:~1-2 分鐘
|
||
|
||
#### 階段 2:自動化測試(Testing)
|
||
- **觸發條件**:通過階段 1
|
||
- **執行內容**:
|
||
- 單元測試(pytest)
|
||
- 整合測試(測試資料庫操作)
|
||
- API 端點測試(測試 Flask routes)
|
||
- **目標**:確保功能正確性
|
||
- **執行時間**:~2-3 分鐘
|
||
|
||
#### 階段 3:建置與打包(Build)
|
||
- **觸發條件**:通過階段 2
|
||
- **執行內容**:
|
||
- 安裝 Python 依賴(pip install -r requirements.txt)
|
||
- 檢查依賴版本衝突
|
||
- 建置文件版本號
|
||
- **目標**:確保可部署性
|
||
- **執行時間**:~1-2 分鐘
|
||
|
||
#### 階段 4:部署(Deployment)
|
||
- **觸發條件**:
|
||
- **自動觸發**:Push 到 main 分支
|
||
- **手動觸發**:透過 GitHub Actions UI 手動執行
|
||
- **執行內容**:
|
||
- 備份遠端資料庫
|
||
- 上傳程式碼到 GCP VM
|
||
- 重啟服務(systemctl restart momo)
|
||
- 健康檢查(確認服務正常運行)
|
||
- 失敗時自動回滾
|
||
- **目標**:零停機部署
|
||
- **執行時間**:~3-5 分鐘
|
||
|
||
---
|
||
|
||
## 3. 具體實作方案
|
||
|
||
### 3.1 GitHub Actions 實作
|
||
|
||
#### 目錄結構
|
||
```
|
||
.github/
|
||
└── workflows/
|
||
├── ci.yml # 持續整合(測試、檢查)
|
||
├── deploy.yml # 持續部署(部署到 GCP)
|
||
└── backup.yml # 定期備份任務(每日)
|
||
```
|
||
|
||
#### 範例:`.github/workflows/ci.yml`
|
||
```yaml
|
||
name: CI - Continuous Integration
|
||
|
||
on:
|
||
pull_request:
|
||
branches: [main, develop]
|
||
push:
|
||
branches: [develop]
|
||
|
||
jobs:
|
||
lint:
|
||
name: 程式碼檢查
|
||
runs-on: ubuntu-latest
|
||
steps:
|
||
- uses: actions/checkout@v4
|
||
|
||
- name: 設定 Python 環境
|
||
uses: actions/setup-python@v5
|
||
with:
|
||
python-version: '3.13'
|
||
|
||
- name: 安裝檢查工具
|
||
run: |
|
||
pip install flake8 bandit black
|
||
|
||
- name: Python 語法檢查
|
||
run: flake8 app.py scheduler.py --max-line-length=120
|
||
|
||
- name: 安全漏洞掃描
|
||
run: bandit -r . -x ./venv,./lib
|
||
|
||
- name: 程式碼格式檢查
|
||
run: black --check app.py scheduler.py
|
||
|
||
test:
|
||
name: 自動化測試
|
||
runs-on: ubuntu-latest
|
||
needs: lint
|
||
steps:
|
||
- uses: actions/checkout@v4
|
||
|
||
- name: 設定 Python 環境
|
||
uses: actions/setup-python@v5
|
||
with:
|
||
python-version: '3.13'
|
||
|
||
- name: 安裝依賴
|
||
run: |
|
||
pip install -r requirements.txt
|
||
pip install pytest pytest-cov
|
||
|
||
- name: 執行測試
|
||
run: |
|
||
pytest tests/ -v --cov=. --cov-report=html
|
||
|
||
- name: 上傳測試覆蓋率報告
|
||
uses: actions/upload-artifact@v4
|
||
with:
|
||
name: coverage-report
|
||
path: htmlcov/
|
||
```
|
||
|
||
#### 範例:`.github/workflows/deploy.yml`
|
||
```yaml
|
||
name: CD - Deploy to GCP
|
||
|
||
on:
|
||
push:
|
||
branches: [main]
|
||
workflow_dispatch: # 允許手動觸發
|
||
|
||
jobs:
|
||
deploy:
|
||
name: 部署到 GCP Production
|
||
runs-on: ubuntu-latest
|
||
environment:
|
||
name: production
|
||
url: http://35.194.172.48
|
||
|
||
steps:
|
||
- uses: actions/checkout@v4
|
||
|
||
- name: 設定 GCP 認證
|
||
uses: google-github-actions/auth@v2
|
||
with:
|
||
credentials_json: ${{ secrets.GCP_SA_KEY }}
|
||
|
||
- name: 設定 gcloud CLI
|
||
uses: google-github-actions/setup-gcloud@v2
|
||
|
||
- name: 備份遠端資料庫
|
||
run: |
|
||
gcloud compute ssh momo-server \
|
||
--zone=asia-east1-a \
|
||
--command="bash ~/momo_pro_system/backup_system.py"
|
||
|
||
- name: 上傳程式碼
|
||
run: |
|
||
gcloud compute scp --recurse \
|
||
--exclude='.git' --exclude='venv' --exclude='logs' \
|
||
./*.py ./*.html \
|
||
momo-server:~/momo_pro_system/ \
|
||
--zone=asia-east1-a
|
||
|
||
- name: 重啟服務
|
||
run: |
|
||
gcloud compute ssh momo-server \
|
||
--zone=asia-east1-a \
|
||
--command="sudo systemctl restart momo"
|
||
|
||
- name: 健康檢查
|
||
run: |
|
||
sleep 10
|
||
gcloud compute ssh momo-server \
|
||
--zone=asia-east1-a \
|
||
--command="
|
||
if sudo systemctl is-active --quiet momo; then
|
||
echo '✓ 服務運行正常'
|
||
exit 0
|
||
else
|
||
echo '✗ 服務啟動失敗'
|
||
sudo journalctl -u momo -n 50 --no-pager
|
||
exit 1
|
||
fi
|
||
"
|
||
|
||
- name: 部署失敗時回滾
|
||
if: failure()
|
||
run: |
|
||
echo "部署失敗,執行回滾..."
|
||
gcloud compute ssh momo-server \
|
||
--zone=asia-east1-a \
|
||
--command="bash ~/momo_pro_system/rollback_latest.sh"
|
||
```
|
||
|
||
---
|
||
|
||
### 3.2 Self-hosted Runner 設定(節省成本)
|
||
|
||
在 GCP VM 上安裝 GitHub Actions Runner,讓 CI/CD 在自己的伺服器上執行(完全免費)。
|
||
|
||
#### 安裝步驟(在 GCP VM 上執行)
|
||
```bash
|
||
# 1. 建立 Runner 目錄
|
||
mkdir -p ~/actions-runner && cd ~/actions-runner
|
||
|
||
# 2. 下載 Runner
|
||
curl -o actions-runner-linux-x64-2.313.0.tar.gz \
|
||
-L https://github.com/actions/runner/releases/download/v2.313.0/actions-runner-linux-x64-2.313.0.tar.gz
|
||
|
||
# 3. 解壓縮
|
||
tar xzf ./actions-runner-linux-x64-2.313.0.tar.gz
|
||
|
||
# 4. 配置 Runner(需要 GitHub Token)
|
||
./config.sh --url https://github.com/YOUR_USERNAME/momo_pro_system \
|
||
--token YOUR_TOKEN
|
||
|
||
# 5. 安裝為系統服務
|
||
sudo ./svc.sh install
|
||
sudo ./svc.sh start
|
||
```
|
||
|
||
使用 Self-hosted Runner 後,所有 CI/CD 任務都在您的 GCP VM 上執行,**完全免費**。
|
||
|
||
---
|
||
|
||
## 4. 自動化測試策略
|
||
|
||
### 4.1 測試框架選擇:pytest
|
||
|
||
建議使用 `pytest` 作為主要測試框架,理由:
|
||
- Python 最流行的測試框架
|
||
- 語法簡潔,易於編寫和維護
|
||
- 豐富的插件生態系統
|
||
- 支援測試覆蓋率報告
|
||
|
||
### 4.2 測試架構規劃
|
||
|
||
```
|
||
tests/
|
||
├── __init__.py
|
||
├── conftest.py # pytest 配置和 fixtures
|
||
├── test_app.py # Flask 路由測試
|
||
├── test_database.py # 資料庫操作測試
|
||
├── test_scheduler.py # 排程器測試
|
||
├── test_crawler.py # 爬蟲測試
|
||
└── test_email.py # 郵件發送測試
|
||
```
|
||
|
||
### 4.3 測試範例
|
||
|
||
#### `tests/conftest.py`(測試配置)
|
||
```python
|
||
import pytest
|
||
from app import app, db
|
||
|
||
@pytest.fixture
|
||
def client():
|
||
"""Flask 測試客戶端"""
|
||
app.config['TESTING'] = True
|
||
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///:memory:'
|
||
|
||
with app.test_client() as client:
|
||
with app.app_context():
|
||
db.create_all()
|
||
yield client
|
||
|
||
@pytest.fixture
|
||
def auth_client(client):
|
||
"""已登入的測試客戶端"""
|
||
client.post('/login', data={
|
||
'username': 'admin',
|
||
'password': 'test_password'
|
||
})
|
||
return client
|
||
```
|
||
|
||
#### `tests/test_app.py`(路由測試)
|
||
```python
|
||
def test_index_redirect(client):
|
||
"""測試首頁重定向到登入頁面"""
|
||
response = client.get('/')
|
||
assert response.status_code == 302
|
||
assert '/login' in response.location
|
||
|
||
def test_login_success(client):
|
||
"""測試登入成功"""
|
||
response = client.post('/login', data={
|
||
'username': 'admin',
|
||
'password': 'correct_password'
|
||
})
|
||
assert response.status_code == 302
|
||
assert '/' in response.location
|
||
|
||
def test_dashboard_access(auth_client):
|
||
"""測試已登入用戶可訪問儀表板"""
|
||
response = auth_client.get('/dashboard')
|
||
assert response.status_code == 200
|
||
assert b'dashboard' in response.data.lower()
|
||
```
|
||
|
||
#### `tests/test_database.py`(資料庫測試)
|
||
```python
|
||
from datetime import date
|
||
|
||
def test_sales_query(auth_client):
|
||
"""測試銷售數據查詢"""
|
||
# 插入測試數據
|
||
from database.models import RealtimeSalesMonthly
|
||
test_data = RealtimeSalesMonthly(
|
||
日期=date.today(),
|
||
商品ID='TEST001',
|
||
商品名稱='測試商品',
|
||
銷售數量=100,
|
||
銷售金額=5000
|
||
)
|
||
db.session.add(test_data)
|
||
db.session.commit()
|
||
|
||
# 查詢測試
|
||
result = RealtimeSalesMonthly.query.filter_by(商品ID='TEST001').first()
|
||
assert result is not None
|
||
assert result.銷售數量 == 100
|
||
```
|
||
|
||
### 4.4 測試執行
|
||
|
||
```bash
|
||
# 執行所有測試
|
||
pytest tests/ -v
|
||
|
||
# 執行測試並生成覆蓋率報告
|
||
pytest tests/ --cov=. --cov-report=html
|
||
|
||
# 執行特定測試檔案
|
||
pytest tests/test_app.py -v
|
||
|
||
# 執行特定測試函數
|
||
pytest tests/test_app.py::test_login_success -v
|
||
```
|
||
|
||
---
|
||
|
||
## 5. 零停機部署策略
|
||
|
||
### 5.1 Blue-Green 部署(推薦)
|
||
|
||
**概念**:維護兩個相同的生產環境(Blue 和 Green),部署時切換流量。
|
||
|
||
**實作方式**:
|
||
```bash
|
||
# 1. 部署到 Green 環境(新版本)
|
||
gcloud compute ssh momo-server --command="
|
||
# 複製當前版本到 blue 目錄
|
||
cp -r ~/momo_pro_system ~/momo_pro_system_blue
|
||
|
||
# 部署新版本到 green 目錄
|
||
cd ~/momo_pro_system_green
|
||
git pull origin main
|
||
|
||
# 啟動 Green 服務(Port 5001)
|
||
sudo systemctl restart momo-green
|
||
"
|
||
|
||
# 2. 健康檢查 Green 環境
|
||
curl http://localhost:5001/health
|
||
|
||
# 3. 切換 Nginx 流量到 Green
|
||
# 修改 /etc/nginx/sites-available/momo
|
||
# proxy_pass http://127.0.0.1:5001; # 從 5000 切換到 5001
|
||
|
||
# 4. 重新載入 Nginx(無停機)
|
||
sudo nginx -s reload
|
||
|
||
# 5. 停止 Blue 環境
|
||
sudo systemctl stop momo-blue
|
||
```
|
||
|
||
**優點**:
|
||
- 完全零停機
|
||
- 可快速回滾(切換回 Blue)
|
||
- 可進行 A/B 測試
|
||
|
||
**缺點**:
|
||
- 需要雙倍資源(兩個服務同時運行)
|
||
- 配置較複雜
|
||
|
||
---
|
||
|
||
### 5.2 Rolling 更新(簡化版,推薦用於小型專案)
|
||
|
||
**概念**:先更新程式碼,然後快速重啟服務。
|
||
|
||
**實作方式**(現有 deploy.sh 已實現):
|
||
```bash
|
||
# 1. 備份資料庫
|
||
bash ~/momo_pro_system/backup_system.py
|
||
|
||
# 2. 上傳新程式碼
|
||
gcloud compute scp *.py *.html momo-server:~/momo_pro_system/
|
||
|
||
# 3. 重啟服務(Gunicorn graceful reload)
|
||
sudo systemctl reload momo # 使用 reload 而非 restart
|
||
|
||
# 4. 健康檢查
|
||
sleep 5
|
||
curl http://localhost:5000/health || {
|
||
echo "部署失敗,回滾..."
|
||
# 從備份還原
|
||
bash ~/momo_pro_system/rollback_latest.sh
|
||
}
|
||
```
|
||
|
||
**優點**:
|
||
- 簡單易實作
|
||
- 資源消耗少
|
||
- 適合小型專案
|
||
|
||
**缺點**:
|
||
- 有短暫停機(約 2-5 秒)
|
||
- 回滾較慢
|
||
|
||
---
|
||
|
||
### 5.3 建議實作
|
||
|
||
**階段 1(立即可行)**:使用 Rolling 更新 + Gunicorn Graceful Reload
|
||
- 修改 `momo.service`,使用 `ExecReload=/bin/kill -HUP $MAINPID`
|
||
- 部署時執行 `systemctl reload momo` 而非 `restart`
|
||
|
||
**階段 2(長期目標)**:Blue-Green 部署
|
||
- 當業務量增長後,再實作完整的 Blue-Green 部署
|
||
|
||
---
|
||
|
||
## 6. 密鑰管理
|
||
|
||
### 6.1 GitHub Secrets 配置
|
||
|
||
需要在 GitHub Repository Settings > Secrets 中新增:
|
||
|
||
| Secret 名稱 | 說明 | 取得方式 |
|
||
|------------|------|----------|
|
||
| `GCP_SA_KEY` | GCP Service Account JSON 金鑰 | 在 GCP Console 建立 Service Account 並下載 JSON |
|
||
| `GCP_PROJECT_ID` | GCP 專案 ID | GCP Console 查看 |
|
||
| `GCP_ZONE` | GCP VM 區域 | `asia-east1-a` |
|
||
| `GCP_INSTANCE` | GCP VM 實例名稱 | `momo-server` |
|
||
| `ADMIN_PASSWORD_HASH` | 管理員密碼雜湊 | 現有 `generate_password_hash.py` 生成 |
|
||
|
||
### 6.2 GCP Service Account 權限
|
||
|
||
需要賦予 Service Account 以下權限:
|
||
- `Compute Instance Admin (v1)` - 管理 VM
|
||
- `Service Account User` - 使用 Service Account
|
||
- `Storage Object Viewer` - 讀取 Cloud Storage(如果使用)
|
||
|
||
---
|
||
|
||
## 7. 實作階段規劃
|
||
|
||
### 階段 1:基礎設施準備(1-2 天)
|
||
- [ ] 將專案推送到 GitHub 私有倉庫
|
||
- [ ] 建立 GCP Service Account 並配置權限
|
||
- [ ] 在 GitHub 設定 Secrets
|
||
- [ ] 安裝 Self-hosted Runner(可選,節省成本)
|
||
|
||
### 階段 2:建立測試框架(3-5 天)
|
||
- [ ] 安裝 pytest 和相關插件
|
||
- [ ] 撰寫基本測試(路由測試、資料庫測試)
|
||
- [ ] 建立測試數據 fixtures
|
||
- [ ] 達到 >60% 測試覆蓋率
|
||
|
||
### 階段 3:設定 CI Pipeline(1-2 天)
|
||
- [ ] 建立 `.github/workflows/ci.yml`
|
||
- [ ] 配置程式碼檢查(flake8, bandit)
|
||
- [ ] 配置自動化測試
|
||
- [ ] 測試 PR 觸發 CI
|
||
|
||
### 階段 4:設定 CD Pipeline(2-3 天)
|
||
- [ ] 建立 `.github/workflows/deploy.yml`
|
||
- [ ] 整合現有 `deploy.sh` 腳本
|
||
- [ ] 實作自動備份機制
|
||
- [ ] 實作健康檢查和回滾
|
||
- [ ] 測試自動部署流程
|
||
|
||
### 階段 5:優化與監控(持續進行)
|
||
- [ ] 整合 Prometheus 監控到 CI/CD
|
||
- [ ] 設定部署失敗通知(Slack / Email)
|
||
- [ ] 優化部署速度
|
||
- [ ] 建立部署文件和 Runbook
|
||
|
||
**總計時間**:約 1-2 週(根據團隊經驗調整)
|
||
|
||
---
|
||
|
||
## 8. 成本分析
|
||
|
||
### 8.1 GitHub Actions(使用 Self-hosted Runner)
|
||
- **費用**:$0/月(完全免費)
|
||
- **說明**:所有 CI/CD 任務在 GCP VM 上執行,不消耗 GitHub 提供的分鐘數
|
||
|
||
### 8.2 GitHub Actions(使用 GitHub-hosted Runner)
|
||
- **免費額度**:2,000 分鐘/月(私有倉庫)
|
||
- **預估使用**:
|
||
- 每次 CI: 5 分鐘
|
||
- 每次 CD: 5 分鐘
|
||
- 每月約 100 次部署 = 1,000 分鐘
|
||
- **費用**:$0/月(在免費額度內)
|
||
|
||
### 8.3 GitLab CI(Self-hosted)
|
||
- **額外 VM 成本**:$20-50/月(需要額外的 Runner VM)
|
||
- **維護成本**:需要額外的系統維護時間
|
||
|
||
### 8.4 總結
|
||
**建議使用 GitHub Actions + Self-hosted Runner**,完全免費且功能完整。
|
||
|
||
---
|
||
|
||
## 9. 風險評估
|
||
|
||
| 風險 | 影響 | 機率 | 緩解措施 |
|
||
|-----|------|------|----------|
|
||
| 部署失敗導致服務中斷 | 高 | 中 | 實作自動回滾機制 + 健康檢查 |
|
||
| 測試覆蓋不足,未發現 Bug | 中 | 高 | 逐步提升測試覆蓋率至 >80% |
|
||
| GCP Service Account 金鑰洩漏 | 高 | 低 | 使用 GitHub Secrets + 定期輪換金鑰 |
|
||
| CI/CD Pipeline 執行時間過長 | 低 | 中 | 使用 Self-hosted Runner + 快取依賴 |
|
||
| 資料庫遷移失敗 | 高 | 低 | 部署前自動備份 + 測試環境驗證 |
|
||
|
||
---
|
||
|
||
## 10. 建議與結論
|
||
|
||
### 10.1 核心建議
|
||
1. **採用 GitHub Actions** 作為 CI/CD 平台
|
||
2. **使用 Self-hosted Runner** 節省成本(完全免費)
|
||
3. **分階段實作**,先建立 CI,再建立 CD
|
||
4. **優先建立測試框架**,確保程式碼品質
|
||
5. **實作自動回滾機制**,降低部署風險
|
||
|
||
### 10.2 立即可執行的行動
|
||
1. 將專案推送到 GitHub(私有倉庫)
|
||
2. 建立 `tests/` 目錄並撰寫基本測試
|
||
3. 建立 `.github/workflows/ci.yml`(先實作 CI)
|
||
4. 驗證 CI 正常運作後,再建立 `deploy.yml`(實作 CD)
|
||
|
||
### 10.3 長期目標
|
||
- 測試覆蓋率 >80%
|
||
- 平均部署時間 <5 分鐘
|
||
- 自動化部署成功率 >95%
|
||
- 零停機部署(Blue-Green)
|
||
|
||
---
|
||
|
||
## 附錄
|
||
|
||
### A. 相關文件
|
||
- [GitHub Actions 官方文件](https://docs.github.com/en/actions)
|
||
- [pytest 官方文件](https://docs.pytest.org/)
|
||
- [Gunicorn Graceful Reload](https://docs.gunicorn.org/en/stable/signals.html)
|
||
- [GCP Service Account 設定](https://cloud.google.com/iam/docs/service-accounts)
|
||
|
||
### B. 參考專案
|
||
- [Flask CI/CD 範例](https://github.com/actions/starter-workflows/blob/main/deployments/azure-webapps-python.yml)
|
||
- [Python 測試最佳實踐](https://realpython.com/pytest-python-testing/)
|
||
|
||
---
|
||
|
||
**文件版本**:1.0
|
||
**撰寫日期**:2026-01-14
|
||
**下次更新**:實作完成後更新實際成果和經驗
|