Files
schemaCheck/src/main/java/com/codechecker/cache/cli/CacheSchemaCheckerMain.java
dongzi e7aa970ef8
All checks were successful
缓存序列化结构检查 / cache-schema-check (push) Has been skipped
feat:
1、多 key 默认拼成 1 条企微通知
2、UTF-8 超过 4096 字节 → 按 key 拆开,每条带完整抬头,依次发送
3、条间间隔 200ms,降低机器人限频风险
4、CI 控制台会标明「超长已按 key 拆为 N 条」并逐条打印
2026-07-14 14:30:24 +08:00

108 lines
4.2 KiB
Java
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.

package com.codechecker.cache.cli;
import com.codechecker.cache.analyze.SchemaCheckAnalyzer;
import com.codechecker.cache.config.CheckerConfig;
import com.codechecker.cache.config.ConfigLoader;
import com.codechecker.cache.notify.WeComNotifier;
import com.codechecker.cache.report.CheckReport;
import com.codechecker.cache.report.ReportBuilder;
import picocli.CommandLine;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;
import java.nio.file.Path;
import java.util.List;
import java.util.concurrent.Callable;
/**
* 命令行入口。退出码0 通过 / 1 阻断 / 2 执行错误。
*/
@Command(name = "cache-schema-checker",
mixinStandardHelpOptions = true,
version = "cache-schema-checker 1.0.0",
description = "检测两次提交间缓存 value 序列化结构变更并通过企微机器人通知。")
public class CacheSchemaCheckerMain implements Callable<Integer> {
@Option(names = "--config", required = true, description = "业务仓库检测配置文件路径")
private Path configPath;
@Option(names = "--repo-root", required = true, description = "被检测仓库根目录")
private Path repoRoot;
@Option(names = "--old-sha", required = true, description = "对比基准提交")
private String oldSha;
@Option(names = "--new-sha", required = true, description = "当前提交")
private String newSha;
@Option(names = "--branch", description = "分支名(用于报告展示)")
private String branch;
@Option(names = "--modifier", description = "提交人")
private String modifier;
@Option(names = "--modify-time", description = "提交时间")
private String modifyTime;
@Option(names = "--repository", description = "仓库名(默认取仓库目录名)")
private String repository;
@Option(names = "--dry-run", description = "只输出报告,不发送企微通知")
private boolean dryRun;
@Override
public Integer call() {
try {
CheckerConfig config = ConfigLoader.load(configPath);
if (!config.isEnabled()) {
System.out.println("[cache-schema-checker] 总开关 enabled=false跳过检测。");
return 0;
}
if (oldSha == null || oldSha.trim().isEmpty()) {
System.out.println("[cache-schema-checker] 无对比基准提交,跳过检测。");
return 0;
}
Path root = repoRoot.toAbsolutePath().normalize();
SchemaCheckAnalyzer analyzer = new SchemaCheckAnalyzer(config, root);
CheckReport report = analyzer.analyze(oldSha, newSha);
report.setBranch(branch);
report.setModifier(modifier);
report.setModifyTime(modifyTime);
report.setRepository(repository != null ? repository : root.getFileName().toString());
ReportBuilder builder = new ReportBuilder(config.getNotify().getTitlePrefix());
// CI字段明细 + 完整企微 Markdown
System.out.println(builder.toConsole(report));
boolean shouldNotify = config.getNotify().isEnabled()
&& (report.hasChanges() || config.getNotify().isNotifyOnClean());
if (shouldNotify && !dryRun) {
String webhook = config.getNotify().getWebhookUrl();
List<String> messages = builder.toWeComMessages(report);
int ok = new WeComNotifier().sendMarkdownMessages(webhook, messages);
System.out.println("[cache-schema-checker] 企微通知发送: "
+ ok + "/" + messages.size()
+ (messages.size() > 1 ? "(已按 key 拆分)" : ""));
}
if (report.isBlocked()) {
System.out.println("[cache-schema-checker] block 模式命中流水线将被阻断exit 1");
}
return report.getExitCode();
} catch (Exception e) {
System.err.println("[cache-schema-checker] 执行错误: " + e.getMessage());
e.printStackTrace();
return 2;
}
}
public static void main(String[] args) {
int exitCode = new CommandLine(new CacheSchemaCheckerMain()).execute(args);
System.exit(exitCode);
}
}