diff --git a/deploy/update.sh b/deploy/update.sh index efabc9c..339a9ca 100755 --- a/deploy/update.sh +++ b/deploy/update.sh @@ -163,9 +163,13 @@ PYEOF # 排除第三方 vendored 文件(vue.global.prod.js / tailwind.js / chart.umd.js)。 # 保持零构建现状(raw JS + ?v=mtime 缓存失效),仅做最小语法校验。 check_js_syntax() { - local node_bin="" failed=0 f - # node 探测:优先 venv 内(如有),回退系统 PATH - for _cand in ".venv/bin/node" "node"; do + local node_bin="" failed=0 f nvm_node + # node 探测:venv 内 → 系统 PATH → nvm 安装目录。 + # systemd unit 的 PATH 不含 nvm,cc1 上 node 仅存在于 ~/.nvm/versions/node/*/bin, + # 缺这层回退会让 JS 闸门每轮都被静默跳过,闸门形同虚设。 + 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 @@ -287,7 +291,14 @@ fi # ---- 测试闸门:restart 前用 pytest 拦截坏版本 ---- # 旧版本服务仍在运行(尚未 restart),测试失败时只需回退磁盘代码、不 restart, # 避免坏版本上线。使用规则要求的 .venv/bin/python 解释器。 -if [ -x ".venv/bin/python" ]; then +if [ ! -x ".venv/bin/python" ]; then + echo "[$(date '+%F %T')] ⚠️ 未找到 .venv/bin/python,跳过测试闸门" +elif ! .venv/bin/python -c 'import pytest' >/dev/null 2>&1; then + # pytest 属 requirements-dev.txt(注明生产部署不装)。模块缺失是环境问题,不是版本有问题: + # 若按「测试失败」处理,会拦截完全正常的提交,并写 FAILED_STATE 把更新链路永久冻结 + # (cc1 曾因此卡在旧版本数小时,直到人工介入)。降级为跳过,与 JS 闸门缺 node 的处理一致。 + echo "[$(date '+%F %T')] ⚠️ .venv 未安装 pytest(见 requirements-dev.txt),跳过测试闸门" +else echo "[$(date '+%F %T')] 运行测试闸门(pytest -x -q)…" if ! .venv/bin/python -m pytest tests/ -x -q 2>&1; then FAIL_REASON="测试闸门失败(pytest -x -q 未通过),已阻止 restart" @@ -308,8 +319,6 @@ if [ -x ".venv/bin/python" ]; then exit 1 fi echo "[$(date '+%F %T')] ✅ 测试闸门通过" -else - echo "[$(date '+%F %T')] ⚠️ 未找到 .venv/bin/python,跳过测试闸门" fi # 重启服务加载新代码