#!/usr/bin/env bash # 全量代码门禁:部署前在本地开发机执行,确保后端 + 前端检查全绿。 # # 用途: # - 部署门禁:scripts/deploy-prod.sh 在 build 镜像前自动调用本脚本(--skip-check 可跳过) # - 手动校验:开发时手动跑 ./scripts/check.sh # # 包含: # 数据库:SQL 约束与迁移完整性检查 # 后端:go vet + go build + go test # 前端:npm run check (prettier + eslint + typecheck) + npm run test + npm run build # # 任一步骤失败即退出非零,阻止部署。 set -euo pipefail ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" BACKEND_DIR="${ROOT_DIR}/backend" FRONTEND_DIR="${ROOT_DIR}/frontend" RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[1;34m' NC='\033[0m' log() { printf "${BLUE}[check]${NC} %s\n" "$*"; } log_ok() { printf "${GREEN}[check]${NC} %s\n" "$*"; } log_warn() { printf "${YELLOW}[check]${NC} %s\n" "$*"; } log_error() { printf "${RED}[check]${NC} %s\n" "$*" >&2; } SKIP_BACKEND=0 SKIP_FRONTEND=0 SKIP_TESTS=0 show_help() { cat << EOF 用法: ./scripts/check.sh [选项] 全量代码门禁:后端 go vet/build/test + 前端 check/test/build。 选项: --skip-backend 跳过后端检查 --skip-frontend 跳过前端检查 --skip-tests 跳过测试(仅做 vet/build + lint/typecheck/build) -h, --help 显示帮助 示例: ./scripts/check.sh ./scripts/check.sh --skip-frontend EOF } while [[ $# -gt 0 ]]; do case "$1" in --skip-backend) SKIP_BACKEND=1; shift ;; --skip-frontend) SKIP_FRONTEND=1; shift ;; --skip-tests) SKIP_TESTS=1; shift ;; -h|--help) show_help; exit 0 ;; *) log_error "未知参数: $1" show_help exit 1 ;; esac done step_start() { printf "\n${BLUE}[check]${NC} \033[1m▶ %s${NC}\n" "$1"; } step_ok() { log_ok "✓ $1 ($2)"; } step_fail() { log_error "✗ $1 失败"; } run_step() { # run_step "步骤名" 命令... local name="$1"; shift local start start=$(date +%s) step_start "$name" if "$@"; then local elapsed=$(( $(date +%s) - start )) step_ok "$name" "${elapsed}s" else step_fail "$name" return 1 fi } FAILED=0 # --------------------------------------------------------------------------- # 后端检查 # --------------------------------------------------------------------------- if [[ "${SKIP_BACKEND}" == "0" ]]; then log "后端检查目录: ${BACKEND_DIR}" cd "${BACKEND_DIR}" run_step "SQL 约束检查" bash "${ROOT_DIR}/scripts/check-sql-guard.sh" || FAILED=1 run_step "go vet ./..." go vet ./... || FAILED=1 run_step "go build ./..." go build ./... || FAILED=1 if [[ "${SKIP_TESTS}" == "0" ]]; then # -p 1 串行避免 SQLite 内存库并发; 真实 MySQL e2e 默认 skip run_step "go test ./..." go test -p 1 -count=1 ./... || FAILED=1 else log_warn "跳过后端测试 (--skip-tests)" fi else log_warn "跳过后端检查 (--skip-backend)" fi # --------------------------------------------------------------------------- # 前端检查 # --------------------------------------------------------------------------- if [[ "${SKIP_FRONTEND}" == "0" ]]; then log "前端检查目录: ${FRONTEND_DIR}" cd "${FRONTEND_DIR}" if [[ ! -d node_modules ]]; then run_step "npm ci (首次安装依赖)" npm ci || FAILED=1 fi # npm run check = prettier --check + eslint --max-warnings=0 + vue-tsc run_step "npm run check (prettier + eslint + typecheck)" npm run check || FAILED=1 if [[ "${SKIP_TESTS}" == "0" ]]; then run_step "npm run test (vitest)" npm run test || FAILED=1 else log_warn "跳过前端测试 (--skip-tests)" fi run_step "npm run build (vite 生产构建)" npm run build || FAILED=1 else log_warn "跳过前端检查 (--skip-frontend)" fi # --------------------------------------------------------------------------- # 汇总 # --------------------------------------------------------------------------- printf "\n" if [[ "${FAILED}" == "0" ]]; then log_ok "全部检查通过 ✓" exit 0 else log_error "检查未通过,已阻止本次部署。可用 --skip-check 强制跳过(不推荐)。" exit 1 fi