# 序列化结构检测 — CI 集成说明 --- ## 1. 集成概览 ```text 开发者 push 代码(可含多个 commit) ↓ Gitea Actions 触发 ↓ 浅克隆业务仓库 tip(depth=1)+ 按需取 push 前 tip(before) ↓ 从 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 `(或 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 回填) | | 触发集 | 仅 **责任人非 merge 提交** 触及的 Java 文件 ∩ 区间 diff | | 责任人参数 | `--responsible-author`(流水线传 `gitea.actor`);`--modifier` 同为 actor,报告抬头「责任人」 | | Author 匹配 | 对 `git log` 的 `%an <%ae>` **不区分大小写包含** actor(中文名/邮箱对不上时可能匹配失败) | | `--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` | | 合并推送仍告他人改动 | 未传 `--responsible-author` / jar 过旧 | 同步流水线模板;确认 jar ≥ 含责任人过滤的版本 | | 责任人过滤后漏报自己的改动 | actor 与 `%an <%ae>` 对不上 | 看日志「责任人过滤…」;核对 commit author 是否含 actor 子串 | --- ## 9. 本地调试 模拟一次「多 commit push」的累计区间: ```bash # OLD = 推送前 tip,NEW = 当前 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 消息体 Schema(RocketMQ + Kafka,方案已落地) |