ci/woodpecker/push/main Pipeline was successful
单 project-20260921-deploy-dirtyguard-rootfix(任总 2026-09-21 10:28「根治」)。 问题:开发区 /root/cma-management → /srv/hermes/shared/cma-management 既是编辑区又是部署源, deploy.sh [0] 对任何 tracked modified 即 exit 1,多 agent 并行下反复自锁: - 2026-09-18 frontend/package.json(corepack 生成物) - 2026-09-21 10:09 batch5 在途 6 文件(放行卡住) - 2026-09-21 11:07 构建又写出 frontend/components.d.ts 改动: - deploy.sh:部署内容 = 已提交的 origin/main(独立部署检出 /srv/hermes/shared/cma-deploy: fetch -> checkout --detach -f -> clean -fdx);[0] 降级为告警(不再 exit); 新增 1.1 部署树自检(部署树必须无 tracked 修改)、1.2 运行时资产单源接线(.env/venv/node_modules)、 1d 后端可导入自检、运行树幂等切换(unit 改写前备份 + 一行回滚,cma-runtime-unit-switch 可抽取块); 保留 [1b] 鉴权面审计闸门(B 类缺口即中止)与 构建->铺站->重启->冒烟 全流程; 新增 drill 模式(离线演练:www 必须在 /var/www 之外、systemctl/nginx 必须是 PATH 桩、迁移只 --check)。 - deploy/cma-deploy-dirty-guard.sh:宿主前置闸门降级为告警(仅仓库不可用时失败关闭),不再写开发区。 - deploy/gitea-cma-deploy-hook.sh:[0] 段文案/语义同步(gate-trail 留痕链原样保留)。 - deploy/install-host-deploy-hook.sh:宿主组件安装/升级(备份 + md5 校验 + --check)。 演练证据(26/26 PASS):脏区旧版 [0] exit=1 / 新版整链 exit=0;开发区在途改动逐字节保留; 构造 B 类缺口时 [1b] 中止且未铺站;真机 drill 零生产影响。 未 push(发布须任总放行)。
47 lines
2.8 KiB
Bash
Executable File
47 lines
2.8 KiB
Bash
Executable File
#!/bin/bash
|
||
# ============================================================
|
||
# CMA 部署前「部署源」前置检查(宿主侧,由 gitea-cma-deploy-hook.sh 调用)
|
||
# ------------------------------------------------------------
|
||
# 版本: cma-deploy-source-decouple-20260921(单 project-20260921-deploy-dirtyguard-rootfix)
|
||
#
|
||
# 旧行为(cma-deploy-dirty-guard-20260918):开发工作区出现**任何** tracked modified 即 exit 1。
|
||
# 初衷是「防 deploy.sh 里的 `git pull` 覆盖未提交改动」。但开发区同时是部署源 ⇒ 多 agent 并行下
|
||
# 必然反复自锁(corepack 生成物、在途任务文件、unplugin-vue-components 生成物…),发布链被自己的
|
||
# 纪律闸门卡死(09-18 / 09-21 两次实测)。
|
||
#
|
||
# 新行为:部署内容 = **已提交的 origin/main 树**(deploy.sh 用独立检出 $CMA_DEPLOY_SRC 重建;
|
||
# 部署过程不再对开发区做 pull/stash/checkout)。开发区的脏净与部署内容无关 ⇒ 本闸门**降级为告警**:
|
||
# 打印开发区状态供留痕,不因 modified 中止部署。真正的硬闸门仍有三道,且都在 deploy.sh 里:
|
||
# [0] 部署源解析(fetch 失败即中止) [1c] 部署树 ≠ 已提交树即中止 [1b] 鉴权面审计 B 类缺口即中止。
|
||
# 本脚本只在「仓库不可用」这一种情况失败关闭(部署本身需要这个仓库)。
|
||
#
|
||
# 用法: cma-deploy-dirty-guard.sh [repo_dir] # 默认 /root/cma-management
|
||
# 退出码: 0 = 可继续部署(无论开发区脏净); 1 = 仓库不可用
|
||
# 依赖: git。本脚本**不写**开发区任何文件(旧版会把 corepack 生成物 checkout 回去,已移除)。
|
||
# ============================================================
|
||
set -uo pipefail
|
||
|
||
REPO="${1:-/root/cma-management}"
|
||
|
||
cd "$REPO" 2>/dev/null || { echo "❌ 仓库不可用: $REPO"; exit 1; }
|
||
if ! git rev-parse --git-dir > /dev/null 2>&1; then
|
||
echo "❌ 不是 git 仓库: $REPO"
|
||
exit 1
|
||
fi
|
||
|
||
BRANCH="$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo '?')"
|
||
HEAD_SHA="$(git rev-parse HEAD 2>/dev/null || echo '?')"
|
||
ORIGIN_SHA="$(git rev-parse origin/main 2>/dev/null || echo '?')"
|
||
DIRTY="$(git status --porcelain 2>/dev/null | grep -vE "__pycache__|^\?\?" | head -20)"
|
||
DIRTY_N="$(git status --porcelain 2>/dev/null | grep -vcE "__pycache__|^\?\?")"
|
||
|
||
echo " ℹ️ 开发区 $REPO: 分支=$BRANCH HEAD=${HEAD_SHA:0:8} origin/main=${ORIGIN_SHA:0:8}"
|
||
if [ "$DIRTY_N" -gt 0 ]; then
|
||
echo " ⚠️ 开发区有 $DIRTY_N 处未提交 tracked 改动 —— 不阻断部署(这些改动不会上线,也不会被丢弃):"
|
||
echo "$DIRTY" | sed 's/^/ /'
|
||
else
|
||
echo " ✓ 开发区无未提交 tracked 改动"
|
||
fi
|
||
echo " ℹ️ 部署内容 = 已提交的 origin/main 树(与开发区脏净解耦)"
|
||
exit 0
|