From efe0cf119b9df64b739cff72526bace67afc0e3e Mon Sep 17 00:00:00 2001 From: JianFeeeee Date: Sat, 24 Oct 2026 11:59:00 +0800 Subject: [PATCH] =?UTF-8?q?fix(ci):=20=E6=8E=92=E9=99=A4=E8=A1=A8=E6=96=AD?= =?UTF-8?q?=E8=A8=80=E4=BB=8E=E3=80=8C=E6=9F=A5=E6=8F=90=E7=A4=BA=E6=96=87?= =?UTF-8?q?=E6=A1=88=E3=80=8D=E6=94=B9=E4=B8=BA=E3=80=8C=E6=9F=A5=E5=8F=AF?= =?UTF-8?q?=E6=89=A7=E8=A1=8C=E5=88=A4=E7=A9=BA=E9=80=BB=E8=BE=91=E3=80=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 缺陷(真实存在,已实测复现) check-ci-gates.py 里「排除表每项必须写原因」这条断言原本写成: check(any("没有写原因" in r for _n, r in race), ...) 它只检查**提示文案还在**,完全不看校验逻辑本身。 实测取证:把 ci.yml 第 245 行的 if [ -z "${reason// /}" ]; then 改成 if false; then (提示文案一字未动、校验实际彻底失效): · 该步骤实跑 EXIT=0 ——「无原因必须失败」这条保证彻底破掉 · 而 check-ci-gates.py 仍然通过(GATES_EXIT=0) 也就是说:判据被文案顶包了。这正是本脚本 docstring 里批判的 「run: | 里的 # 是字符串不是注释 ⇒ 注释能骗过断言」,自己又犯了一次。 ## 修法 断言改为在**剥掉 shell 注释后的可执行行**上,同时要求: · `${reason// /}`(判空变量)存在 · `exit 1` 存在 只有文案、没有真逻辑 ⇒ 不通过。 ## 验证(先证能红,再证不误伤) 注入 if false 变异(保留文案)→ 修复前 EXIT=0(漏),修复后 **EXIT=1**(咬住) 还原 → EXIT=0 回归另两个变异(去掉 cmd/gui 剔除、去掉 -count=1)→ 均仍 EXIT=1,未被这次修改削弱 ## 门禁 go build ./... = 0|go vet ./... = 0|go test ./internal/kernelboot/modules/ = ok check-ci-gates.py = 0|gofmt 本线文件干净 边界:只改这一个脚本文件,未动 ci.yml、未动业务逻辑;未 push、未开 PR。 --- .github/scripts/check-ci-gates.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/.github/scripts/check-ci-gates.py b/.github/scripts/check-ci-gates.py index 009b9dd5..602433f7 100755 --- a/.github/scripts/check-ci-gates.py +++ b/.github/scripts/check-ci-gates.py @@ -97,8 +97,17 @@ for _n, r in evid: "取证步骤应显式检查 DATA RACE 报告数(否则取证没意义)") # ── 3. skip 排除表:每项必须写原因,无原因必须步骤自己失败 ── -check(any("没有写原因" in r for _n, r in race), - "race job 缺少 -skip 排除表的结构校验(无原因的排除必须让步骤失败)") +# +# ★ 这里曾经写成 `any("没有写原因" in r ...)` —— 只检查**提示文案还在**。 +# 实测:把 `if [ -z "${reason// /}" ]; then` 改成 `if false; then` +# (文案全保留、校验实际失效),该断言仍然绿,而该步骤实跑 EXIT=0 +# —— 也就是说「无原因必须失败」这条保证彻底破掉,判据却看不见。 +# 这正是本脚本自己在 docstring 里批判的「被文案顶包」,不能自己再犯。 +# ⇒ 改为剥注释后断言**可执行的判空逻辑**:必须同时出现判空变量与 exit 1。 +race_code = "\n".join(code_lines(r) for _n, r in race) +check('${reason// /}' in race_code and "exit 1" in race_code, + "race job 排除表缺少真校验:剥注释后必须能看到 ${reason// /} 判空 + exit 1," + "只有提示文案不算(把 if 条件改 false 就能骗过纯文案断言)") # ── 4. go job:整机启动图判据必须单列一步跑 kernelboot/modules ── gojob = step_runs("go")