feat: 项目整体命名修改cache-schema-checker
All checks were successful
缓存序列化结构检查 / cache-schema-check (push) Has been skipped
All checks were successful
缓存序列化结构检查 / cache-schema-check (push) Has been skipped
This commit is contained in:
@@ -1,11 +1,12 @@
|
|||||||
# ============================================================
|
# ============================================================
|
||||||
# Redis 序列化结构变更检测 — 业务仓库配置
|
# 缓存序列化结构变更检测 — 业务仓库配置
|
||||||
# ============================================================
|
# ============================================================
|
||||||
# 说明:
|
# 说明:
|
||||||
# - 本配置文件为业务覆盖配置,会与 jar 内 default-config.yaml 深度合并
|
# - 本配置文件为业务覆盖配置,会与 jar 内 default-config.yaml 深度合并
|
||||||
# - 未声明的项沿用工具内置默认值(忽略规则、检测模式等)
|
# - 未声明的项沿用工具内置默认值(忽略规则、检测模式等)
|
||||||
|
# - 当前实现以 Redis 写入检测为主,后续可扩展其他缓存
|
||||||
|
|
||||||
# 总开关 true-执行检测 false-跳过检测
|
# 总开关 true-执行检测 false-跳过检测(流水线直接通过,不发通知)
|
||||||
enabled: true
|
enabled: true
|
||||||
|
|
||||||
# 运行模式 notify-仅通知,不阻断流水线 block-检测到结构变更即阻断流水线(exit 1)
|
# 运行模式 notify-仅通知,不阻断流水线 block-检测到结构变更即阻断流水线(exit 1)
|
||||||
@@ -16,7 +17,7 @@ notify:
|
|||||||
enabled: true
|
enabled: true
|
||||||
webhook_url: https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=fa14f0b3-e01a-40f6-96bd-e18beb94e85e
|
webhook_url: https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=fa14f0b3-e01a-40f6-96bd-e18beb94e85e
|
||||||
notify_on_clean: false
|
notify_on_clean: false
|
||||||
title_prefix: "【序列化结构变更】"
|
title_prefix: "【缓存结构变更】"
|
||||||
|
|
||||||
# 观察期:先只扫描 jnpf-tenant 模块,稳定后改为 include_modules: []
|
# 观察期:先只扫描 jnpf-tenant 模块,稳定后改为 include_modules: []
|
||||||
include_modules:
|
include_modules:
|
||||||
@@ -1,17 +1,17 @@
|
|||||||
name: Redis序列化结构检查
|
name: 缓存序列化结构检查
|
||||||
run-name: ${{ gitea.actor }}的Redis结构检查
|
run-name: ${{ gitea.actor }}的缓存结构检查
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
env:
|
env:
|
||||||
# redis-schema-checker 私库坐标:com.codechecker:redis-schema-checker:1.0.0
|
# cache-schema-checker 私库坐标:com.codechecker:cache-schema-checker:1.0.0
|
||||||
REDIS_SCHEMA_CHECKER_VERSION: "1.0.0"
|
CACHE_SCHEMA_CHECKER_VERSION: "1.0.0"
|
||||||
REDIS_SCHEMA_CHECKER_REPO_URL: "http://192.168.3.25:18081/nexus/repository/maven-releases"
|
CACHE_SCHEMA_CHECKER_REPO_URL: "http://192.168.3.25:18081/nexus/repository/maven-releases"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
redis-schema-check:
|
cache-schema-check:
|
||||||
if: ${{ gitea.ref != 'refs/heads/pre' && gitea.ref != 'refs/heads/dev' && gitea.ref != 'refs/heads/master-2.0' }}
|
if: ${{ gitea.ref != 'refs/heads/pre' && gitea.ref != 'refs/heads/dev' && gitea.ref != 'refs/heads/master-2.0' }}
|
||||||
runs-on: jdk11
|
runs-on: jdk11
|
||||||
steps:
|
steps:
|
||||||
@@ -26,26 +26,26 @@ jobs:
|
|||||||
|
|
||||||
- name: 检查配置文件
|
- name: 检查配置文件
|
||||||
run: |
|
run: |
|
||||||
if [ ! -f .gitea/config/redis-schema-check-config.yaml ]; then
|
if [ ! -f .gitea/config/cache-schema-check-config.yaml ]; then
|
||||||
echo "错误: 缺少 .gitea/config/redis-schema-check-config.yaml"
|
echo "错误: 缺少 .gitea/config/cache-schema-check-config.yaml"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
# 顶层总开关 enabled: false 时跳过后续步骤(与 notify.enabled 区分,仅匹配行首)
|
# 顶层总开关 enabled: false 时跳过后续步骤(与 notify.enabled 区分,仅匹配行首)
|
||||||
if grep -Eq '^enabled:[[:space:]]*false([[:space:]]|#|$)' .gitea/config/redis-schema-check-config.yaml; then
|
if grep -Eq '^enabled:[[:space:]]*false([[:space:]]|#|$)' .gitea/config/cache-schema-check-config.yaml; then
|
||||||
echo "总开关 enabled=false,跳过 Redis 结构检查"
|
echo "总开关 enabled=false,跳过缓存结构检查"
|
||||||
touch /tmp/redis-schema-check.skip
|
touch /tmp/cache-schema-check.skip
|
||||||
fi
|
fi
|
||||||
|
|
||||||
- name: 从 Nexus 私库下载 redis-schema-checker
|
- name: 从 Nexus 私库下载 cache-schema-checker
|
||||||
run: |
|
run: |
|
||||||
if [ -f /tmp/redis-schema-check.skip ]; then
|
if [ -f /tmp/cache-schema-check.skip ]; then
|
||||||
echo "总开关已关闭,跳过下载"
|
echo "总开关已关闭,跳过下载"
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
GROUP_PATH="com/codechecker/redis-schema-checker"
|
GROUP_PATH="com/codechecker/cache-schema-checker"
|
||||||
JAR_NAME="redis-schema-checker-${REDIS_SCHEMA_CHECKER_VERSION}.jar"
|
JAR_NAME="cache-schema-checker-${CACHE_SCHEMA_CHECKER_VERSION}.jar"
|
||||||
JAR_URL="${REDIS_SCHEMA_CHECKER_REPO_URL}/${GROUP_PATH}/${REDIS_SCHEMA_CHECKER_VERSION}/${JAR_NAME}"
|
JAR_URL="${CACHE_SCHEMA_CHECKER_REPO_URL}/${GROUP_PATH}/${CACHE_SCHEMA_CHECKER_VERSION}/${JAR_NAME}"
|
||||||
JAR_PATH="/tmp/${JAR_NAME}"
|
JAR_PATH="/tmp/${JAR_NAME}"
|
||||||
|
|
||||||
echo "下载: ${JAR_URL}"
|
echo "下载: ${JAR_URL}"
|
||||||
@@ -67,15 +67,15 @@ jobs:
|
|||||||
|
|
||||||
- name: 验证 JDK
|
- name: 验证 JDK
|
||||||
run: |
|
run: |
|
||||||
if [ -f /tmp/redis-schema-check.skip ]; then
|
if [ -f /tmp/cache-schema-check.skip ]; then
|
||||||
echo "总开关已关闭,跳过"
|
echo "总开关已关闭,跳过"
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
echo "Java: $(java -version 2>&1 | head -1)"
|
echo "Java: $(java -version 2>&1 | head -1)"
|
||||||
|
|
||||||
- name: 执行 Redis 序列化结构检测
|
- name: 执行缓存序列化结构检测
|
||||||
run: |
|
run: |
|
||||||
if [ -f /tmp/redis-schema-check.skip ]; then
|
if [ -f /tmp/cache-schema-check.skip ]; then
|
||||||
echo "总开关已关闭,跳过检测"
|
echo "总开关已关闭,跳过检测"
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
@@ -88,8 +88,8 @@ jobs:
|
|||||||
|
|
||||||
COMMIT_TIME=$(git log -1 --format=%cd --date=format:'%Y-%m-%d %H:%M:%S')
|
COMMIT_TIME=$(git log -1 --format=%cd --date=format:'%Y-%m-%d %H:%M:%S')
|
||||||
|
|
||||||
java -jar "/tmp/redis-schema-checker-${REDIS_SCHEMA_CHECKER_VERSION}.jar" \
|
java -jar "/tmp/cache-schema-checker-${CACHE_SCHEMA_CHECKER_VERSION}.jar" \
|
||||||
--config .gitea/config/redis-schema-check-config.yaml \
|
--config .gitea/config/cache-schema-check-config.yaml \
|
||||||
--repo-root . \
|
--repo-root . \
|
||||||
--old-sha "$OLD_SHA" \
|
--old-sha "$OLD_SHA" \
|
||||||
--new-sha "$(git rev-parse HEAD)" \
|
--new-sha "$(git rev-parse HEAD)" \
|
||||||
4
.idea/compiler.xml
generated
4
.idea/compiler.xml
generated
@@ -6,11 +6,11 @@
|
|||||||
<sourceOutputDir name="target/generated-sources/annotations" />
|
<sourceOutputDir name="target/generated-sources/annotations" />
|
||||||
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
|
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
|
||||||
<outputRelativeToContentRoot value="true" />
|
<outputRelativeToContentRoot value="true" />
|
||||||
<module name="redis-schema-checker-parent" />
|
<module name="cache-schema-checker" />
|
||||||
</profile>
|
</profile>
|
||||||
</annotationProcessing>
|
</annotationProcessing>
|
||||||
<bytecodeTargetLevel>
|
<bytecodeTargetLevel>
|
||||||
<module name="redis-schema-checker" target="11" />
|
<module name="cache-schema-checker" target="11" />
|
||||||
</bytecodeTargetLevel>
|
</bytecodeTargetLevel>
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
2
.idea/encodings.xml
generated
2
.idea/encodings.xml
generated
@@ -1,8 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="Encoding">
|
<component name="Encoding">
|
||||||
<file url="file://$PROJECT_DIR$/redis-schema-checker/src/main/java" charset="UTF-8" />
|
|
||||||
<file url="file://$PROJECT_DIR$/redis-schema-checker/src/main/resources" charset="UTF-8" />
|
|
||||||
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
|
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
|
||||||
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
|
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
|
||||||
</component>
|
</component>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Redis 序列化结构检测 — CI 集成说明
|
# 缓存序列化结构检测 — CI 集成说明
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -11,7 +11,7 @@ Gitea Actions 触发
|
|||||||
↓
|
↓
|
||||||
浅克隆业务仓库(depth=2)
|
浅克隆业务仓库(depth=2)
|
||||||
↓
|
↓
|
||||||
从 Nexus 下载 redis-schema-checker.jar
|
从 Nexus 下载 cache-schema-checker.jar
|
||||||
↓
|
↓
|
||||||
java -jar 执行(对比 HEAD~1 与 HEAD)
|
java -jar 执行(对比 HEAD~1 与 HEAD)
|
||||||
↓
|
↓
|
||||||
@@ -28,7 +28,7 @@ mode=block 且含 P0/P1/P2 任一变更 → exit 1(流水线失败)
|
|||||||
|----|------|
|
|----|------|
|
||||||
| Gitea Runner | 标签 `jdk11`,已安装 Java 11 |
|
| Gitea Runner | 标签 `jdk11`,已安装 Java 11 |
|
||||||
| Nexus 私库 | 可访问 `http://192.168.3.25:18081/nexus/repository/maven-releases` |
|
| Nexus 私库 | 可访问 `http://192.168.3.25:18081/nexus/repository/maven-releases` |
|
||||||
| 工具 JAR | `com.codechecker:redis-schema-checker:1.0.0` 已发布 |
|
| 工具 JAR | `com.codechecker:cache-schema-checker:1.0.0` 已发布 |
|
||||||
| 仓库 Secret | `WECOM_ROBOT_WEBHOOK` 已配置 |
|
| 仓库 Secret | `WECOM_ROBOT_WEBHOOK` 已配置 |
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -41,9 +41,9 @@ mode=block 且含 P0/P1/P2 任一变更 → exit 1(流水线失败)
|
|||||||
jnpf-java-cloud/
|
jnpf-java-cloud/
|
||||||
├── .gitea/
|
├── .gitea/
|
||||||
│ ├── workflows/
|
│ ├── workflows/
|
||||||
│ │ └── redis-schema-check.yaml # 流水线
|
│ │ └── cache-schema-check.yaml # 流水线
|
||||||
│ └── config/
|
│ └── config/
|
||||||
│ └── redis-schema-check-config.yaml # 检测配置
|
│ └── cache-schema-check-config.yaml # 检测配置
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -51,19 +51,19 @@ jnpf-java-cloud/
|
|||||||
## 4. 流水线模板
|
## 4. 流水线模板
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
name: Redis序列化结构检查
|
name: 缓存序列化结构检查
|
||||||
run-name: ${{ gitea.actor }}的Redis结构检查
|
run-name: ${{ gitea.actor }}的缓存结构检查
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
env:
|
env:
|
||||||
REDIS_SCHEMA_CHECKER_VERSION: "1.0.0"
|
CACHE_SCHEMA_CHECKER_VERSION: "1.0.0"
|
||||||
REDIS_SCHEMA_CHECKER_REPO_URL: "http://192.168.3.25:18081/nexus/repository/maven-releases"
|
CACHE_SCHEMA_CHECKER_REPO_URL: "http://192.168.3.25:18081/nexus/repository/maven-releases"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
redis-schema-check:
|
cache-schema-check:
|
||||||
if: ${{ gitea.ref != 'refs/heads/pre' && gitea.ref != 'refs/heads/dev' && gitea.ref != 'refs/heads/master-2.0' }}
|
if: ${{ gitea.ref != 'refs/heads/pre' && gitea.ref != 'refs/heads/dev' && gitea.ref != 'refs/heads/master-2.0' }}
|
||||||
runs-on: jdk11
|
runs-on: jdk11
|
||||||
steps:
|
steps:
|
||||||
@@ -76,16 +76,16 @@ jobs:
|
|||||||
|
|
||||||
- name: 检查配置文件
|
- name: 检查配置文件
|
||||||
run: |
|
run: |
|
||||||
if [ ! -f .gitea/config/redis-schema-check-config.yaml ]; then
|
if [ ! -f .gitea/config/cache-schema-check-config.yaml ]; then
|
||||||
echo "错误: 缺少 .gitea/config/redis-schema-check-config.yaml"
|
echo "错误: 缺少 .gitea/config/cache-schema-check-config.yaml"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
- name: 从 Nexus 下载检测工具
|
- name: 从 Nexus 下载检测工具
|
||||||
run: |
|
run: |
|
||||||
GROUP_PATH="com/codechecker/redis-schema-checker"
|
GROUP_PATH="com/codechecker/cache-schema-checker"
|
||||||
JAR_NAME="redis-schema-checker-${REDIS_SCHEMA_CHECKER_VERSION}.jar"
|
JAR_NAME="cache-schema-checker-${CACHE_SCHEMA_CHECKER_VERSION}.jar"
|
||||||
JAR_URL="${REDIS_SCHEMA_CHECKER_REPO_URL}/${GROUP_PATH}/${REDIS_SCHEMA_CHECKER_VERSION}/${JAR_NAME}"
|
JAR_URL="${CACHE_SCHEMA_CHECKER_REPO_URL}/${GROUP_PATH}/${CACHE_SCHEMA_CHECKER_VERSION}/${JAR_NAME}"
|
||||||
JAR_PATH="/tmp/${JAR_NAME}"
|
JAR_PATH="/tmp/${JAR_NAME}"
|
||||||
|
|
||||||
echo "下载: ${JAR_URL}"
|
echo "下载: ${JAR_URL}"
|
||||||
@@ -108,7 +108,7 @@ jobs:
|
|||||||
- name: 验证 JDK
|
- name: 验证 JDK
|
||||||
run: java -version
|
run: java -version
|
||||||
|
|
||||||
- name: 执行 Redis 结构检测
|
- name: 执行 缓存结构检测
|
||||||
env:
|
env:
|
||||||
WECOM_ROBOT_WEBHOOK: ${{ secrets.WECOM_ROBOT_WEBHOOK }}
|
WECOM_ROBOT_WEBHOOK: ${{ secrets.WECOM_ROBOT_WEBHOOK }}
|
||||||
run: |
|
run: |
|
||||||
@@ -120,8 +120,8 @@ jobs:
|
|||||||
|
|
||||||
COMMIT_TIME=$(git log -1 --format=%cd --date=format:'%Y-%m-%d %H:%M:%S')
|
COMMIT_TIME=$(git log -1 --format=%cd --date=format:'%Y-%m-%d %H:%M:%S')
|
||||||
|
|
||||||
java -jar "/tmp/redis-schema-checker-${REDIS_SCHEMA_CHECKER_VERSION}.jar" \
|
java -jar "/tmp/cache-schema-checker-${CACHE_SCHEMA_CHECKER_VERSION}.jar" \
|
||||||
--config .gitea/config/redis-schema-check-config.yaml \
|
--config .gitea/config/cache-schema-check-config.yaml \
|
||||||
--repo-root . \
|
--repo-root . \
|
||||||
--old-sha "$OLD_SHA" \
|
--old-sha "$OLD_SHA" \
|
||||||
--new-sha "$(git rev-parse HEAD)" \
|
--new-sha "$(git rev-parse HEAD)" \
|
||||||
@@ -138,7 +138,7 @@ jobs:
|
|||||||
|--------|------|------|
|
|--------|------|------|
|
||||||
| `demo.yaml` (AI代码质量分析) | AI Code Review | 并行,互不影响 |
|
| `demo.yaml` (AI代码质量分析) | AI Code Review | 并行,互不影响 |
|
||||||
| `code-check` (CodeChecker) | 通用变更检测 | **同模式**,可并列执行 |
|
| `code-check` (CodeChecker) | 通用变更检测 | **同模式**,可并列执行 |
|
||||||
| `redis-schema-check` | Redis 结构检测 | 新增 |
|
| `cache-schema-check` | 缓存结构检测 | 新增 |
|
||||||
|
|
||||||
建议:三个 job 独立并行,各自 exit code 独立。
|
建议:三个 job 独立并行,各自 exit code 独立。
|
||||||
|
|
||||||
@@ -157,9 +157,9 @@ mvn clean deploy -Dnexus.deploy.enabled=true -DskipTests
|
|||||||
发布产物:
|
发布产物:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
com/codechecker/redis-schema-checker/1.0.0/
|
com/codechecker/cache-schema-checker/1.0.0/
|
||||||
├── redis-schema-checker-1.0.0.jar # 可执行 fat-jar
|
├── cache-schema-checker-1.0.0.jar # 可执行 fat-jar
|
||||||
└── redis-schema-checker-1.0.0.pom
|
└── cache-schema-checker-1.0.0.pom
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -191,8 +191,8 @@ com/codechecker/redis-schema-checker/1.0.0/
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 在 jnpf-java-cloud 根目录
|
# 在 jnpf-java-cloud 根目录
|
||||||
java -jar /path/to/redis-schema-checker-1.0.0.jar \
|
java -jar /path/to/cache-schema-checker-1.0.0.jar \
|
||||||
--config .gitea/config/redis-schema-check-config.yaml \
|
--config .gitea/config/cache-schema-check-config.yaml \
|
||||||
--repo-root . \
|
--repo-root . \
|
||||||
--old-sha HEAD~1 \
|
--old-sha HEAD~1 \
|
||||||
--new-sha HEAD \
|
--new-sha HEAD \
|
||||||
|
|||||||
46
docs/实施方案.md
46
docs/实施方案.md
@@ -1,4 +1,4 @@
|
|||||||
# Redis 序列化结构变更检测 — 实施方案
|
# 缓存序列化结构变更检测 — 实施方案
|
||||||
|
|
||||||
> 版本:v0.1
|
> 版本:v0.1
|
||||||
> 日期:2026-07-13
|
> 日期:2026-07-13
|
||||||
@@ -104,12 +104,12 @@
|
|||||||
redisCheck 仓库
|
redisCheck 仓库
|
||||||
├── 开发 Java 分析工具
|
├── 开发 Java 分析工具
|
||||||
├── mvn package 打 fat-jar
|
├── mvn package 打 fat-jar
|
||||||
├── 发布到 Nexus:com.codechecker:redis-schema-checker:{version}
|
├── 发布到 Nexus:com.codechecker:cache-schema-checker:{version}
|
||||||
└── 提供默认配置模板
|
└── 提供默认配置模板
|
||||||
|
|
||||||
jnpf-java-cloud 仓库
|
jnpf-java-cloud 仓库
|
||||||
├── .gitea/workflows/redis-schema-check.yaml
|
├── .gitea/workflows/cache-schema-check.yaml
|
||||||
├── .gitea/config/redis-schema-check-config.yaml
|
├── .gitea/config/cache-schema-check-config.yaml
|
||||||
└── push 时下载 jar 并执行检测
|
└── push 时下载 jar 并执行检测
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -119,11 +119,11 @@ jnpf-java-cloud 仓库
|
|||||||
flowchart TB
|
flowchart TB
|
||||||
subgraph Gitea["Gitea Push Pipeline"]
|
subgraph Gitea["Gitea Push Pipeline"]
|
||||||
A[push 事件] --> B[浅克隆 old/new 提交]
|
A[push 事件] --> B[浅克隆 old/new 提交]
|
||||||
B --> C[下载 redis-schema-checker.jar]
|
B --> C[下载 cache-schema-checker.jar]
|
||||||
C --> D[java -jar 执行检测]
|
C --> D[java -jar 执行检测]
|
||||||
end
|
end
|
||||||
|
|
||||||
subgraph Checker["redis-schema-checker (JDK 11)"]
|
subgraph Checker["cache-schema-checker (JDK 11)"]
|
||||||
D --> E[GitDiffScanner]
|
D --> E[GitDiffScanner]
|
||||||
E --> F[RedisWritePointDetector]
|
E --> F[RedisWritePointDetector]
|
||||||
F --> G[JavaSchemaExtractor]
|
F --> G[JavaSchemaExtractor]
|
||||||
@@ -195,8 +195,8 @@ redisCheck/
|
|||||||
│ ├── resources/fixtures/tenant/
|
│ ├── resources/fixtures/tenant/
|
||||||
│ └── java/...
|
│ └── java/...
|
||||||
├── .gitea/
|
├── .gitea/
|
||||||
│ ├── workflows/redis-schema-check.yaml
|
│ ├── workflows/cache-schema-check.yaml
|
||||||
│ └── config/redis-schema-check-config.yaml
|
│ └── config/cache-schema-check-config.yaml
|
||||||
└── target/ # 构建产物
|
└── target/ # 构建产物
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -204,11 +204,11 @@ redisCheck/
|
|||||||
|
|
||||||
```xml
|
```xml
|
||||||
<groupId>com.codechecker</groupId>
|
<groupId>com.codechecker</groupId>
|
||||||
<artifactId>redis-schema-checker</artifactId>
|
<artifactId>cache-schema-checker</artifactId>
|
||||||
<version>1.0.0-SNAPSHOT</version>
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
```
|
```
|
||||||
|
|
||||||
打包为 **shaded/fat jar**,主类:`com.codechecker.redis.cli.RedisSchemaCheckerMain`
|
打包为 **shaded/fat jar**,主类:`com.codechecker.cache.cli.CacheSchemaCheckerMain`
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -217,8 +217,8 @@ redisCheck/
|
|||||||
### 6.1 CLI 参数
|
### 6.1 CLI 参数
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
java -jar redis-schema-checker-1.0.0.jar \
|
java -jar cache-schema-checker-1.0.0.jar \
|
||||||
--config .gitea/config/redis-schema-check-config.yaml \
|
--config .gitea/config/cache-schema-check-config.yaml \
|
||||||
--repo-root /path/to/jnpf-java-cloud \
|
--repo-root /path/to/jnpf-java-cloud \
|
||||||
--old-sha abc123 \
|
--old-sha abc123 \
|
||||||
--new-sha def456 \
|
--new-sha def456 \
|
||||||
@@ -251,7 +251,7 @@ java -jar redis-schema-checker-1.0.0.jar \
|
|||||||
|
|
||||||
#### Step 1:加载配置
|
#### Step 1:加载配置
|
||||||
|
|
||||||
读取 `redis-schema-check-config.yaml`,合并默认值(见 `docs/配置说明.md`)。
|
读取 `cache-schema-check-config.yaml`,合并默认值(见 `docs/配置说明.md`)。
|
||||||
|
|
||||||
#### Step 2:Git Diff 扫描
|
#### Step 2:Git Diff 扫描
|
||||||
|
|
||||||
@@ -416,15 +416,15 @@ manual_mappings:
|
|||||||
| 层级 | 位置 | 职责 |
|
| 层级 | 位置 | 职责 |
|
||||||
|------|------|------|
|
|------|------|------|
|
||||||
| 默认配置 | 工具 jar 内 `default-config.yaml` | 检测模式、忽略规则、严重级别默认值 |
|
| 默认配置 | 工具 jar 内 `default-config.yaml` | 检测模式、忽略规则、严重级别默认值 |
|
||||||
| 业务覆盖 | `jnpf-java-cloud/.gitea/config/redis-schema-check-config.yaml` | mode、notify、include_modules、manual_mappings |
|
| 业务覆盖 | `jnpf-java-cloud/.gitea/config/cache-schema-check-config.yaml` | mode、notify、include_modules、manual_mappings |
|
||||||
|
|
||||||
合并规则:**业务配置覆盖默认配置**,未声明的项沿用默认值。
|
合并规则:**业务配置覆盖默认配置**,未声明的项沿用默认值。
|
||||||
|
|
||||||
CLI 调用:
|
CLI 调用:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
java -jar redis-schema-checker.jar \
|
java -jar cache-schema-checker.jar \
|
||||||
--config .gitea/config/redis-schema-check-config.yaml \
|
--config .gitea/config/cache-schema-check-config.yaml \
|
||||||
...
|
...
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -452,12 +452,12 @@ notify:
|
|||||||
详见 `docs/CI集成说明.md`。核心流程:
|
详见 `docs/CI集成说明.md`。核心流程:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
# jnpf-java-cloud/.gitea/workflows/redis-schema-check.yaml
|
# jnpf-java-cloud/.gitea/workflows/cache-schema-check.yaml
|
||||||
name: Redis序列化结构检查
|
name: 缓存序列化结构检查
|
||||||
on: [push]
|
on: [push]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
redis-schema-check:
|
cache-schema-check:
|
||||||
if: ${{ gitea.ref != 'refs/heads/pre' && gitea.ref != 'refs/heads/dev' && gitea.ref != 'refs/heads/master-2.0' }}
|
if: ${{ gitea.ref != 'refs/heads/pre' && gitea.ref != 'refs/heads/dev' && gitea.ref != 'refs/heads/master-2.0' }}
|
||||||
runs-on: jdk11
|
runs-on: jdk11
|
||||||
steps:
|
steps:
|
||||||
@@ -469,7 +469,7 @@ jobs:
|
|||||||
|
|
||||||
- name: 下载检测工具
|
- name: 下载检测工具
|
||||||
run: |
|
run: |
|
||||||
# 从 Nexus 下载 redis-schema-checker jar
|
# 从 Nexus 下载 cache-schema-checker jar
|
||||||
...
|
...
|
||||||
|
|
||||||
- name: 执行检测
|
- name: 执行检测
|
||||||
@@ -478,8 +478,8 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
OLD_SHA=$(git rev-parse HEAD~1 2>/dev/null || echo "")
|
OLD_SHA=$(git rev-parse HEAD~1 2>/dev/null || echo "")
|
||||||
[ -z "$OLD_SHA" ] && exit 0
|
[ -z "$OLD_SHA" ] && exit 0
|
||||||
java -jar /tmp/redis-schema-checker-1.0.0.jar \
|
java -jar /tmp/cache-schema-checker-1.0.0.jar \
|
||||||
--config .gitea/config/redis-schema-check-config.yaml \
|
--config .gitea/config/cache-schema-check-config.yaml \
|
||||||
--repo-root . \
|
--repo-root . \
|
||||||
--old-sha "$OLD_SHA" \
|
--old-sha "$OLD_SHA" \
|
||||||
--new-sha "$(git rev-parse HEAD)" \
|
--new-sha "$(git rev-parse HEAD)" \
|
||||||
@@ -578,7 +578,7 @@ jobs:
|
|||||||
| # | 决策项 | 结论 |
|
| # | 决策项 | 结论 |
|
||||||
|---|--------|------|
|
|---|--------|------|
|
||||||
| 1 | 阻断范围 | `block` 模式下 **P0/P1/P2 全部阻断**(exit 1) |
|
| 1 | 阻断范围 | `block` 模式下 **P0/P1/P2 全部阻断**(exit 1) |
|
||||||
| 2 | 发布坐标 | 独立产物 `com.codechecker:redis-schema-checker:1.0.0` |
|
| 2 | 发布坐标 | 独立产物 `com.codechecker:cache-schema-checker:1.0.0` |
|
||||||
| 3 | 配置归属 | **双层配置**:jar 内 `default-config.yaml` + 业务仓覆盖合并 |
|
| 3 | 配置归属 | **双层配置**:jar 内 `default-config.yaml` + 业务仓覆盖合并 |
|
||||||
| 4 | 上线策略 | 先 `notify` 观察 **1 周**,稳定后手动切 `block` |
|
| 4 | 上线策略 | 先 `notify` 观察 **1 周**,稳定后手动切 `block` |
|
||||||
| 5 | 检测范围 | **仅 `src/main/java`**,不扫描测试代码 |
|
| 5 | 检测范围 | **仅 `src/main/java`**,不扫描测试代码 |
|
||||||
|
|||||||
14
docs/配置说明.md
14
docs/配置说明.md
@@ -1,6 +1,6 @@
|
|||||||
# Redis 序列化结构检测 — 配置说明
|
# 缓存序列化结构检测 — 配置说明
|
||||||
|
|
||||||
> **双层配置**:工具 jar 内置 `default-config.yaml`(默认) + 业务仓库 `.gitea/config/redis-schema-check-config.yaml`(覆盖)
|
> **双层配置**:工具 jar 内置 `default-config.yaml`(默认) + 业务仓库 `.gitea/config/cache-schema-check-config.yaml`(覆盖)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
```text
|
```text
|
||||||
jar 内 default-config.yaml(工具仓维护)
|
jar 内 default-config.yaml(工具仓维护)
|
||||||
↓ 深度合并
|
↓ 深度合并
|
||||||
业务仓 redis-schema-check-config.yaml(业务仓维护)
|
业务仓 cache-schema-check-config.yaml(业务仓维护)
|
||||||
↓
|
↓
|
||||||
最终生效配置
|
最终生效配置
|
||||||
```
|
```
|
||||||
@@ -21,7 +21,7 @@ jar 内 default-config.yaml(工具仓维护)
|
|||||||
### 1.1 业务仓最小配置示例
|
### 1.1 业务仓最小配置示例
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
# jnpf-java-cloud/.gitea/config/redis-schema-check-config.yaml
|
# jnpf-java-cloud/.gitea/config/cache-schema-check-config.yaml
|
||||||
mode: notify
|
mode: notify
|
||||||
|
|
||||||
notify:
|
notify:
|
||||||
@@ -68,7 +68,7 @@ notify:
|
|||||||
# 无变更时是否也发通知(一般 false)
|
# 无变更时是否也发通知(一般 false)
|
||||||
notify_on_clean: false
|
notify_on_clean: false
|
||||||
# 消息标题前缀
|
# 消息标题前缀
|
||||||
title_prefix: "[Redis结构变更]"
|
title_prefix: "[缓存结构变更]"
|
||||||
|
|
||||||
# 忽略规则
|
# 忽略规则
|
||||||
ignore:
|
ignore:
|
||||||
@@ -173,7 +173,7 @@ mode: block
|
|||||||
| `enabled` | boolean | true | 是否发企微 |
|
| `enabled` | boolean | true | 是否发企微 |
|
||||||
| `webhook_env` | string | WECOM_ROBOT_WEBHOOK | 环境变量名 |
|
| `webhook_env` | string | WECOM_ROBOT_WEBHOOK | 环境变量名 |
|
||||||
| `notify_on_clean` | boolean | false | 无变更时是否通知 |
|
| `notify_on_clean` | boolean | false | 无变更时是否通知 |
|
||||||
| `title_prefix` | string | [Redis结构变更] | 消息标题前缀 |
|
| `title_prefix` | string | [缓存结构变更] | 消息标题前缀 |
|
||||||
|
|
||||||
### 3.4 ignore.key_patterns
|
### 3.4 ignore.key_patterns
|
||||||
|
|
||||||
@@ -238,7 +238,7 @@ suppressions:
|
|||||||
## 5. 企微消息格式示例
|
## 5. 企微消息格式示例
|
||||||
|
|
||||||
```markdown
|
```markdown
|
||||||
## [Redis结构变更] jnpf-java-cloud
|
## [缓存结构变更] jnpf-java-cloud
|
||||||
|
|
||||||
> 分支: feature/tenant-cache
|
> 分支: feature/tenant-cache
|
||||||
> 提交: a1b2c3d → e4f5g6h
|
> 提交: a1b2c3d → e4f5g6h
|
||||||
|
|||||||
10
pom.xml
10
pom.xml
@@ -5,12 +5,12 @@
|
|||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<groupId>com.codechecker</groupId>
|
<groupId>com.codechecker</groupId>
|
||||||
<artifactId>redis-schema-checker</artifactId>
|
<artifactId>cache-schema-checker</artifactId>
|
||||||
<version>1.0.0</version>
|
<version>1.0.0</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>redis-schema-checker</name>
|
<name>cache-schema-checker</name>
|
||||||
<description>基于 JavaParser 的 Redis value 序列化结构变更检测器</description>
|
<description>基于 JavaParser 的缓存 value 序列化结构变更检测器</description>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<maven.compiler.source>11</maven.compiler.source>
|
<maven.compiler.source>11</maven.compiler.source>
|
||||||
@@ -74,7 +74,7 @@
|
|||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
<finalName>redis-schema-checker-${project.version}</finalName>
|
<finalName>cache-schema-checker-${project.version}</finalName>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
@@ -101,7 +101,7 @@
|
|||||||
<transformers>
|
<transformers>
|
||||||
<transformer
|
<transformer
|
||||||
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
|
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
|
||||||
<mainClass>com.codechecker.redis.cli.RedisSchemaCheckerMain</mainClass>
|
<mainClass>com.codechecker.cache.cli.CacheSchemaCheckerMain</mainClass>
|
||||||
</transformer>
|
</transformer>
|
||||||
<transformer
|
<transformer
|
||||||
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
|
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.codechecker.redis.analyze;
|
package com.codechecker.cache.analyze;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.UncheckedIOException;
|
import java.io.UncheckedIOException;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.codechecker.redis.analyze;
|
package com.codechecker.cache.analyze;
|
||||||
|
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
@@ -1,20 +1,20 @@
|
|||||||
package com.codechecker.redis.analyze;
|
package com.codechecker.cache.analyze;
|
||||||
|
|
||||||
import com.codechecker.redis.config.CheckerConfig;
|
import com.codechecker.cache.config.CheckerConfig;
|
||||||
import com.codechecker.redis.detector.RedisWritePointDetector;
|
import com.codechecker.cache.detector.RedisWritePointDetector;
|
||||||
import com.codechecker.redis.detector.WritePoint;
|
import com.codechecker.cache.detector.WritePoint;
|
||||||
import com.codechecker.redis.diff.ChangeType;
|
import com.codechecker.cache.diff.ChangeType;
|
||||||
import com.codechecker.redis.diff.SchemaChange;
|
import com.codechecker.cache.diff.SchemaChange;
|
||||||
import com.codechecker.redis.diff.SchemaDiffer;
|
import com.codechecker.cache.diff.SchemaDiffer;
|
||||||
import com.codechecker.redis.diff.Severity;
|
import com.codechecker.cache.diff.Severity;
|
||||||
import com.codechecker.redis.git.GitDiffScanner;
|
import com.codechecker.cache.git.GitDiffScanner;
|
||||||
import com.codechecker.redis.git.GitException;
|
import com.codechecker.cache.git.GitException;
|
||||||
import com.codechecker.redis.report.CheckReport;
|
import com.codechecker.cache.report.CheckReport;
|
||||||
import com.codechecker.redis.report.KeyStructureChange;
|
import com.codechecker.cache.report.KeyStructureChange;
|
||||||
import com.codechecker.redis.schema.JavaSchemaExtractor;
|
import com.codechecker.cache.schema.JavaSchemaExtractor;
|
||||||
import com.codechecker.redis.schema.SkeletonJsonRenderer;
|
import com.codechecker.cache.schema.SkeletonJsonRenderer;
|
||||||
import com.codechecker.redis.schema.SourceIndex;
|
import com.codechecker.cache.schema.SourceIndex;
|
||||||
import com.codechecker.redis.schema.TypeSchema;
|
import com.codechecker.cache.schema.TypeSchema;
|
||||||
import com.github.javaparser.StaticJavaParser;
|
import com.github.javaparser.StaticJavaParser;
|
||||||
import com.github.javaparser.ast.CompilationUnit;
|
import com.github.javaparser.ast.CompilationUnit;
|
||||||
import com.github.javaparser.ast.body.TypeDeclaration;
|
import com.github.javaparser.ast.body.TypeDeclaration;
|
||||||
@@ -144,7 +144,7 @@ public class SchemaCheckAnalyzer {
|
|||||||
SchemaChange c = new SchemaChange(ChangeType.WRITE_POINT_ADDED);
|
SchemaChange c = new SchemaChange(ChangeType.WRITE_POINT_ADDED);
|
||||||
c.setKeyPattern(nw.getResolvedKeyPattern());
|
c.setKeyPattern(nw.getResolvedKeyPattern());
|
||||||
c.setWriteLocation(nw.location());
|
c.setWriteLocation(nw.location());
|
||||||
c.setMessage("新增 Redis 写入点,value 类型: " + shortType(nw.getResolvedValueType()));
|
c.setMessage("新增缓存写入点,value 类型: " + shortType(nw.getResolvedValueType()));
|
||||||
allChanges.add(c);
|
allChanges.add(c);
|
||||||
TypeSchema newSchema = extractorNew.extract(nw.getResolvedValueType(), nw.isRootArray());
|
TypeSchema newSchema = extractorNew.extract(nw.getResolvedValueType(), nw.isRootArray());
|
||||||
mergeKeyChange(keyChanges, nw.getResolvedKeyPattern(),
|
mergeKeyChange(keyChanges, nw.getResolvedKeyPattern(),
|
||||||
@@ -163,7 +163,7 @@ public class SchemaCheckAnalyzer {
|
|||||||
SchemaChange c = new SchemaChange(ChangeType.WRITE_POINT_REMOVED);
|
SchemaChange c = new SchemaChange(ChangeType.WRITE_POINT_REMOVED);
|
||||||
c.setKeyPattern(ow.getResolvedKeyPattern());
|
c.setKeyPattern(ow.getResolvedKeyPattern());
|
||||||
c.setWriteLocation(ow.location());
|
c.setWriteLocation(ow.location());
|
||||||
c.setMessage("删除 Redis 写入点,原 value 类型: " + shortType(ow.getResolvedValueType()));
|
c.setMessage("删除缓存写入点,原 value 类型: " + shortType(ow.getResolvedValueType()));
|
||||||
allChanges.add(c);
|
allChanges.add(c);
|
||||||
TypeSchema oldSchema = extractorOld.extract(ow.getResolvedValueType(), ow.isRootArray());
|
TypeSchema oldSchema = extractorOld.extract(ow.getResolvedValueType(), ow.isRootArray());
|
||||||
mergeKeyChange(keyChanges, ow.getResolvedKeyPattern(),
|
mergeKeyChange(keyChanges, ow.getResolvedKeyPattern(),
|
||||||
@@ -1,27 +1,26 @@
|
|||||||
package com.codechecker.redis.cli;
|
package com.codechecker.cache.cli;
|
||||||
|
|
||||||
import com.codechecker.redis.analyze.SchemaCheckAnalyzer;
|
import com.codechecker.cache.analyze.SchemaCheckAnalyzer;
|
||||||
import com.codechecker.redis.config.CheckerConfig;
|
import com.codechecker.cache.config.CheckerConfig;
|
||||||
import com.codechecker.redis.config.ConfigLoader;
|
import com.codechecker.cache.config.ConfigLoader;
|
||||||
import com.codechecker.redis.notify.WeComNotifier;
|
import com.codechecker.cache.notify.WeComNotifier;
|
||||||
import com.codechecker.redis.report.CheckReport;
|
import com.codechecker.cache.report.CheckReport;
|
||||||
import com.codechecker.redis.report.ReportBuilder;
|
import com.codechecker.cache.report.ReportBuilder;
|
||||||
import picocli.CommandLine;
|
import picocli.CommandLine;
|
||||||
import picocli.CommandLine.Command;
|
import picocli.CommandLine.Command;
|
||||||
import picocli.CommandLine.Option;
|
import picocli.CommandLine.Option;
|
||||||
|
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 命令行入口。退出码:0 通过 / 1 阻断 / 2 执行错误。
|
* 命令行入口。退出码:0 通过 / 1 阻断 / 2 执行错误。
|
||||||
*/
|
*/
|
||||||
@Command(name = "redis-schema-checker",
|
@Command(name = "cache-schema-checker",
|
||||||
mixinStandardHelpOptions = true,
|
mixinStandardHelpOptions = true,
|
||||||
version = "redis-schema-checker 1.0.0",
|
version = "cache-schema-checker 1.0.0",
|
||||||
description = "检测两次提交间 Redis value 序列化结构变更并通过企微机器人通知。")
|
description = "检测两次提交间缓存 value 序列化结构变更并通过企微机器人通知。")
|
||||||
public class RedisSchemaCheckerMain implements Callable<Integer> {
|
public class CacheSchemaCheckerMain implements Callable<Integer> {
|
||||||
|
|
||||||
@Option(names = "--config", required = true, description = "业务仓库检测配置文件路径")
|
@Option(names = "--config", required = true, description = "业务仓库检测配置文件路径")
|
||||||
private Path configPath;
|
private Path configPath;
|
||||||
@@ -56,12 +55,12 @@ public class RedisSchemaCheckerMain implements Callable<Integer> {
|
|||||||
CheckerConfig config = ConfigLoader.load(configPath);
|
CheckerConfig config = ConfigLoader.load(configPath);
|
||||||
|
|
||||||
if (!config.isEnabled()) {
|
if (!config.isEnabled()) {
|
||||||
System.out.println("[redis-schema-checker] 总开关 enabled=false,跳过检测。");
|
System.out.println("[cache-schema-checker] 总开关 enabled=false,跳过检测。");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (oldSha == null || oldSha.trim().isEmpty()) {
|
if (oldSha == null || oldSha.trim().isEmpty()) {
|
||||||
System.out.println("[redis-schema-checker] 无对比基准提交,跳过检测。");
|
System.out.println("[cache-schema-checker] 无对比基准提交,跳过检测。");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,22 +83,22 @@ public class RedisSchemaCheckerMain implements Callable<Integer> {
|
|||||||
String webhook = config.getNotify().getWebhookUrl();
|
String webhook = config.getNotify().getWebhookUrl();
|
||||||
String markdown = builder.toMarkdown(report);
|
String markdown = builder.toMarkdown(report);
|
||||||
boolean ok = new WeComNotifier().sendMarkdown(webhook, markdown);
|
boolean ok = new WeComNotifier().sendMarkdown(webhook, markdown);
|
||||||
System.out.println("[redis-schema-checker] 企微通知发送: " + (ok ? "成功" : "失败/跳过"));
|
System.out.println("[cache-schema-checker] 企微通知发送: " + (ok ? "成功" : "失败/跳过"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (report.isBlocked()) {
|
if (report.isBlocked()) {
|
||||||
System.out.println("[redis-schema-checker] block 模式命中,流水线将被阻断(exit 1)。");
|
System.out.println("[cache-schema-checker] block 模式命中,流水线将被阻断(exit 1)。");
|
||||||
}
|
}
|
||||||
return report.getExitCode();
|
return report.getExitCode();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
System.err.println("[redis-schema-checker] 执行错误: " + e.getMessage());
|
System.err.println("[cache-schema-checker] 执行错误: " + e.getMessage());
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
int exitCode = new CommandLine(new RedisSchemaCheckerMain()).execute(args);
|
int exitCode = new CommandLine(new CacheSchemaCheckerMain()).execute(args);
|
||||||
System.exit(exitCode);
|
System.exit(exitCode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.codechecker.redis.config;
|
package com.codechecker.cache.config;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
@@ -41,7 +41,7 @@ public class CheckerConfig {
|
|||||||
/** 企微机器人 Webhook 完整 URL */
|
/** 企微机器人 Webhook 完整 URL */
|
||||||
private String webhookUrl = "";
|
private String webhookUrl = "";
|
||||||
private boolean notifyOnClean = false;
|
private boolean notifyOnClean = false;
|
||||||
private String titlePrefix = "[Redis结构变更]";
|
private String titlePrefix = "[缓存结构变更]";
|
||||||
|
|
||||||
public boolean isEnabled() {
|
public boolean isEnabled() {
|
||||||
return enabled;
|
return enabled;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.codechecker.redis.config;
|
package com.codechecker.cache.config;
|
||||||
|
|
||||||
import org.yaml.snakeyaml.Yaml;
|
import org.yaml.snakeyaml.Yaml;
|
||||||
|
|
||||||
@@ -87,7 +87,7 @@ public final class ConfigLoader {
|
|||||||
n.setEnabled(bool(notify, "enabled", true));
|
n.setEnabled(bool(notify, "enabled", true));
|
||||||
n.setWebhookUrl(resolveWebhookUrl(notify));
|
n.setWebhookUrl(resolveWebhookUrl(notify));
|
||||||
n.setNotifyOnClean(bool(notify, "notify_on_clean", false));
|
n.setNotifyOnClean(bool(notify, "notify_on_clean", false));
|
||||||
n.setTitlePrefix(str(notify, "title_prefix", "[Redis结构变更]"));
|
n.setTitlePrefix(str(notify, "title_prefix", "[缓存结构变更]"));
|
||||||
|
|
||||||
Map<String, Object> ignore = asMap(map.get("ignore"));
|
Map<String, Object> ignore = asMap(map.get("ignore"));
|
||||||
CheckerConfig.Ignore ig = config.getIgnore();
|
CheckerConfig.Ignore ig = config.getIgnore();
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
package com.codechecker.redis.detector;
|
package com.codechecker.cache.detector;
|
||||||
|
|
||||||
import com.codechecker.redis.key.RedisKeyResolver;
|
import com.codechecker.cache.key.RedisKeyResolver;
|
||||||
import com.codechecker.redis.schema.SourceIndex;
|
import com.codechecker.cache.schema.SourceIndex;
|
||||||
import com.github.javaparser.StaticJavaParser;
|
import com.github.javaparser.StaticJavaParser;
|
||||||
import com.github.javaparser.ast.CompilationUnit;
|
import com.github.javaparser.ast.CompilationUnit;
|
||||||
import com.github.javaparser.ast.body.CallableDeclaration;
|
import com.github.javaparser.ast.body.CallableDeclaration;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.codechecker.redis.detector;
|
package com.codechecker.cache.detector;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 一个 Redis value 写入点的静态描述。
|
* 一个 Redis value 写入点的静态描述。
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.codechecker.redis.diff;
|
package com.codechecker.cache.diff;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 结构变更类型及其默认严重级别。
|
* 结构变更类型及其默认严重级别。
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.codechecker.redis.diff;
|
package com.codechecker.cache.diff;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 一条结构变更记录。
|
* 一条结构变更记录。
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
package com.codechecker.redis.diff;
|
package com.codechecker.cache.diff;
|
||||||
|
|
||||||
import com.codechecker.redis.schema.FieldSchema;
|
import com.codechecker.cache.schema.FieldSchema;
|
||||||
import com.codechecker.redis.schema.JsonType;
|
import com.codechecker.cache.schema.JsonType;
|
||||||
import com.codechecker.redis.schema.TypeSchema;
|
import com.codechecker.cache.schema.TypeSchema;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.codechecker.redis.diff;
|
package com.codechecker.cache.diff;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 变更严重级别。
|
* 变更严重级别。
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.codechecker.redis.git;
|
package com.codechecker.cache.git;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.codechecker.redis.git;
|
package com.codechecker.cache.git;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Git 操作异常。
|
* Git 操作异常。
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
package com.codechecker.redis.key;
|
package com.codechecker.cache.key;
|
||||||
|
|
||||||
import com.codechecker.redis.schema.SourceIndex;
|
import com.codechecker.cache.schema.SourceIndex;
|
||||||
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
|
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
|
||||||
import com.github.javaparser.ast.body.FieldDeclaration;
|
import com.github.javaparser.ast.body.FieldDeclaration;
|
||||||
import com.github.javaparser.ast.body.MethodDeclaration;
|
import com.github.javaparser.ast.body.MethodDeclaration;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.codechecker.redis.notify;
|
package com.codechecker.cache.notify;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
package com.codechecker.redis.report;
|
package com.codechecker.cache.report;
|
||||||
|
|
||||||
import com.codechecker.redis.diff.SchemaChange;
|
import com.codechecker.cache.diff.SchemaChange;
|
||||||
import com.codechecker.redis.diff.Severity;
|
import com.codechecker.cache.diff.Severity;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
package com.codechecker.redis.report;
|
package com.codechecker.cache.report;
|
||||||
|
|
||||||
import com.codechecker.redis.diff.SchemaChange;
|
import com.codechecker.cache.diff.SchemaChange;
|
||||||
import com.codechecker.redis.diff.Severity;
|
import com.codechecker.cache.diff.Severity;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
package com.codechecker.redis.report;
|
package com.codechecker.cache.report;
|
||||||
|
|
||||||
import com.codechecker.redis.diff.SchemaChange;
|
import com.codechecker.cache.diff.SchemaChange;
|
||||||
import com.codechecker.redis.diff.Severity;
|
import com.codechecker.cache.diff.Severity;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.EnumMap;
|
import java.util.EnumMap;
|
||||||
@@ -20,7 +20,7 @@ public class ReportBuilder {
|
|||||||
private final String titlePrefix;
|
private final String titlePrefix;
|
||||||
|
|
||||||
public ReportBuilder(String titlePrefix) {
|
public ReportBuilder(String titlePrefix) {
|
||||||
this.titlePrefix = titlePrefix == null ? "[Redis结构变更]" : titlePrefix;
|
this.titlePrefix = titlePrefix == null ? "[缓存结构变更]" : titlePrefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toMarkdown(CheckReport report) {
|
public String toMarkdown(CheckReport report) {
|
||||||
@@ -37,7 +37,7 @@ public class ReportBuilder {
|
|||||||
if (keys == null || keys.isEmpty()) {
|
if (keys == null || keys.isEmpty()) {
|
||||||
// 兼容仅有字段明细时退化展示
|
// 兼容仅有字段明细时退化展示
|
||||||
if (report.getChanges().isEmpty()) {
|
if (report.getChanges().isEmpty()) {
|
||||||
sb.append("未检测到 Redis 序列化结构变更。\n");
|
sb.append("未检测到缓存序列化结构变更。\n");
|
||||||
} else {
|
} else {
|
||||||
for (SchemaChange c : report.getChanges()) {
|
for (SchemaChange c : report.getChanges()) {
|
||||||
sb.append("- `").append(nvl(c.getKeyPattern())).append("`\n");
|
sb.append("- `").append(nvl(c.getKeyPattern())).append("`\n");
|
||||||
@@ -71,7 +71,7 @@ public class ReportBuilder {
|
|||||||
public String toConsole(CheckReport report) {
|
public String toConsole(CheckReport report) {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
if (!report.hasChanges()) {
|
if (!report.hasChanges()) {
|
||||||
sb.append("未检测到 Redis 序列化结构变更。\n");
|
sb.append("未检测到缓存序列化结构变更。\n");
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,8 +125,8 @@ public class ReportBuilder {
|
|||||||
+ trimmed.substring(colonEn + 1).trim();
|
+ trimmed.substring(colonEn + 1).trim();
|
||||||
}
|
}
|
||||||
String[] knownPrefixes = {
|
String[] knownPrefixes = {
|
||||||
"删除字段 ", "新增字段 ", "字段路径迁移 ", "新增包装层 ", "新增 Redis 写入点,",
|
"删除字段 ", "新增字段 ", "字段路径迁移 ", "新增包装层 ", "新增缓存写入点,",
|
||||||
"删除 Redis 写入点,原 value 类型: "
|
"删除缓存写入点,原 value 类型: "
|
||||||
};
|
};
|
||||||
for (String prefix : knownPrefixes) {
|
for (String prefix : knownPrefixes) {
|
||||||
if (trimmed.startsWith(prefix)) {
|
if (trimmed.startsWith(prefix)) {
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.codechecker.redis.schema;
|
package com.codechecker.cache.schema;
|
||||||
|
|
||||||
import com.github.javaparser.ast.body.FieldDeclaration;
|
import com.github.javaparser.ast.body.FieldDeclaration;
|
||||||
import com.github.javaparser.ast.expr.AnnotationExpr;
|
import com.github.javaparser.ast.expr.AnnotationExpr;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.codechecker.redis.schema;
|
package com.codechecker.cache.schema;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.codechecker.redis.schema;
|
package com.codechecker.cache.schema;
|
||||||
|
|
||||||
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
|
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
|
||||||
import com.github.javaparser.ast.body.FieldDeclaration;
|
import com.github.javaparser.ast.body.FieldDeclaration;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.codechecker.redis.schema;
|
package com.codechecker.cache.schema;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 序列化后 JSON 值的粗粒度类型。
|
* 序列化后 JSON 值的粗粒度类型。
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.codechecker.redis.schema;
|
package com.codechecker.cache.schema;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.codechecker.redis.schema;
|
package com.codechecker.cache.schema;
|
||||||
|
|
||||||
import com.github.javaparser.ParserConfiguration;
|
import com.github.javaparser.ParserConfiguration;
|
||||||
import com.github.javaparser.StaticJavaParser;
|
import com.github.javaparser.StaticJavaParser;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.codechecker.redis.schema;
|
package com.codechecker.cache.schema;
|
||||||
|
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
# redis-schema-checker 内置默认配置
|
# cache-schema-checker 内置默认配置
|
||||||
# 业务仓库通过 --config 指定的配置会与本文件深度合并(业务配置优先)。
|
# 业务仓库通过 --config 指定的配置会与本文件深度合并(业务配置优先)。
|
||||||
|
|
||||||
# 总开关:false 时不执行检测、不发通知、流水线直接通过
|
# 总开关:false 时不执行检测、不发通知、流水线直接通过
|
||||||
@@ -19,7 +19,7 @@ notify:
|
|||||||
enabled: true
|
enabled: true
|
||||||
webhook_url: ""
|
webhook_url: ""
|
||||||
notify_on_clean: false
|
notify_on_clean: false
|
||||||
title_prefix: "[Redis结构变更]"
|
title_prefix: "[缓存结构变更]"
|
||||||
|
|
||||||
# 忽略规则
|
# 忽略规则
|
||||||
ignore:
|
ignore:
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
package com.codechecker.redis;
|
package com.codechecker.cache;
|
||||||
|
|
||||||
import com.codechecker.redis.detector.RedisWritePointDetector;
|
import com.codechecker.cache.detector.RedisWritePointDetector;
|
||||||
import com.codechecker.redis.detector.WritePoint;
|
import com.codechecker.cache.detector.WritePoint;
|
||||||
import com.codechecker.redis.diff.ChangeType;
|
import com.codechecker.cache.diff.ChangeType;
|
||||||
import com.codechecker.redis.diff.SchemaChange;
|
import com.codechecker.cache.diff.SchemaChange;
|
||||||
import com.codechecker.redis.diff.SchemaDiffer;
|
import com.codechecker.cache.diff.SchemaDiffer;
|
||||||
import com.codechecker.redis.schema.JavaSchemaExtractor;
|
import com.codechecker.cache.schema.JavaSchemaExtractor;
|
||||||
import com.codechecker.redis.schema.SourceIndex;
|
import com.codechecker.cache.schema.SourceIndex;
|
||||||
import com.codechecker.redis.schema.TypeSchema;
|
import com.codechecker.cache.schema.TypeSchema;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.codechecker.redis;
|
package com.codechecker.cache;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.codechecker.redis.analyze;
|
package com.codechecker.cache.analyze;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.codechecker.redis.config;
|
package com.codechecker.cache.config;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
package com.codechecker.redis.diff;
|
package com.codechecker.cache.diff;
|
||||||
|
|
||||||
import com.codechecker.redis.schema.FieldSchema;
|
import com.codechecker.cache.schema.FieldSchema;
|
||||||
import com.codechecker.redis.schema.JsonType;
|
import com.codechecker.cache.schema.JsonType;
|
||||||
import com.codechecker.redis.schema.TypeSchema;
|
import com.codechecker.cache.schema.TypeSchema;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
package com.codechecker.redis.report;
|
package com.codechecker.cache.report;
|
||||||
|
|
||||||
import com.codechecker.redis.diff.ChangeType;
|
import com.codechecker.cache.diff.ChangeType;
|
||||||
import com.codechecker.redis.diff.SchemaChange;
|
import com.codechecker.cache.diff.SchemaChange;
|
||||||
import com.codechecker.redis.diff.Severity;
|
import com.codechecker.cache.diff.Severity;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
@@ -35,9 +35,9 @@ class ReportBuilderTest {
|
|||||||
key.setSeverity(Severity.P0);
|
key.setSeverity(Severity.P0);
|
||||||
report.getKeyChanges().add(key);
|
report.getKeyChanges().add(key);
|
||||||
|
|
||||||
String md = new ReportBuilder("[Redis数据结构变更]").toMarkdown(report);
|
String md = new ReportBuilder("[缓存结构变更]").toMarkdown(report);
|
||||||
|
|
||||||
assertTrue(md.startsWith("## [Redis数据结构变更] jnpf-java-cloud"));
|
assertTrue(md.startsWith("## [缓存结构变更] jnpf-java-cloud"));
|
||||||
assertTrue(md.contains("> **分支**: code/redis_change_detection_v1.0"));
|
assertTrue(md.contains("> **分支**: code/redis_change_detection_v1.0"));
|
||||||
assertTrue(md.contains("> **时间**: 2026-07-13 16:54:17"));
|
assertTrue(md.contains("> **时间**: 2026-07-13 16:54:17"));
|
||||||
assertTrue(md.contains("`tenant:db:content:*`"));
|
assertTrue(md.contains("`tenant:db:content:*`"));
|
||||||
@@ -69,7 +69,7 @@ class ReportBuilderTest {
|
|||||||
key.setNewSkeletonJson("{}");
|
key.setNewSkeletonJson("{}");
|
||||||
report.getKeyChanges().add(key);
|
report.getKeyChanges().add(key);
|
||||||
|
|
||||||
String console = new ReportBuilder("[Redis数据结构变更]").toConsole(report);
|
String console = new ReportBuilder("[缓存结构变更]").toConsole(report);
|
||||||
assertTrue(console.contains("======== 字段明细 ========"));
|
assertTrue(console.contains("======== 字段明细 ========"));
|
||||||
assertTrue(console.contains("**位置**: Foo#bar:1"));
|
assertTrue(console.contains("**位置**: Foo#bar:1"));
|
||||||
assertTrue(console.contains("**删除字段**: x"));
|
assertTrue(console.contains("**删除字段**: x"));
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
package com.codechecker.redis.schema;
|
package com.codechecker.cache.schema;
|
||||||
|
|
||||||
import com.codechecker.redis.TestSupport;
|
import com.codechecker.cache.TestSupport;
|
||||||
import com.codechecker.redis.detector.RedisWritePointDetector;
|
import com.codechecker.cache.detector.RedisWritePointDetector;
|
||||||
import com.codechecker.redis.detector.WritePoint;
|
import com.codechecker.cache.detector.WritePoint;
|
||||||
import com.codechecker.redis.diff.SchemaChange;
|
import com.codechecker.cache.diff.SchemaChange;
|
||||||
import com.codechecker.redis.diff.SchemaDiffer;
|
import com.codechecker.cache.diff.SchemaDiffer;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
Reference in New Issue
Block a user