目标:明确”本地 scripts/ 脚本”与”GitHub Actions”各自的职责,防止同一件事有两套做法造成漂移。 规则:凡是 Actions 已覆盖的检查,本地不再重复实现;凡是本地才有的凭据操作,Actions 不再手工模拟。
| 入口 | 触发 | 职责 | 产物/结果 |
|---|---|---|---|
| ci.yml | push/PR 到 main | 三平台(ubuntu/macOS/Windows)质量门禁:编译 + 全量测试 + Checkstyle + JaCoCo 覆盖率(≥0.90) | 门禁通过/失败 |
| codeql.yml | push/PR/定时 | GitHub CodeQL 静态安全扫描(Java) | SARIF 安全告警 |
| osv-scanner.yml | push/定时 | 第三方依赖漏洞扫描(OSV) | 漏洞告警 |
| benchmark.yml | push/PR(核心模块变更)/定时 | 性能基准门禁:JMH 跑 sure vs hutool 关键项,比率 >1.5 报警 | 基准回归报告 |
| pages.yml | push main | 构建文档站:javadoc(api/)+ 覆盖率徽章 + 文档页 | GitHub Pages 站点 |
| release.yml | 推送 v* 标签 / 手动 |
发布到 Maven Central:全量门禁 → 构建(含源码/javadoc/SBOM)→ GPG 签名 → Central Portal 上传 → 轮询 repo1 → 创建 GitHub Release | Central 制品 + Release |
| scripts/release.ps1 | 本地手动(Windows) | 备选发布通道:本地 GPG 签名 + 本地 ~/.m2/settings.xml 凭据 → deploy 到 OSSRH | Central 制品 |
mvn -pl sure-core verify(等价于 ci.yml 的 ubuntu 单机部分),不新建本地检查脚本。release.yml,推送 vX.Y.Z 标签即触发。签名与凭据放在仓库 Secrets(GPG_PRIVATE_KEY/GPG_PASSPHRASE/SONATYPE_USERNAME/SONATYPE_PASSWORD),不在任何仓库文件中。scripts/release.ps1,适用于 CI 不可用/密钥不便上云的场景。前置条件:~/.m2/settings.xml(ossrh server + gpg.keyname)+ 本机 GPG 密钥。pages.yml 全自动构建并部署 javadoc 与覆盖率徽章;本地不手工维护 _site/ 或 api/ 目录。release.yml 或 scripts/release.ps1 时,需同步更新 docs/RELEASING.md 与 docs/ci-workflow.md。docs/versioning.md 的流程:mvn versions:set → CHANGELOG → 打 v* 标签 → push(触发 release.yml)。| 现象 | 排查入口 |
|---|---|
| CI 失败 | Actions 对应 workflow 日志;本地 mvn -pl <模块> verify 复现 |
| 覆盖率门禁失败 | 本地 jacoco 报告 target/site/jacoco/,补测试后重跑 |
| 发布失败(Actions) | Secrets 是否配置齐全;GPG key 是否与本地一致;版本号是否已发布过 |
| 发布失败(本地) | ~/.m2/settings.xml 凭据与 GPG 配置;scripts/release.ps1 -DryRun 演练 |
| 文档站不更新 | pages.yml 是否成功;pages 分支/目录设置是否正确 |
benchmark.yml(job: benchmark-gate)按以下顺序执行:
mvn -pl sure-benchmark -am package,显式选取 shade fat jar(排除 original-* 残留,避免通配符多匹配导致 java -jar 选错)。java -jar "$JAR" 输出到 /tmp/bench.log。benchmark_gate.py /tmp/bench.log 解析 sure/hutool 配对,ratio = sure/hutool > 1.5 判 FAIL;日志含 JMH <failure 标记时立即 FAIL(诚实门禁,防静默漏判)。Format 项 ratio 虚高(历史出现 1.84 / 2.69,均判 FAIL),其余项 PASS。# 本机若默认 JDK 不是 21,先切到 JDK 25(否则报 UnsupportedClassVersionError)
export JAVA_HOME=<jdk25 路径>; export PATH=$JAVA_HOME/bin:$PATH
mvn -B -pl sure-benchmark -am package -DskipTests
java -jar sure-benchmark/target/sure-benchmark-<version>-jar-with-dependencies.jar # 全量
java -jar sure-benchmark/target/sure-benchmark-<version>-jar-with-dependencies.jar ".*DateUtilBenchmark.*" # 单类
python3 .github/scripts/benchmark_gate.py /tmp/bench.log # 本地跑 gate
sure-core/**、sure-json/**、sure-benchmark/**、pom.xml、.github/workflows/benchmark.yml、.github/scripts/benchmark_gate.py —— workflow/脚本自身变更也会自动触发,无需手动 dispatch。schedule: 0 5 * * 1(每周一 05:00 UTC)与 workflow_dispatch 兜底。_site 属主为 root,后续写入 Permission denied。actions/jekyll-build-pages@v1 在容器内以 root 构建,生成的 _site/ 属主为 root;紧接着在同一 job 里 mkdir -p _site/api 会报 Permission denied,导致 pages 部署连续失败(站点停留在更早的成功构建,新增文档 404)。
_site 前先 sudo chmod -R a+rwX _site 解锁。mvn -B javadoc:aggregate 输出到 target/reports/apidocs,本地 Maven 输出到 target/site/apidocs(插件 3.6.3 默认 site,runner 环境差异导致)。cp -r target/site/apidocs/. _site/api/ 在 CI 上报 No such file or directory。
APIDOCS=$(find target -maxdepth 4 -type d -name apidocs 2>/dev/null | head -1)
[ -n "$APIDOCS" ] || { echo "未找到聚合 javadoc 产物"; exit 1; }
cp -r "$APIDOCS/." _site/api/
\\\\<dependency>、\ ),GitHub Pages 首页由 jekyll-readme-index 渲染 README.md,导致首页代码块显示乱码。修复 = 清理 README.md 代码块内全部反斜杠转义(保留徽章 URL 的合法 \&)。