Просмотр исходного кода

fix(cron): 接口测试闭环提交/推送守卫,杜绝'假成功'(unmerged 时 commit 被拒仍报 push 成功)

cron-fix 1 неделя назад
Родитель
Сommit
04e89e804e
1 измененных файлов с 68 добавлено и 26 удалено
  1. 68 26
      run_interface_tests_cron.sh

+ 68 - 26
run_interface_tests_cron.sh

@@ -63,11 +63,20 @@ log "REPO=$REPO_DIR BRANCH=$BRANCH BASE=$BASE_URL HOST=$HOST_HDR"
 #    --autostash 处理,避免破坏用户其他在途工作。
 # ---------------------------------------------------------------------------
 git checkout -- INTERFACE_TEST_REPORT.md interface_test_report.tsv cfc-frontend/INTERFACE_TEST_MATRIX.md 2>/dev/null
+# 预检:若工作区已存在未解决冲突(多因上轮 autostash 回填冲突残留),先告警,避免本轮静默空转
+if git ls-files -u | grep -q .; then
+  log "⚠️ 工作区已存在未解决冲突(unmerged),pull 前请先人工 git status 处理;本轮继续但提交大概率失败"
+fi
 if git pull --rebase --autostash origin "$BRANCH" >>"$LOG_DIR/interface_cron.log" 2>&1; then
   log "git pull 成功"
 else
   log "git pull 失败(可能本地有冲突或凭证问题),用当前代码继续"
 fi
+# 后检:pull+autostash 回填后出现未解决冲突时,明确提示——此状态会令后续 commit 被拒,
+#       由下方「提交守卫」拦截,绝不会误报 push 成功。
+if git ls-files -u | grep -q .; then
+  log "⚠️ git pull --rebase --autostash 引入/残留未解决冲突,后续 git commit 将被拒绝(提交守卫会拦截,不假成功推送)"
+fi
 
 # ---------------------------------------------------------------------------
 # 2) 检测新增/变更需求(前端接口面变化)
@@ -470,11 +479,26 @@ git add -f INTERFACE_TEST_REPORT.md interface_test_report.tsv cfc-frontend/INTER
 [ -s "$EXTRA_CASES" ] && git add -f "$EXTRA_CASES"
 # 纳入 Playwright E2E 冒烟报告(仅当本轮实际执行过,PW_RPT 才存在)
 [ -f "$PW_RPT" ] && git add -f "$PW_RPT" "$PW_LOG"
+COMMIT_OK=1   # 1=已提交 0=提交失败 2=无变更跳过
+HEAD_BEFORE=$(git rev-parse HEAD)
 if git diff --cached --quiet; then
   log "无测试结果变更,跳过提交"
+  COMMIT_OK=2
 else
-  git commit -m "test(interface): 接口冒烟闭环 $(date '+%Y-%m-%d %H:%M') — 通过率 ${RATE}% (fix=${FIXED_COUNT} reg=${REGRESSED_COUNT}); 测试用例 ${TC_DONE:-?}/${TC_E2E_TOTAL:-?} 完成(文档化${TC_DOC:-?})" \
-    >>"$LOG_DIR/interface_cron.log" 2>&1 && log "已提交测试结果(测试用例完成 ${TC_DONE:-?}/${TC_E2E_TOTAL:-?})"
+  if git commit -m "test(interface): 接口冒烟闭环 $(date '+%Y-%m-%d %H:%M') — 通过率 ${RATE}% (fix=${FIXED_COUNT} reg=${REGRESSED_COUNT}); 测试用例 ${TC_DONE:-?}/${TC_E2E_TOTAL:-?} 完成(文档化${TC_DOC:-?})" \
+    >>"$LOG_DIR/interface_cron.log" 2>&1; then
+    HEAD_AFTER=$(git rev-parse HEAD)
+    if [ "$HEAD_BEFORE" = "$HEAD_AFTER" ]; then
+      # git commit 返回 0 但未产生新提交(unmerged/钩子拦截等):必须按失败处理,否则会假成功
+      log "⚠️ git commit 返回成功但未产生新提交(HEAD 未变化,疑似工作区未解决冲突 unmerged 或 pre-commit 钩子拦截)——测试结果未入库"
+      COMMIT_OK=0
+    else
+      log "已提交测试结果(测试用例完成 ${TC_DONE:-?}/${TC_E2E_TOTAL:-?})"
+    fi
+  else
+    log "⚠️ git commit 失败(详见 $LOG_DIR/interface_cron.log)——测试结果未入库"
+    COMMIT_OK=0
+  fi
 fi
 
 # ---------------------------------------------------------------------------
@@ -482,35 +506,46 @@ fi
 #    增强:远端领先(非快进)时自动 rebase 后重试,避免测试结果不落远端。
 #         凭证/网络类错误不盲目重试,直接失败并留待下次运行。
 # ---------------------------------------------------------------------------
-PUSH_LOG="$RUN_DIR/push.log"
-MAX_PUSH_RETRY=2
-push_ok=0
-attempt=0
-while [ "$attempt" -lt $((MAX_PUSH_RETRY + 1)) ]; do
-  attempt=$((attempt + 1))
-  if git push origin "$BRANCH" >"$PUSH_LOG" 2>&1; then
-    push_ok=1
-    log "git push 成功 — 测试闭环已同步远端(第 ${attempt} 次尝试)"
-    break
+# 提交守卫:仅当测试产物确实已提交(COMMIT_OK=1)才推送远端;否则绝不推送,
+#           避免「远端无新提交 → push 返回成功」造成假成功误报。
+if [ "${COMMIT_OK:-1}" -ne 1 ]; then
+  if [ "${COMMIT_OK:-1}" -eq 0 ]; then
+    log "⛔ 提交未成功(COMMIT_OK=0),跳过 git push —— 不假成功误报;请人工解决工作区冲突后重跑(或手动提交推送)"
+  else
+    log "(无提交内容,无需推送)"
   fi
-  # 仅在「远端领先/非快进」时自动 rebase 后重试
-  if grep -qiE "non-fast-forward|fetch first|Updates were rejected|rejected" "$PUSH_LOG"; then
-    log "git push 被拒(远端领先/非快进)。rebase 后重试(${attempt}/${MAX_PUSH_RETRY})"
-    # rebase 期间用 --autostash 保护未提交改动(如事后刷新的 interface_test_report.tsv)
-    if git pull --rebase --autostash origin "$BRANCH" >>"$LOG_DIR/interface_cron.log" 2>&1; then
-      log "rebase 完成,重新尝试 push"
+  push_ok=0
+else
+  PUSH_LOG="$RUN_DIR/push.log"
+  MAX_PUSH_RETRY=2
+  push_ok=0
+  attempt=0
+  while [ "$attempt" -lt $((MAX_PUSH_RETRY + 1)) ]; do
+    attempt=$((attempt + 1))
+    if git push origin "$BRANCH" >"$PUSH_LOG" 2>&1; then
+      push_ok=1
+      log "git push 成功 — 测试闭环已同步远端(第 ${attempt} 次尝试)"
+      break
+    fi
+    # 仅在「远端领先/非快进」时自动 rebase 后重试
+    if grep -qiE "non-fast-forward|fetch first|Updates were rejected|rejected" "$PUSH_LOG"; then
+      log "git push 被拒(远端领先/非快进)。rebase 后重试(${attempt}/${MAX_PUSH_RETRY})"
+      # rebase 期间用 --autostash 保护未提交改动(如事后刷新的 interface_test_report.tsv)
+      if git pull --rebase --autostash origin "$BRANCH" >>"$LOG_DIR/interface_cron.log" 2>&1; then
+        log "rebase 完成,重新尝试 push"
+      else
+        log "rebase 失败(可能存在冲突),中止 push 重试"
+        break
+      fi
     else
-      log "rebase 失败(可能存在冲突),中止 push 重试"
+      # 凭证/网络等其他错误:不盲目重试,避免空耗与误报
+      log "git push 失败(疑似凭证/网络,非非快进类): $(grep -iE 'error|fatal|timed out|could not|permission denied' "$PUSH_LOG" | head -3 | tr '\n' ' ')"
       break
     fi
-  else
-    # 凭证/网络等其他错误:不盲目重试,避免空耗与误报
-    log "git push 失败(疑似凭证/网络,非非快进类): $(grep -iE 'error|fatal|timed out|could not|permission denied' "$PUSH_LOG" | head -3 | tr '\n' ' ')"
-    break
+  done
+  if [ "$push_ok" -ne 1 ]; then
+    log "git push 最终失败,本轮结果未同步远端(下次运行将重试)"
   fi
-done
-if [ "$push_ok" -ne 1 ]; then
-  log "git push 最终失败,本轮结果未同步远端(下次运行将重试)"
 fi
 
 # 更新回归基线(仅有效轮才覆盖,避免无效轮污染下一轮回归对比)
@@ -519,4 +554,11 @@ cp "$CUR_TSV" "$PREV_TSV"
 cp "$CUR_TSV" "interface_test_report.tsv"
 log "已同步全量结果 -> interface_test_report.tsv"
 
+# 提交守卫收尾:若测试产物提交失败(COMMIT_OK=0),以非零退出码标记本轮未真正闭环,
+#               便于自动化调度与 owner 识别「假成功」已被消除(而非静默通过)。
+if [ "${COMMIT_OK:-1}" -eq 0 ]; then
+  log "⛔ 本轮提交失败(COMMIT_OK=0),闭环未完成;退出码 1 标记"
+  log "===== 本轮结束(提交失败,未闭环)====="
+  exit 1
+fi
 log "===== 本轮结束 ====="