From 114b0537332cfb50b066be9575cf52057253fe8e Mon Sep 17 00:00:00 2001 From: dongzi Date: Tue, 14 Jul 2026 10:58:05 +0800 Subject: [PATCH] =?UTF-8?q?feat:=201=E3=80=81=E6=B5=81=E6=B0=B4=E7=BA=BF?= =?UTF-8?q?=E6=80=BB=E5=BC=80=E5=85=B3=E9=85=8D=E7=BD=AE=202=E3=80=81?= =?UTF-8?q?=E5=88=A0=E9=99=A4p0p1p2=E7=BA=A7=E5=88=AB=E9=98=BB=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitea/config/redis-schema-check-config.yaml | 17 ++++----- .gitea/workflows/redis-schema-check.yaml | 19 ++++++++++ docs/实施方案.md | 11 ++---- docs/配置说明.md | 37 +++++++++---------- .../redis/analyze/SchemaCheckAnalyzer.java | 11 +----- .../redis/cli/RedisSchemaCheckerMain.java | 5 +++ .../redis/config/CheckerConfig.java | 21 ++++++----- .../redis/config/ConfigLoader.java | 2 +- src/main/resources/default-config.yaml | 11 ++---- .../redis/config/ConfigLoaderTest.java | 8 ++-- 10 files changed, 74 insertions(+), 68 deletions(-) diff --git a/.gitea/config/redis-schema-check-config.yaml b/.gitea/config/redis-schema-check-config.yaml index 78d2382..6d69433 100644 --- a/.gitea/config/redis-schema-check-config.yaml +++ b/.gitea/config/redis-schema-check-config.yaml @@ -5,27 +5,24 @@ # - 本配置文件为业务覆盖配置,会与 jar 内 default-config.yaml 深度合并 # - 未声明的项沿用工具内置默认值(忽略规则、检测模式等) -# 运行模式 notify-仅通知,不阻断流水线 block-按block_severities阻断流水线(exit 1) -mode: notify +# 总开关 true-执行检测 false-跳过检测 +enabled: true -# block 模式下触发阻断的严重级别(P0/P1/P2 全部阻断) -block_severities: - - P0 - - P1 - - P2 +# 运行模式 notify-仅通知,不阻断流水线 block-检测到结构变更即阻断流水线(exit 1) +mode: notify # 通知配置 notify: enabled: true webhook_url: https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=fa14f0b3-e01a-40f6-96bd-e18beb94e85e notify_on_clean: false - title_prefix: "【Redis数据结构变更】" + title_prefix: "【序列化结构变更】" # 观察期:先只扫描 jnpf-tenant 模块,稳定后改为 include_modules: [] include_modules: - jnpf-tenant -# 人工补充映射(自动推断不准时使用) +# 手动补充映射(自动推断不准时使用) manual_mappings: - id: tenant-db-content writer_method: "jnpf.util.TenantDbContentCacheHelper#cacheSuccess" @@ -33,5 +30,5 @@ manual_mappings: value_type: "jnpf.util.TenantDbContentCacheHelper.CacheEnvelope" description: "租户库信息缓存" -# 已知误报抑制(按需添加) +# 误报忽略(按需添加) suppressions: [] diff --git a/.gitea/workflows/redis-schema-check.yaml b/.gitea/workflows/redis-schema-check.yaml index 9ef2237..18cb175 100644 --- a/.gitea/workflows/redis-schema-check.yaml +++ b/.gitea/workflows/redis-schema-check.yaml @@ -30,9 +30,19 @@ jobs: echo "错误: 缺少 .gitea/config/redis-schema-check-config.yaml" exit 1 fi + # 顶层总开关 enabled: false 时跳过后续步骤(与 notify.enabled 区分,仅匹配行首) + if grep -Eq '^enabled:[[:space:]]*false([[:space:]]|#|$)' .gitea/config/redis-schema-check-config.yaml; then + echo "总开关 enabled=false,跳过 Redis 结构检查" + touch /tmp/redis-schema-check.skip + fi - name: 从 Nexus 私库下载 redis-schema-checker run: | + if [ -f /tmp/redis-schema-check.skip ]; then + echo "总开关已关闭,跳过下载" + exit 0 + fi + GROUP_PATH="com/codechecker/redis-schema-checker" JAR_NAME="redis-schema-checker-${REDIS_SCHEMA_CHECKER_VERSION}.jar" JAR_URL="${REDIS_SCHEMA_CHECKER_REPO_URL}/${GROUP_PATH}/${REDIS_SCHEMA_CHECKER_VERSION}/${JAR_NAME}" @@ -57,10 +67,19 @@ jobs: - name: 验证 JDK run: | + if [ -f /tmp/redis-schema-check.skip ]; then + echo "总开关已关闭,跳过" + exit 0 + fi echo "Java: $(java -version 2>&1 | head -1)" - name: 执行 Redis 序列化结构检测 run: | + if [ -f /tmp/redis-schema-check.skip ]; then + echo "总开关已关闭,跳过检测" + exit 0 + fi + OLD_SHA=$(git rev-parse HEAD~1 2>/dev/null || echo "") if [ -z "$OLD_SHA" ]; then echo "首次提交,跳过检测" diff --git a/docs/实施方案.md b/docs/实施方案.md index 232118d..c51a6ba 100644 --- a/docs/实施方案.md +++ b/docs/实施方案.md @@ -433,14 +433,11 @@ java -jar redis-schema-checker.jar \ 详见 `docs/配置说明.md`。核心开关: ```yaml -# 运行模式:notify(仅通知)| block(P0/P1/P2 全部阻断流水线) -mode: notify +# 总开关:false 时跳过检测与通知,流水线直接通过 +enabled: true -# block 模式下触发 exit 1 的严重级别(全部阻断) -block_severities: - - P0 - - P1 - - P2 +# 运行模式:notify(仅通知)| block(检测到结构变更即阻断流水线) +mode: notify # 是否发送企微通知 notify: diff --git a/docs/配置说明.md b/docs/配置说明.md index 247833f..40d1575 100644 --- a/docs/配置说明.md +++ b/docs/配置说明.md @@ -38,7 +38,6 @@ include_modules: - `detection.patterns`(W01~W03) - `ignore.key_patterns`(锁/计数器/token) -- `block_severities`(P0/P1/P2) - `detection.min_confidence`、`max_field_depth` 等 --- @@ -46,17 +45,14 @@ include_modules: ## 2. 业务仓完整配置示例 ```yaml +# 总开关:false 时不执行检测、不发通知、流水线直接通过 +enabled: true + # 运行模式 # notify - 仅通知,不阻断流水线 -# block - 按 block_severities 阻断流水线(exit 1) +# block - 检测到结构变更即阻断流水线(exit 1) mode: notify -# block 模式下触发 exit 1 的严重级别(全部阻断:P0/P1/P2) -block_severities: - - P0 - - P1 - - P2 - # 是否扫描测试代码(已确认:不扫描) scan_test_sources: false @@ -146,25 +142,28 @@ include_modules: ## 3. 配置项说明 -### 3.1 mode +### 3.1 enabled + +总开关。默认 `true`。 + +| 值 | 行为 | +|----|------| +| `true` | 正常执行检测(再按 `mode` / `notify` 行为) | +| `false` | 跳过检测与通知,流水线 `exit 0`(与 `notify.enabled` 无关) | + +临时关闭时可仅改此项,无需删除 workflow。 + +### 3.2 mode | 值 | 行为 | |----|------| | `notify` | 检测到变更 → 发企微 → `exit 0` | -| `block` | 检测到 `block_severities` 中的级别 → 发企微 → `exit 1` | - -### 3.2 block_severities - -默认 `["P0", "P1", "P2"]`,`block` 模式下任意级别变更均 `exit 1`。 +| `block` | 检测到任意结构变更 → 发企微 → `exit 1` | 建议上线初期仍使用 `mode: notify` 观察误报情况,确认稳定后再切换: ```yaml mode: block -block_severities: - - P0 - - P1 - - P2 ``` ### 3.3 notify @@ -280,7 +279,6 @@ include_modules: ```yaml mode: block -block_severities: [P0, P1, P2] include_modules: [] # 扩至全仓 ``` @@ -288,7 +286,6 @@ include_modules: [] # 扩至全仓 ```yaml mode: block -block_severities: [P0, P1, P2] include_modules: [] # 空表示全部模块 detection: patterns: [W01, W02, W03, W04, W05] diff --git a/src/main/java/com/codechecker/redis/analyze/SchemaCheckAnalyzer.java b/src/main/java/com/codechecker/redis/analyze/SchemaCheckAnalyzer.java index 7aeaea8..63a06e8 100644 --- a/src/main/java/com/codechecker/redis/analyze/SchemaCheckAnalyzer.java +++ b/src/main/java/com/codechecker/redis/analyze/SchemaCheckAnalyzer.java @@ -330,16 +330,7 @@ public class SchemaCheckAnalyzer { report.getChanges().addAll(changes); report.getKeyChanges().addAll(keyChanges.values()); - boolean blocked = false; - if (config.isBlockMode()) { - Set blockSev = new HashSet<>(config.getBlockSeverities()); - for (SchemaChange c : changes) { - if (blockSev.contains(c.getSeverity().name())) { - blocked = true; - break; - } - } - } + boolean blocked = config.isBlockMode() && !changes.isEmpty(); report.setBlocked(blocked); report.setExitCode(blocked ? 1 : 0); return report; diff --git a/src/main/java/com/codechecker/redis/cli/RedisSchemaCheckerMain.java b/src/main/java/com/codechecker/redis/cli/RedisSchemaCheckerMain.java index d8320d5..8f1badd 100644 --- a/src/main/java/com/codechecker/redis/cli/RedisSchemaCheckerMain.java +++ b/src/main/java/com/codechecker/redis/cli/RedisSchemaCheckerMain.java @@ -55,6 +55,11 @@ public class RedisSchemaCheckerMain implements Callable { try { CheckerConfig config = ConfigLoader.load(configPath); + if (!config.isEnabled()) { + System.out.println("[redis-schema-checker] 总开关 enabled=false,跳过检测。"); + return 0; + } + if (oldSha == null || oldSha.trim().isEmpty()) { System.out.println("[redis-schema-checker] 无对比基准提交,跳过检测。"); return 0; diff --git a/src/main/java/com/codechecker/redis/config/CheckerConfig.java b/src/main/java/com/codechecker/redis/config/CheckerConfig.java index ea84479..7d4a130 100644 --- a/src/main/java/com/codechecker/redis/config/CheckerConfig.java +++ b/src/main/java/com/codechecker/redis/config/CheckerConfig.java @@ -10,11 +10,12 @@ import java.util.Map; */ public class CheckerConfig { + /** 总开关:false 时跳过检测与通知(流水线 exit 0) */ + private boolean enabled = true; + /** notify | block */ private String mode = "notify"; - private List blockSeverities = new ArrayList<>(); - private boolean scanTestSources = false; private List sourceRoots = new ArrayList<>(); @@ -231,6 +232,14 @@ public class CheckerConfig { } } + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + public String getMode() { return mode; } @@ -239,14 +248,6 @@ public class CheckerConfig { this.mode = mode; } - public List getBlockSeverities() { - return blockSeverities; - } - - public void setBlockSeverities(List blockSeverities) { - this.blockSeverities = blockSeverities; - } - public boolean isScanTestSources() { return scanTestSources; } diff --git a/src/main/java/com/codechecker/redis/config/ConfigLoader.java b/src/main/java/com/codechecker/redis/config/ConfigLoader.java index 6c8d559..733d91b 100644 --- a/src/main/java/com/codechecker/redis/config/ConfigLoader.java +++ b/src/main/java/com/codechecker/redis/config/ConfigLoader.java @@ -75,8 +75,8 @@ public final class ConfigLoader { private static CheckerConfig bind(Map map) { CheckerConfig config = new CheckerConfig(); + config.setEnabled(bool(map, "enabled", true)); config.setMode(str(map, "mode", "notify")); - config.setBlockSeverities(strList(map.get("block_severities"))); config.setScanTestSources(bool(map, "scan_test_sources", false)); config.setSourceRoots(strList(map.get("source_roots"))); config.setIncludeModules(strList(map.get("include_modules"))); diff --git a/src/main/resources/default-config.yaml b/src/main/resources/default-config.yaml index 1e0fc30..bd511bb 100644 --- a/src/main/resources/default-config.yaml +++ b/src/main/resources/default-config.yaml @@ -1,14 +1,11 @@ # redis-schema-checker 内置默认配置 # 业务仓库通过 --config 指定的配置会与本文件深度合并(业务配置优先)。 -# 运行模式:notify(仅通知)| block(按 block_severities 阻断,exit 1) -mode: notify +# 总开关:false 时不执行检测、不发通知、流水线直接通过 +enabled: true -# block 模式下触发阻断的严重级别(默认全部阻断) -block_severities: - - P0 - - P1 - - P2 +# 运行模式:notify(仅通知)| block(检测到结构变更即阻断,exit 1) +mode: notify # 是否扫描测试代码(第一版固定 false) scan_test_sources: false diff --git a/src/test/java/com/codechecker/redis/config/ConfigLoaderTest.java b/src/test/java/com/codechecker/redis/config/ConfigLoaderTest.java index cc9502b..3076b2c 100644 --- a/src/test/java/com/codechecker/redis/config/ConfigLoaderTest.java +++ b/src/test/java/com/codechecker/redis/config/ConfigLoaderTest.java @@ -16,8 +16,8 @@ class ConfigLoaderTest { @Test void loadsDefaultsWhenNoBusinessConfig() { CheckerConfig config = ConfigLoader.load(null); + assertTrue(config.isEnabled()); assertEquals("notify", config.getMode()); - assertTrue(config.getBlockSeverities().contains("P0")); assertTrue(config.getDetection().getPatterns().contains("W01")); assertFalse(config.isScanTestSources()); } @@ -25,18 +25,20 @@ class ConfigLoaderTest { @Test void businessConfigOverridesDefaults(@org.junit.jupiter.api.io.TempDir Path tmp) throws IOException { Path cfg = tmp.resolve("biz.yaml"); - Files.write(cfg, ("mode: block\n" + Files.write(cfg, ("enabled: false\n" + + "mode: block\n" + "include_modules:\n - jnpf-tenant\n" + "notify:\n enabled: false\n").getBytes(StandardCharsets.UTF_8)); CheckerConfig config = ConfigLoader.load(cfg); + assertFalse(config.isEnabled()); assertEquals("block", config.getMode()); assertTrue(config.isBlockMode()); assertEquals(1, config.getIncludeModules().size()); assertEquals("jnpf-tenant", config.getIncludeModules().get(0)); // 未覆盖项保留默认 assertFalse(config.getNotify().isEnabled()); - assertTrue(config.getBlockSeverities().contains("P2")); + assertTrue(config.getDetection().getPatterns().contains("W01")); } @Test