Files
ewoooc/scripts/verify-cicd.sh
ogt 1b4f3a7bbe
Some checks failed
CD Pipeline / deploy (push) Failing after 59s
feat: EwoooC 初始化 — 完整專案推版至 Gitea
- 建立 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>
2026-04-19 01:21:13 +08:00

350 lines
13 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# =============================================================================
# MOMO Pro System - CI/CD 完整驗證腳本
# 用途: 驗證完整的 CI/CD 流程和一鍵部署自動化
# =============================================================================
set -e
# 顏色定義
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
NC='\033[0m'
BOLD='\033[1m'
# 配置
K3S_HOST="${K3S_HOST:-192.168.0.110}"
K3S_USER="${K3S_USER:-wooo}"
PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
# 統計
TOTAL_TESTS=0
PASSED_TESTS=0
FAILED_TESTS=0
log_section() {
echo ""
echo -e "${CYAN}═══════════════════════════════════════════════════════════════${NC}"
echo -e "${CYAN} $1${NC}"
echo -e "${CYAN}═══════════════════════════════════════════════════════════════${NC}"
}
log_test() {
echo -e "${BLUE}[TEST]${NC} $1"
TOTAL_TESTS=$((TOTAL_TESTS + 1))
}
log_pass() {
echo -e "${GREEN} ✅ PASS${NC}: $1"
PASSED_TESTS=$((PASSED_TESTS + 1))
}
log_fail() {
echo -e "${RED} ❌ FAIL${NC}: $1"
FAILED_TESTS=$((FAILED_TESTS + 1))
}
log_skip() {
echo -e "${YELLOW} ⏭️ SKIP${NC}: $1"
}
# =============================================================================
# 1. 本地環境檢查
# =============================================================================
verify_local_environment() {
log_section "1. 本地環境檢查"
# Docker
log_test "Docker 是否安裝"
if command -v docker &> /dev/null; then
log_pass "Docker 已安裝 ($(docker --version | head -1))"
else
log_fail "Docker 未安裝"
fi
# Git
log_test "Git 是否安裝"
if command -v git &> /dev/null; then
log_pass "Git 已安裝 ($(git --version))"
else
log_fail "Git 未安裝"
fi
# SSH
log_test "SSH 是否可用"
if command -v ssh &> /dev/null; then
log_pass "SSH 可用"
else
log_fail "SSH 不可用"
fi
# 專案目錄
log_test "專案目錄結構"
local required_files=("app.py" "Dockerfile" "requirements.txt" "config.py")
local missing_files=()
for file in "${required_files[@]}"; do
if [[ ! -f "$PROJECT_ROOT/$file" ]]; then
missing_files+=("$file")
fi
done
if [[ ${#missing_files[@]} -eq 0 ]]; then
log_pass "所有必要檔案存在"
else
log_fail "缺少檔案: ${missing_files[*]}"
fi
}
# =============================================================================
# 2. SSH 連線測試
# =============================================================================
verify_ssh_connection() {
log_section "2. SSH 連線測試"
log_test "SSH 連線到 K3s 主機 (${K3S_HOST})"
if ssh -o ConnectTimeout=10 -o BatchMode=yes "${K3S_USER}@${K3S_HOST}" "echo 'SSH OK'" &>/dev/null; then
log_pass "SSH 連線成功"
else
log_fail "SSH 連線失敗"
return 1
fi
log_test "K3s 主機 Docker 狀態"
if ssh "${K3S_USER}@${K3S_HOST}" "docker info" &>/dev/null; then
log_pass "Docker 運行正常"
else
log_fail "Docker 未運行或無法訪問"
fi
log_test "K3s 叢集狀態"
if ssh "${K3S_USER}@${K3S_HOST}" "sudo kubectl get nodes" &>/dev/null; then
log_pass "K3s 叢集正常"
else
log_fail "K3s 叢集無法訪問"
fi
}
# =============================================================================
# 3. K8s 服務狀態
# =============================================================================
verify_k8s_services() {
log_section "3. K8s 服務狀態"
log_test "momo namespace 存在"
if ssh "${K3S_USER}@${K3S_HOST}" "sudo kubectl get namespace momo" &>/dev/null; then
log_pass "momo namespace 存在"
else
log_fail "momo namespace 不存在"
return 1
fi
log_test "momo-app Pod 狀態"
local app_status=$(ssh "${K3S_USER}@${K3S_HOST}" "sudo kubectl get pod -n momo -l app=momo-app -o jsonpath='{.items[0].status.phase}'" 2>/dev/null)
if [[ "$app_status" == "Running" ]]; then
log_pass "momo-app 運行中"
else
log_fail "momo-app 狀態異常: $app_status"
fi
log_test "momo-postgres Pod 狀態"
local pg_status=$(ssh "${K3S_USER}@${K3S_HOST}" "sudo kubectl get pod -n momo momo-postgres-0 -o jsonpath='{.status.phase}'" 2>/dev/null)
if [[ "$pg_status" == "Running" ]]; then
log_pass "momo-postgres 運行中"
else
log_fail "momo-postgres 狀態異常: $pg_status"
fi
log_test "momo-scheduler Pod 狀態"
local sched_status=$(ssh "${K3S_USER}@${K3S_HOST}" "sudo kubectl get pod -n momo -l app=momo-scheduler -o jsonpath='{.items[0].status.phase}'" 2>/dev/null)
if [[ "$sched_status" == "Running" ]]; then
log_pass "momo-scheduler 運行中"
else
log_fail "momo-scheduler 狀態異常: $sched_status"
fi
}
# =============================================================================
# 4. 應用健康檢查
# =============================================================================
verify_app_health() {
log_section "4. 應用健康檢查"
log_test "HTTPS 端點可訪問 (mo.wooo.work)"
local health_response=$(curl -s -m 10 https://mo.wooo.work/health 2>/dev/null)
if echo "$health_response" | grep -q "healthy"; then
log_pass "應用健康 ($health_response)"
else
log_fail "應用健康檢查失敗"
fi
log_test "資料庫連線"
local db_test=$(ssh "${K3S_USER}@${K3S_HOST}" "sudo kubectl exec -n momo momo-postgres-0 -- psql -U momo -d momo_analytics -c 'SELECT 1'" 2>/dev/null)
if echo "$db_test" | grep -q "1"; then
log_pass "資料庫連線正常"
else
log_fail "資料庫連線失敗"
fi
}
# =============================================================================
# 5. CI/CD 檔案驗證
# =============================================================================
verify_cicd_files() {
log_section "5. CI/CD 檔案驗證"
log_test ".gitlab-ci-simple.yml 存在"
if [[ -f "$PROJECT_ROOT/.gitlab-ci-simple.yml" ]]; then
log_pass "簡化版 CI 配置存在"
else
log_fail "簡化版 CI 配置不存在"
fi
log_test "build-and-deploy.sh 存在且可執行"
if [[ -x "$PROJECT_ROOT/scripts/deploy/build-and-deploy.sh" ]]; then
log_pass "部署腳本存在且可執行"
else
log_fail "部署腳本不存在或不可執行"
fi
log_test "deploy/deploy.sh 存在且可執行"
if [[ -x "$PROJECT_ROOT/deploy/deploy.sh" ]]; then
log_pass "一鍵部署腳本存在且可執行"
else
log_fail "一鍵部署腳本不存在或不可執行"
fi
log_test "K8s 配置檔案完整"
local k8s_files=("00-namespace.yaml" "01-secrets.yaml" "02-configmap.yaml" "03-postgres.yaml" "04-momo-app.yaml" "05-scheduler.yaml")
local missing_k8s=()
for file in "${k8s_files[@]}"; do
if [[ ! -f "$PROJECT_ROOT/k8s/$file" ]]; then
missing_k8s+=("$file")
fi
done
if [[ ${#missing_k8s[@]} -eq 0 ]]; then
log_pass "所有 K8s 配置存在"
else
log_fail "缺少 K8s 配置: ${missing_k8s[*]}"
fi
}
# =============================================================================
# 6. 自動啟動驗證
# =============================================================================
verify_auto_start() {
log_section "6. 系統自動啟動驗證"
log_test "momo-startup-complete.service 已啟用"
local service_status=$(ssh "${K3S_USER}@${K3S_HOST}" "systemctl is-enabled momo-startup-complete.service 2>/dev/null" || echo "not-found")
if [[ "$service_status" == "enabled" ]]; then
log_pass "自動啟動服務已啟用"
else
log_fail "自動啟動服務未啟用 ($service_status)"
fi
log_test "啟動腳本存在"
local script_exists=$(ssh "${K3S_USER}@${K3S_HOST}" "test -f /home/wooo/momo_pro_system/scripts/tools/system_startup_complete.sh && echo 'yes'" 2>/dev/null)
if [[ "$script_exists" == "yes" ]]; then
log_pass "啟動腳本存在"
else
log_fail "啟動腳本不存在"
fi
}
# =============================================================================
# 7. 端對端部署測試(可選)
# =============================================================================
verify_e2e_deploy() {
log_section "7. 端對端部署測試(模擬)"
log_test "本地 Docker 建置"
echo " 執行: docker build -t momo-pro-system:test ."
if docker build -t momo-pro-system:test "$PROJECT_ROOT" -q &>/dev/null; then
log_pass "本地 Docker 建置成功"
docker rmi momo-pro-system:test &>/dev/null || true
else
log_fail "本地 Docker 建置失敗"
fi
log_test "rsync 同步測試dry-run"
if rsync -avzn --delete --exclude='.git' --exclude='venv' --exclude='__pycache__' "$PROJECT_ROOT/" "${K3S_USER}@${K3S_HOST}:/tmp/rsync-test/" &>/dev/null; then
log_pass "rsync 同步可行"
else
log_fail "rsync 同步失敗"
fi
}
# =============================================================================
# 8. 監控系統驗證
# =============================================================================
verify_monitoring() {
log_section "8. 監控系統驗證"
log_test "Prometheus 運行中"
local prom_pods=$(ssh "${K3S_USER}@${K3S_HOST}" "sudo kubectl get pods -n monitoring -l app.kubernetes.io/name=prometheus -o jsonpath='{.items[*].status.phase}'" 2>/dev/null)
if echo "$prom_pods" | grep -q "Running"; then
log_pass "Prometheus 運行中"
else
log_skip "Prometheus 未部署或未運行"
fi
log_test "Alertmanager 運行中"
local am_pods=$(ssh "${K3S_USER}@${K3S_HOST}" "sudo kubectl get pods -n monitoring -l app.kubernetes.io/name=alertmanager -o jsonpath='{.items[*].status.phase}'" 2>/dev/null)
if echo "$am_pods" | grep -q "Running"; then
log_pass "Alertmanager 運行中"
else
log_skip "Alertmanager 未部署或未運行"
fi
}
# =============================================================================
# 輸出總結
# =============================================================================
print_summary() {
log_section "驗證結果總結"
echo ""
echo -e " ${BOLD}總測試數:${NC} $TOTAL_TESTS"
echo -e " ${GREEN}通過:${NC} $PASSED_TESTS"
echo -e " ${RED}失敗:${NC} $FAILED_TESTS"
echo ""
if [[ $FAILED_TESTS -eq 0 ]]; then
echo -e "${GREEN}═══════════════════════════════════════════════════════════════${NC}"
echo -e "${GREEN} ✅ 所有驗證通過CI/CD 流程準備就緒${NC}"
echo -e "${GREEN}═══════════════════════════════════════════════════════════════${NC}"
return 0
else
echo -e "${RED}═══════════════════════════════════════════════════════════════${NC}"
echo -e "${RED} ❌ 有 $FAILED_TESTS 項驗證失敗,請檢查並修復${NC}"
echo -e "${RED}═══════════════════════════════════════════════════════════════${NC}"
return 1
fi
}
# =============================================================================
# 主程式
# =============================================================================
main() {
echo ""
echo -e "${CYAN}╔═══════════════════════════════════════════════════════════════════════════╗${NC}"
echo -e "${CYAN}${NC} ${BOLD}MOMO Pro System - CI/CD 完整驗證${NC} ${CYAN}${NC}"
echo -e "${CYAN}${NC} ${BOLD}$(date '+%Y-%m-%d %H:%M:%S')${NC} ${CYAN}${NC}"
echo -e "${CYAN}╚═══════════════════════════════════════════════════════════════════════════╝${NC}"
verify_local_environment
verify_ssh_connection
verify_k8s_services
verify_app_health
verify_cicd_files
verify_auto_start
verify_e2e_deploy
verify_monitoring
print_summary
}
main "$@"