Files
schemaCheck/docs/CI集成说明.md
dongzi 0a5b04ffe6
All checks were successful
序列化结构检查 / serialization-schema-check (push) Successful in 2s
feat: V1.1 - 责任人区分,多次合并时误触修复
2026-08-05 17:29:17 +08:00

212 lines
7.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 序列化结构检测 — CI 集成说明
---
## 1. 集成概览
```text
开发者 push 代码(可含多个 commit
Gitea Actions 触发
浅克隆业务仓库 tipdepth=1+ 按需取 push 前 tipbefore
从 Nexus 下载 serialization-schema-checker.jar
java -jar 执行(对比 before → after累计 diff
有结构变更 → 企微通知(按 Key 骨架;删除橙/新增绿/修改灰)
mode=block 且含任意结构变更 → exit 1流水线失败
```
### 1.1 对比区间(重要)
| 参数 | 取值 | 含义 |
|------|------|------|
| `--old-sha` | `gitea.event.before` | 本次 push **前**的远端 tip |
| `--new-sha` | `gitea.sha` | 本次 push **后**的 tip |
一次 push 推了多个 commit 时,只跑 **一次** 检测,覆盖整次 push 的累计代码差,**不会**因为「变更发生在中间 commit、最后一个 commit 没改相关文件」而漏检。
不需要全量历史:工作树是当前 tip`before` 通过 `git fetch --depth 1 <sha>`(或 deepen取到即可。责任人过滤依赖 `git log old..new`,流水线已通过 `ensure_range` deepen保证区间提交可见。
边界:
- `before``0` / 空 → 新分支首次 push跳过
- `workflow_dispatch` 无 before → 回退 `HEAD~1`
- 中间 commit 改坏又被末 commit 改回 → 累计可能无告警(以最终结构为准)
- commit 计数:优先取 `gitea.event.commits` 长度;否则 deepen 到 `before` 为祖先后再 `git rev-list`(浅克隆下直接 `rev-list` 会少算)
### 1.2 责任人过滤(合并推送不背锅)
**前提**A/B 各自 push 都会跑检测B 的结构变更已在 B 的 push 告警。合并/代推时不应再让推送人背他人的锅,也不按人拆多条通知。
| 项 | 行为 |
|----|------|
| 对比区间 | 仍为整次 push 的 `before → after`Schema 新旧用全量 diff 回填) |
| 触发集 | 仅 **责任人 first-parent 非 merge 提交** 触及的 Java 文件 ∩ 区间 diff |
| 责任人参数 | `--responsible-author`(流水线传 `gitea.actor`);未传时回退 `--modifier` |
| Author 匹配 | `git log --author` + `--regexp-ignore-case`(子串;特殊字符已转义) |
| `--first-parent` | 大合并不把二路带入的他人历史算进推送人触及集 |
| `--no-merges` | 纯 merge 推送 → 触发集为空 → **不告警** |
| 责任人无自有 Java 改动 | 空报告、打日志跳过 |
```bash
java -jar serialization-schema-checker-1.0.0.jar \
--old-sha "$OLD_SHA" \
--new-sha "$NEW_SHA" \
--modifier "${{ gitea.actor }}" \
--responsible-author "${{ gitea.actor }}" \
...
```
---
## 2. 前置条件
| 项 | 说明 |
|----|------|
| Gitea Runner | 标签 `jdk11`,已安装 Java 11 |
| Nexus 私库 | 可访问 `http://192.168.3.25:18081/nexus/repository/maven-releases` |
| 工具 JAR | `com.codechecker:serialization-schema-checker:1.0.0` 已发布 |
---
## 3. 业务仓库文件清单
`jnpf-java-cloud` 中新增:
```text
jnpf-java-cloud/
├── .gitea/
│ ├── workflows/
│ │ └── serialization-schema-check.yaml # 流水线
│ └── config/
│ └── serialization-schema-check-config.yaml # 检测配置
```
请以本仓库 `.gitea/workflows/serialization-schema-check.yaml` 为模板同步到业务仓。
---
## 4. 流水线模板(要点)
完整可运行版本见:`.gitea/workflows/serialization-schema-check.yaml`
核心逻辑摘要:
```bash
# 1) 浅拉 tip
git clone --depth 1 --single-branch --branch "$BRANCH" "$REPO_URL" .
git checkout -B "$BRANCH" "$NEW_SHA" # NEW_SHA = gitea.sha
# 2) OLD_SHA = gitea.event.before全 0 则跳过;手动触发回退 HEAD~1
# 3) 本地没有 OLD_SHA 时:
git fetch --depth 1 origin "$OLD_SHA" # 优先
# 或 git fetch --deepen N # 兜底
# 4) 执行(对比区间全量;责任人过滤触发集)
java -jar serialization-schema-checker-1.0.0.jar \
--old-sha "$OLD_SHA" \
--new-sha "$NEW_SHA" \
--modifier "${{ gitea.actor }}" \
--responsible-author "${{ gitea.actor }}" \
...
```
---
## 5. 与现有流水线的关系
| 流水线 | 作用 | 关系 |
|--------|----------------|------|
| `demo.yaml` (AI代码质量分析) | AI Code Review | 并行,互不影响 |
| `code-check` (CodeChecker) | 通用变更检测 | **同模式**,可并列执行 |
| `serialization-schema-check` | 序列化结构检测 | 新增 |
---
## 6. 工具发布流程schemaCheck 仓库)
```bash
# 在 schemaCheck 仓库根目录
mvn clean package -DskipTests
# 发布到 Nexus需配置 settings.xml
mvn clean deploy -DskipTests
```
发布产物:
```text
com/codechecker/serialization-schema-checker/1.0.0/
├── serialization-schema-checker-1.0.0.jar # 可执行 fat-jar
└── serialization-schema-checker-1.0.0.pom
```
---
## 7. 退出码约定
| 退出码 | 含义 | 流水线表现 |
|--------|------|------------|
| 0 | 通过(含 notify 模式下的告警) / 跳过 | 绿色 |
| 1 | 阻断block 模式) | 红色 |
| 2 | 执行错误(配置缺失、无法取 before、jar 异常等) | 红色 |
---
## 8. 故障排查
| 现象 | 可能原因 | 处理 |
|------|----------|------|
| 新分支首次 push 跳过 | `before` 全 0 | 正常行为 |
| 无法获取 before / exit 2 | 浅克隆未取到对象、服务端禁 fetch SHA | 看日志中的 deepen确认 Gitea 允许按 SHA fetch |
| 下载 jar 失败 | Nexus 地址/版本错误 | 检查 env 变量 |
| 未收到企微 | Secret 未配 / notify.enabled=false / webhook_url 空 | 检查配置 |
| 大量 Redis 误报 | 锁/计数器未过滤 | 补充 ignore.key_patterns |
| 大量 MQ 误报 | 压测/临时 topic | 补充 ignore.mq_destinations |
| commit 数显示为 1实际多个 | 浅克隆下 `rev-list` 看不到中间提交 | 已修复:优先事件 `commits` 长度;并 deepen 到 before 为祖先 |
| 漏报(模式/模块) | W0x/MQ 未开 / include_modules 过窄 | 确认 W01~W05 与 mq_patterns含 MQ03~05、MQ-K03/K04检查 `mq_read_hints_enabled` 与模块过滤 |
| 类型展开不完整 | 类型在依赖 jar 中 | 补充 `manual_mappings.value_type` |
| 合并推送仍告他人改动 | jar 过旧(未含 first-parent/`--author` | 重新 deploy 含本次修复的 jar 并确认 Runner 下载到新包 |
| 责任人过滤后漏报自己的改动 | actor 与 commit author/email 对不上 | 看日志「责任人过滤…」;核对 `%an <%ae>` 是否含 actor 子串 |
---
## 9. 本地调试
模拟一次「多 commit push」的累计区间
```bash
# OLD = 推送前 tipNEW = 当前 tip可用 origin/branch@{1} 或显式 sha
OLD_SHA=$(git rev-parse origin/$(git branch --show-current)~3) # 示例:假设 ahead 3
NEW_SHA=$(git rev-parse HEAD)
AUTHOR=$(git log -1 --format=%an)
java -jar /path/to/serialization-schema-checker-1.0.0.jar \
--config .gitea/config/serialization-schema-check-config.yaml \
--repo-root . \
--old-sha "$OLD_SHA" \
--new-sha "$NEW_SHA" \
--branch $(git branch --show-current) \
--modifier "$AUTHOR" \
--responsible-author "$AUTHOR" \
--modify-time "$(git log -1 --format=%cd --date=format:'%Y-%m-%d %H:%M:%S')" \
--dry-run
```
单 commit 自测仍可用 `--old-sha HEAD~1 --new-sha HEAD`。未传 `--responsible-author` 时不做作者过滤(全量 diff 触发)。
---
## 10. 相关文档
| 文档 | 说明 |
|------|------|
| [实施方案.md](v1.0/redis序列化结构检测实施方案.md) | 缓存检测总体方案 |
| [配置说明.md](./配置说明.md) | YAML 配置项 |
| [MQ序列化结构检测方案.md](v1.0/MQ序列化结构检测实施方案.md) | MQ 消息体 SchemaRocketMQ + Kafka方案已落地 |