feat: 流水线更新,修复commit次数统计不正确的问题
All checks were successful
缓存序列化结构检查 / cache-schema-check (push) Has been skipped

This commit is contained in:
2026-07-14 17:30:35 +08:00
parent 96a3bd46cf
commit b7f4bbe03c
3 changed files with 59 additions and 9 deletions

View File

@@ -82,6 +82,8 @@ jobs:
env: env:
# push 前 tip新分支首次 push 时为全 0。workflow_dispatch 可能为空,下方会回退。 # push 前 tip新分支首次 push 时为全 0。workflow_dispatch 可能为空,下方会回退。
PUSH_BEFORE: ${{ gitea.event.before }} PUSH_BEFORE: ${{ gitea.event.before }}
# push 事件携带的 commits 列表JSON用于准确统计 commit 数(不受浅克隆影响)
PUSH_COMMITS_JSON: ${{ toJson(gitea.event.commits) }}
run: | run: |
if [ -f /tmp/cache-schema-check.skip ]; then if [ -f /tmp/cache-schema-check.skip ]; then
echo "总开关已关闭,跳过检测" echo "总开关已关闭,跳过检测"
@@ -113,7 +115,7 @@ jobs:
exit 0 exit 0
fi fi
# 确保 before 提交对象可读(按 SHA 浅取,无需全量历史) # 确保提交对象可读
ensure_commit() { ensure_commit() {
local sha="$1" local sha="$1"
if git cat-file -e "${sha}^{commit}" 2>/dev/null; then if git cat-file -e "${sha}^{commit}" 2>/dev/null; then
@@ -123,7 +125,6 @@ jobs:
if git fetch --depth 1 origin "${sha}"; then if git fetch --depth 1 origin "${sha}"; then
git cat-file -e "${sha}^{commit}" 2>/dev/null && return 0 git cat-file -e "${sha}^{commit}" 2>/dev/null && return 0
fi fi
# 兜底:逐步 deepen应对部分服务端不允许直接 fetch SHA
for d in 10 30 50 100; do for d in 10 30 50 100; do
echo "deepen ${d}…" echo "deepen ${d}…"
git fetch --deepen "${d}" || true git fetch --deepen "${d}" || true
@@ -134,6 +135,43 @@ jobs:
return 1 return 1
} }
# 加深当前 tip 的历史,直到 before 成为 after 的祖先(否则 rev-list 在浅克隆下会少算)
ensure_range() {
local old="$1"
local new="$2"
local i=0
while [ "$i" -lt 15 ]; do
if git merge-base --is-ancestor "${old}" "${new}" 2>/dev/null; then
return 0
fi
echo "区间历史不完整deepen 20…第 $((i + 1)) 次)"
git fetch --deepen 20 || true
i=$((i + 1))
done
# force-push 等非祖先关系:对象在即可做 git show但 rev-list 不可靠
if git cat-file -e "${old}^{commit}" 2>/dev/null \
&& git cat-file -e "${new}^{commit}" 2>/dev/null; then
echo "警告: ${old} 不是 ${new} 的祖先(可能 force-pushcommit 计数将改用事件 payload"
return 0
fi
return 1
}
# 优先用 Gitea push 事件的 commits 数组长度(准确且不依赖 shallow
count_from_payload() {
if [ -z "${PUSH_COMMITS_JSON:-}" ] || [ "${PUSH_COMMITS_JSON}" = "null" ] || [ "${PUSH_COMMITS_JSON}" = "[]" ]; then
return 1
fi
# Gitea/GitHub push payload: [{"id":"<40位sha>", ...}, ...]
local n
n=$(printf '%s' "${PUSH_COMMITS_JSON}" | grep -oE '"id"[[:space:]]*:[[:space:]]*"[0-9a-fA-F]{7,40}"' | wc -l | tr -d ' ')
if [ -n "$n" ] && [ "$n" -gt 0 ] 2>/dev/null; then
echo "$n"
return 0
fi
return 1
}
if ! ensure_commit "$OLD_SHA"; then if ! ensure_commit "$OLD_SHA"; then
echo "错误: 无法获取 push 前 tip ${OLD_SHA},请检查 shallow/权限" echo "错误: 无法获取 push 前 tip ${OLD_SHA},请检查 shallow/权限"
exit 2 exit 2
@@ -142,10 +180,22 @@ jobs:
echo "错误: 无法解析当前 tip ${NEW_SHA}" echo "错误: 无法解析当前 tip ${NEW_SHA}"
exit 2 exit 2
fi fi
if ! ensure_range "$OLD_SHA" "$NEW_SHA"; then
echo "错误: 无法补齐 ${OLD_SHA}..${NEW_SHA} 历史"
exit 2
fi
echo "对比区间: ${OLD_SHA} → ${NEW_SHA}" echo "对比区间: ${OLD_SHA} → ${NEW_SHA}"
COMMIT_COUNT=$(git rev-list --count "${OLD_SHA}..${NEW_SHA}" 2>/dev/null || echo "?")
echo "本次 push 累计 commit 数(约): ${COMMIT_COUNT}" COMMIT_COUNT=""
if COMMIT_COUNT=$(count_from_payload); then
echo "本次 push 累计 commit 数: ${COMMIT_COUNT}(来自事件 payload"
elif git merge-base --is-ancestor "$OLD_SHA" "$NEW_SHA" 2>/dev/null; then
COMMIT_COUNT=$(git rev-list --count "${OLD_SHA}..${NEW_SHA}" 2>/dev/null || echo "?")
echo "本次 push 累计 commit 数: ${COMMIT_COUNT}(来自 git rev-list"
else
echo "本次 push 累计 commit 数: ?(非祖先关系且无 payload"
fi
COMMIT_TIME=$(git log -1 --format=%cd --date=format:'%Y-%m-%d %H:%M:%S' "${NEW_SHA}") COMMIT_TIME=$(git log -1 --format=%cd --date=format:'%Y-%m-%d %H:%M:%S' "${NEW_SHA}")

View File

@@ -36,6 +36,7 @@ mode=block 且含任意结构变更 → exit 1流水线失败
- `before``0` / 空 → 新分支首次 push跳过 - `before``0` / 空 → 新分支首次 push跳过
- `workflow_dispatch` 无 before → 回退 `HEAD~1` - `workflow_dispatch` 无 before → 回退 `HEAD~1`
- 中间 commit 改坏又被末 commit 改回 → 累计可能无告警(以最终结构为准) - 中间 commit 改坏又被末 commit 改回 → 累计可能无告警(以最终结构为准)
- commit 计数:优先取 `gitea.event.commits` 长度;否则 deepen 到 `before` 为祖先后再 `git rev-list`(浅克隆下直接 `rev-list` 会少算)
--- ---
@@ -141,7 +142,7 @@ com/codechecker/cache-schema-checker/1.0.0/
| 下载 jar 失败 | Nexus 地址/版本错误 | 检查 env 变量 | | 下载 jar 失败 | Nexus 地址/版本错误 | 检查 env 变量 |
| 未收到企微 | Secret 未配 / notify.enabled=false / webhook_url 空 | 检查配置 | | 未收到企微 | Secret 未配 / notify.enabled=false / webhook_url 空 | 检查配置 |
| 大量误报 | 锁/计数器未过滤 | 补充 ignore.key_patterns | | 大量误报 | 锁/计数器未过滤 | 补充 ignore.key_patterns |
| 漏报(多 commit | 业务仓仍用旧版 `HEAD~1` 流水线 | 同步本仓库最新 workflow`before..after` | | commit 数显示为 1实际多个 | 浅克隆下 `rev-list` 看不到中间提交 | 已修复:优先事件 `commits` 长度;并 deepen 到 before 为祖先 |
| 漏报(模式/模块) | W0x 未开 / include_modules 过窄 | 确认 W01~W05检查模块过滤 | | 漏报(模式/模块) | W0x 未开 / include_modules 过窄 | 确认 W01~W05检查模块过滤 |
| 类型展开不完整 | 类型在依赖 jar 中 | 补充 `manual_mappings.value_type` | | 类型展开不完整 | 类型在依赖 jar 中 | 补充 `manual_mappings.value_type` |

View File

@@ -245,12 +245,11 @@ java -jar cache-schema-checker-1.0.0.jar \
2. `--old-sha` = `gitea.event.before`push 前 tip 2. `--old-sha` = `gitea.event.before`push 前 tip
3. `before` 为空或全 `0`(新分支首次 push→ 跳过检测,`exit 0` 3. `before` 为空或全 `0`(新分支首次 push→ 跳过检测,`exit 0`
4. `workflow_dispatch` 无 before 时回退 `HEAD~1` 4. `workflow_dispatch` 无 before 时回退 `HEAD~1`
5. 浅克隆当前 tip`--depth 1`),再按需 `git fetch --depth 1 <before>` / `deepen`**无需全量历史** 5. 浅克隆当前 tip`--depth 1`),再按需 `git fetch --depth 1 <before>`;统计 commit 数时 deepen 至 `before` 为祖先,或直接用事件 `commits` 数组长度(**无需全量历史**
> 一次 push 含多个 commit 时,只做 **一次** 检测,对比区间为整次 push 的累计 diff`before..after`),不会漏掉中间 commit 留下的结构变更。 > 一次 push 含多个 commit 时,只做 **一次** 检测,对比区间为整次 push 的累计 diff`before..after`),不会漏掉中间 commit 留下的结构变更。
> 不做「每个 commit 各告警一条」;中间引入又被末 commit 改回的净无变更,累计结果可能为「无变更」(符合阻断「最终结构」的目标)。 > 不做「每个 commit 各告警一条」;中间引入又被末 commit 改回的净无变更,累计结果可能为「无变更」(符合阻断「最终结构」的目标)。
> 日志中的 commit 数:优先 `gitea.event.commits`;勿在未 deepen 时用浅库 `rev-list`(会少算)。
详见 `docs/CI集成说明.md`
### 6.3 处理步骤 ### 6.3 处理步骤