feat(frontend): 引入 vitest 测试框架,为 store.js 添加 smoke test
- 新增 package.json + vitest.config.js,16 个测试覆盖核心状态初始化、 表单工厂、payload 构建、费用归一化、OAuth 候选持久化 - deploy/update.sh 新增 check_js_tests() 闸门,位于 JS 语法闸门之后、 pytest 闸门之前;缺 node/node_modules 时优雅跳过 - update.sh 依赖安装阶段新增 npm install,确保 vitest 可用 - .gitignore 忽略 node_modules/ 与 package-lock.json
This commit is contained in:
@@ -239,6 +239,35 @@ check_js_syntax() {
|
||||
return "$failed"
|
||||
}
|
||||
|
||||
# ---- 前端 JS 单元测试闸门:syntax 通过后验证核心状态逻辑 ----
|
||||
check_js_tests() {
|
||||
local node_bin="" nvm_node
|
||||
nvm_node="$(ls -d "${HOME:-/root}"/.nvm/versions/node/*/bin/node 2>/dev/null | sort -V | tail -1 || true)"
|
||||
for _cand in ".venv/bin/node" "node" "$nvm_node"; do
|
||||
[ -n "$_cand" ] || continue
|
||||
if command -v "$_cand" >/dev/null 2>&1; then node_bin="$_cand"; break; fi
|
||||
done
|
||||
if [ -z "$node_bin" ]; then
|
||||
echo "[$(date '+%F %T')] ⚠️ 未找到 node,跳过 JS 测试闸门"
|
||||
return 0
|
||||
fi
|
||||
if [ ! -d "node_modules" ]; then
|
||||
echo "[$(date '+%F %T')] ⚠️ node_modules 不存在,跳过 JS 测试闸门(需先 npm install)"
|
||||
return 0
|
||||
fi
|
||||
echo "[$(date '+%F %T')] JS 测试闸门:使用 $node_bin(npx vitest run)"
|
||||
# 用 node 的完整路径运行 npx,确保找到 node_modules/.bin/vitest
|
||||
local npx_bin
|
||||
npx_bin="$(dirname "$node_bin")/npx"
|
||||
[ -x "$npx_bin" ] || npx_bin="npx"
|
||||
if ! "$npx_bin" vitest run 2>&1; then
|
||||
echo "[$(date '+%F %T')] ❌ JS 测试失败"
|
||||
return 1
|
||||
fi
|
||||
echo "[$(date '+%F %T')] ✓ JS 测试通过"
|
||||
return 0
|
||||
}
|
||||
|
||||
# 同步 systemd 单元文件:deploy/ 下的 .service/.timer 与 /etc/systemd/system
|
||||
# 不一致时拷贝并 reload;timer 变更额外 enable --now(新调度周期立即生效且开机自启),
|
||||
# 主服务 unit 变更额外 restart(否则光 daemon-reload 日志说已更新、实际没生效)。
|
||||
@@ -309,6 +338,20 @@ if [ -x ".venv/bin/pip" ]; then
|
||||
echo "[$(date '+%F %T')] 警告:依赖安装失败,服务可能因 ImportError 起不来;请手动执行 .venv/bin/pip install -r requirements.txt 看完整报错"
|
||||
fi
|
||||
fi
|
||||
# 前端 JS 测试依赖(vitest):package.json 存在时自动 npm install,无变化时 npm 快速跳过
|
||||
if [ -f "package.json" ]; then
|
||||
local_npm=""
|
||||
for _cand in ".venv/bin/npm" "npm"; do
|
||||
if command -v "$_cand" >/dev/null 2>&1; then local_npm="$_cand"; break; fi
|
||||
done
|
||||
if [ -n "$local_npm" ]; then
|
||||
if ! "$local_npm" install --prefer-offline -q 2>&1; then
|
||||
echo "[$(date '+%F %T')] 警告:npm install 失败,JS 测试闸门将被跳过"
|
||||
fi
|
||||
else
|
||||
echo "[$(date '+%F %T')] ⚠️ 未找到 npm,跳过前端依赖安装"
|
||||
fi
|
||||
fi
|
||||
|
||||
# ---- 前端 JS 语法闸门 ----
|
||||
if ! check_js_syntax; then
|
||||
@@ -327,6 +370,23 @@ if ! check_js_syntax; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ---- 前端 JS 测试闸门 ----
|
||||
if ! check_js_tests; then
|
||||
FAIL_REASON="前端 JS 测试失败(vitest run 未通过,已中止上线)"
|
||||
echo "[$(date '+%F %T')] ❌ ${FAIL_REASON},回滚至 ${LOCAL:0:8}"
|
||||
git reset --hard -q "$LOCAL"
|
||||
systemctl restart "$SERVICE_NAME" || true
|
||||
mark_failed "$REMOTE" "$FAIL_REASON"
|
||||
send_alert "🚨 vps-manager 部署失败:JS 测试闸门拦截
|
||||
坏版本: ${REMOTE:0:8}
|
||||
回滚至: ${LOCAL:0:8}
|
||||
失败原因: ${FAIL_REASON}
|
||||
时间: $(date '+%F %T')
|
||||
主机: cc1:${APP_DIR}
|
||||
排查: npx vitest run"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ---- 测试闸门:restart 前用 pytest 拦截坏版本 ----
|
||||
# 旧版本服务仍在运行(尚未 restart),测试失败时只需回退磁盘代码、不 restart,
|
||||
# 避免坏版本上线。使用规则要求的 .venv/bin/python 解释器。
|
||||
|
||||
Reference in New Issue
Block a user