加部署前代码门禁: scripts/check.sh + deploy-prod.sh 接入
单人维护 + Gitea 无 runner, CI 文件无执行环境。改用部署时刻门禁: deploy-prod.sh 构建镜像前在本地调 check.sh 跑全量检查, 失败即中止部署。 scripts/check.sh (新增): - 后端: go vet + go build + go test (串行 -p 1 避免 SQLite 并发) - 前端: npm run check (prettier + eslint --max-warnings=0 + vue-tsc) + npm run build - 支持 --skip-backend/--skip-frontend/--skip-tests 局部调试 - 每步报耗时, 任一失败退出非零 deploy-prod.sh 接入: - 构建镜像前 (NO_BUILD=0) 自动调 check.sh, 失败中止部署 - 本地缺 go/npm 时跳过并告警 (部署机可能只有 docker), 不硬失败 - --skip-check 显式跳过 (不推荐) README 补 "代码门禁" 章节。 验证: 全量 check.sh 跑通 (~46s, 5 步全绿); 临时注入 lint 错误确认能拦住。
This commit is contained in:
Executable
+134
@@ -0,0 +1,134 @@
|
||||
#!/usr/bin/env bash
|
||||
# 全量代码门禁:部署前在本地开发机执行,确保后端 + 前端检查全绿。
|
||||
#
|
||||
# 用途:
|
||||
# - 部署门禁:scripts/deploy-prod.sh 在 build 镜像前自动调用本脚本(--skip-check 可跳过)
|
||||
# - 手动校验:开发时手动跑 ./scripts/check.sh
|
||||
#
|
||||
# 包含:
|
||||
# 后端:go vet + go build + go test
|
||||
# 前端:npm run check (prettier + eslint + typecheck) + 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/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 "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
|
||||
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
|
||||
Reference in New Issue
Block a user