feat: 1、流水线总开关配置 2、删除p0p1p2级别阻断
All checks were successful
Redis序列化结构检查 / redis-schema-check (push) Has been skipped

This commit is contained in:
2026-07-14 10:58:05 +08:00
parent 7a8ca7ce0b
commit 114b053733
10 changed files with 74 additions and 68 deletions

View File

@@ -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: []

View File

@@ -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 "首次提交,跳过检测"

View File

@@ -433,14 +433,11 @@ java -jar redis-schema-checker.jar \
详见 `docs/配置说明.md`。核心开关:
```yaml
# 运行模式notify仅通知| blockP0/P1/P2 全部阻断流水线)
mode: notify
# 总开关false 时跳过检测与通知,流水线直接通过
enabled: true
# block 模式下触发 exit 1 的严重级别(全部阻断
block_severities:
- P0
- P1
- P2
# 运行模式notify仅通知| block检测到结构变更即阻断流水线
mode: notify
# 是否发送企微通知
notify:

View File

@@ -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]

View File

@@ -330,16 +330,7 @@ public class SchemaCheckAnalyzer {
report.getChanges().addAll(changes);
report.getKeyChanges().addAll(keyChanges.values());
boolean blocked = false;
if (config.isBlockMode()) {
Set<String> 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;

View File

@@ -55,6 +55,11 @@ public class RedisSchemaCheckerMain implements Callable<Integer> {
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;

View File

@@ -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<String> blockSeverities = new ArrayList<>();
private boolean scanTestSources = false;
private List<String> 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<String> getBlockSeverities() {
return blockSeverities;
}
public void setBlockSeverities(List<String> blockSeverities) {
this.blockSeverities = blockSeverities;
}
public boolean isScanTestSources() {
return scanTestSources;
}

View File

@@ -75,8 +75,8 @@ public final class ConfigLoader {
private static CheckerConfig bind(Map<String, Object> 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")));

View File

@@ -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

View File

@@ -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