文件
hyb-oa/scripts/qa/run-release-gate.sh
T
wangsli f223bfb72f
ci-e2e / e2e (push) Canceled after 0s
ci-minimal / check-minimal (push) Canceled after 0s
fix: 隔离既有发布的数据库容器生命周期(09-05-existing-deploy-db-lifecycle-isolation)
2026-09-05 21:02:58 +08:00

175 行
5.5 KiB
Bash
可执行文件
原始文件 Blame 文件历史

此文件含有模棱两可的 Unicode 字符
此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。
#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
ARTIFACT_ROOT="${RELEASE_GATE_ARTIFACT_DIR:-${ROOT_DIR}/artifacts/release-gate/$(date +%Y%m%d-%H%M%S)}"
MODE="${1:-all}"
CURRENT_STAGE=""
mkdir -p "$ARTIFACT_ROOT"
usage() {
cat <<USAGE
Usage: bash scripts/qa/run-release-gate.sh <all|static|smoke-local|full-local|project-wide|deploy|ci-release|r66-trialrun|help>
说明:
static 运行部署契约、server Prisma 校验、client typecheck/build
smoke-local 运行本地网页 smoke 门禁
full-local 运行本地全量门禁(server regression + client full E2E)
project-wide 项目级门禁:static + 覆盖扫描 + UI/移动契约 + 迁移漂移诊断 + 业务流 + 全页面视觉 + live readiness
deploy 调用 deploy/trialrun/deploy.sh,内部会串联 /ready、external deps、runtime smoke 与 live smoke
all 依次执行 static -> smoke-local -> full-local -> deploy
ci-release 依次执行 static -> full-local -> deploy
r66-trialrun R66 小团队试点门禁:static -> server regression-all -> smoke-local
可选环境变量:
RELEASE_GATE_ARTIFACT_DIR 失败产物输出目录
QA_* 透传给 scripts/qa/run-web-gates.sh
LIVE_SMOKE_* 透传给 deploy.sh 与 live smoke
PROJECT_WIDE_SKIP_BUSINESS_FLOW=1 跳过业务流 E2E
PROJECT_WIDE_SKIP_VISUAL=1 跳过项目级视觉 E2E
DEPLOY_SERVER / REMOTE_DIR / REMOTE_ENV_FILE / SYNC_ENV
COMPOSE_PROJECT_NAME / POSTGRES_DATA_DIR / STORAGE_HOST_DIR / DEPLOY_DATA_MODE
USAGE
}
collect_failure_artifacts() {
local stage_name="${CURRENT_STAGE:-unknown}"
local target_dir="${ARTIFACT_ROOT}/${stage_name}"
mkdir -p "$target_dir"
bash "$ROOT_DIR/scripts/qa/collect-failure-artifacts.sh" "$target_dir" >/dev/null 2>&1 || true
echo "[release-gate] 已收集失败产物:$target_dir" >&2
}
handle_error() {
local exit_code="$?"
echo "[release-gate][FAIL] 阶段 ${CURRENT_STAGE:-unknown} 失败(exit=${exit_code})" >&2
collect_failure_artifacts
exit "$exit_code"
}
trap handle_error ERR
run_stage() {
local stage_name="$1"
shift
CURRENT_STAGE="$stage_name"
echo ">>> [release-gate] ${stage_name}"
"$@"
}
stage_static() {
node "$ROOT_DIR/deploy/trialrun/validate-env-contract.js"
(
cd "$ROOT_DIR/server"
npm test -- tests/unit/scripts/deployment-db-lifecycle.test.js
npm run prisma:validate
)
(
cd "$ROOT_DIR/client"
npm run typecheck
npm run build
)
}
stage_smoke_local() {
bash "$ROOT_DIR/scripts/qa/run-web-gates.sh" smoke-local
}
stage_full_local() {
bash "$ROOT_DIR/scripts/qa/run-web-gates.sh" full-local
}
stage_server_regression_all() {
(
cd "$ROOT_DIR/server"
./scripts/regression-all.sh
)
}
stage_project_wide_static() {
local issue_csv="$ROOT_DIR/issues/2026-05-08_23-38-37-project-wide-qa-second-pass.csv"
python3 /home/shunli/.codex/skills/plan/scripts/validate_issues_csv.py "$issue_csv"
node "$ROOT_DIR/scripts/qa/check-ui-design-rules.mjs" --strict
node "$ROOT_DIR/scripts/qa/check-error-reason-contract.mjs" --strict
node "$ROOT_DIR/scripts/qa/check-error-reason-contract.mjs" --self-test
node "$ROOT_DIR/scripts/qa/check-mobile-route-contract.mjs"
node "$ROOT_DIR/scripts/qa/check-flow-coverage.mjs" --json > "$ARTIFACT_ROOT/flow-coverage.json"
node "$ROOT_DIR/scripts/qa/check-flow-coverage.mjs" --markdown "$ARTIFACT_ROOT/flow-coverage.md"
node "$ROOT_DIR/scripts/qa/check-live-smoke-env.mjs" --json > "$ARTIFACT_ROOT/live-smoke-env.json"
bash "$ROOT_DIR/scripts/qa/check-local-migration-drift.sh"
}
stage_project_wide_business_flow() {
if [[ "${PROJECT_WIDE_SKIP_BUSINESS_FLOW:-0}" == "1" ]]; then
echo "[release-gate] 跳过业务流 E2E(PROJECT_WIDE_SKIP_BUSINESS_FLOW=1)"
return 0
fi
bash "$ROOT_DIR/scripts/qa/run-business-flow-gates.sh" local
}
stage_project_wide_visual() {
if [[ "${PROJECT_WIDE_SKIP_VISUAL:-0}" == "1" ]]; then
echo "[release-gate] 跳过项目级视觉 E2E(PROJECT_WIDE_SKIP_VISUAL=1)"
return 0
fi
bash "$ROOT_DIR/scripts/qa/run-web-gates.sh" project-wide-visual-local
}
stage_project_wide_live_readiness() {
LIVE_SMOKE_BASE_URL="${LIVE_SMOKE_BASE_URL:-https://oa.hyinda.com}" bash "$ROOT_DIR/scripts/qa/run-live-smoke-readiness.sh"
}
stage_deploy() {
bash "$ROOT_DIR/deploy/trialrun/deploy.sh"
}
case "$MODE" in
help|-h|--help)
usage
;;
static)
run_stage static stage_static
;;
smoke-local)
run_stage smoke-local stage_smoke_local
;;
full-local)
run_stage full-local stage_full_local
;;
project-wide)
run_stage static stage_static
run_stage project-wide-static stage_project_wide_static
run_stage project-wide-business-flow stage_project_wide_business_flow
run_stage project-wide-visual stage_project_wide_visual
run_stage project-wide-live-readiness stage_project_wide_live_readiness
;;
deploy)
run_stage deploy stage_deploy
;;
ci-release)
run_stage static stage_static
run_stage full-local stage_full_local
run_stage deploy stage_deploy
;;
r66-trialrun)
run_stage static stage_static
run_stage server-regression-all stage_server_regression_all
run_stage smoke-local stage_smoke_local
;;
all)
run_stage static stage_static
run_stage smoke-local stage_smoke_local
run_stage full-local stage_full_local
run_stage deploy stage_deploy
;;
*)
usage >&2
exit 1
;;
esac
echo "[release-gate][PASS] 模式 ${MODE} 通过"
echo "[release-gate] 产物目录:${ARTIFACT_ROOT}"