触发
on: push · pull_request · workflow_dispatch每次推送到 main、每个 pull request,以及手动触发。两个 job 同时开始,各自运行在独立的 ubuntu-latest 上。
一个仅用 Nerviz 生成和开发的 clean-architecture-single-module 项目。每份规格、每份运行报告、每个提交都是公开的。
clean-architecture-single-module,20 分钟,构建通过。
在 GitHub 上查看 →第一份已批准的规格,每层一个分规格。
在 GitHub 上查看 →由 jobs-architect 决定使用不带 ShedLock 的 @Scheduled:删除操作会把工作分摊到各副本。
在 GitHub 上查看 →一个公开读取接口,在规格中明确记录为已接受的风险。
在 GitHub 上查看 →第一个 Kafka 生产者,带 outbox、relay 和清理。
在 GitHub 上查看 →310 个测试,0 失败,行覆盖率 96.7%,50 分钟。
在 GitHub 上查看 →一个 DELETE,匿名化客户,同时保留该行及其 id。它带来项目的第一条 security filter chain:只有 DATA_PROTECTION_OFFICER 角色可以调用。
在 GitHub 上查看 →build.yml 随 /init-project 的脚手架一起生成,此后改过两次。自 2026-10-06 起共 54 次运行:51 次通过,3 次失败。统计于 2026-10-15。
doctor gate 用它们检查了 203 个源文件每个 step 检查什么,按最近一次运行经过的顺序排列。两个 job 并行运行;任何一个 step 失败,这次推送就是红的。
on: push · pull_request · workflow_dispatch每次推送到 main、每个 pull request,以及手动触发。两个 job 同时开始,各自运行在独立的 ubuntu-latest 上。
actions/checkout · actions/setup-javafetch-depth: 0 · temurin 21 · cache: mavencheckout 拉取完整历史,Sonar 用它做 blame。Temurin 的 Java 21,并启用 Maven 缓存。
doctorjava .claude/hooks/ArchHook.java doctor gate一个独立的 job,并行运行。只要有一行受关卡约束的检查失败,doctor gate 就让构建失败:15 条边界规则、对每个源文件的禁止 import 扫描、扩展文件的 schema、由当前 ArchHook.java 构建的 hook jar,以及 hook 注册。依赖 runner 的行,例如 CLAUDE_PROJECT_DIR,会显示但从不卡住构建。
Boundaries ........ ✅ 15 active rules Boundary violations . ✅ 203 file(s) swept against 15 rule(s) Schema ............ ✅ all extension files pass Hook jar .......... ✅ built from the current .claude/hooks/ArchHook.java Hooks ............. ✅ 28 registration(s) across 12 event(s)✅ doctor gate: no gated line failed (Boundaries, Boundary violations, Schema, Hook jar, Hooks, MCP, Audit overrides).
checkstyle:check (checkstyle-validate)./mvnw -B clean verify在 validate 阶段,Checkstyle 按 config/checkstyle/checkstyle.xml 检查 src/main,即 rules/code-quality.md 中可机械检查的部分:长度、参数、复杂度、嵌套、魔法数字。一处违规即构建失败。
[INFO] You have 0 Checkstyle violations.compiler:compile · compiler:testCompile用 Java 21 编译生产代码和测试代码。JaCoCo 代理此时已挂上,用于测量接下来测试的覆盖率。
surefire:test (default-test)287 个测试,不连数据库也不连 broker。其中包括 ArchitectureTest,含 21 条 ArchUnit 规则。
[INFO] Tests run: 21, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 2.496 s -- in dev.nerviz.bankapp.ArchitectureTest[INFO] Tests run: 287, Failures: 0, Errors: 0, Skipped: 0
failsafe:integration-test (default)80 个测试,针对 Testcontainers 启动的真实容器:postgres:16-alpine 和 apache/kafka:4.1.0。GitHub 的 runner 有 Docker,所以没有一个被跳过。
Creating container for image: postgres:16-alpineCreating container for image: apache/kafka:4.1.0[INFO] Tests run: 80, Failures: 0, Errors: 0, Skipped: 0
spotless:check (spotless-check)Spotless 用 palantir-java-format 检查 src/main 和 src/test,未使用的 import 也会导致失败。它能抓到绕过格式化 hook 写入的文件。
[INFO] Spotless.Java is keeping 202 files clean - 0 needs changes to be clean, 202 were already clean, 0 were skipped because caching determined they were already cleancheckstyle:check (checkstyle-test)按 checkstyle-test.xml 检查 src/test,这是专为测试代码准备的规则集。2026-10-12 的三次失败就出在这里,两处违规由 a28934c 修复。
[INFO] You have 0 Checkstyle violations.jacoco:check (check)JaCoCo 要求整个项目 80% 的行和 70% 的分支被覆盖,启动类和配置类除外。数字来自 rules/testing.md,从不为了让构建通过而调低。
[INFO] All coverage checks have been met.[INFO] BUILD SUCCESS
integration tests actually ran一个 shell step 读取 failsafe-summary.xml。如果存在 *IT.java 却没有集成测试运行,或有测试被跳过,构建就失败:被跳过的 IT 什么也证明不了。
✅ 80 integration test(s) ran, none skipped.sonar analysis./mvnw -B sonar:sonar在 verify 之后运行,此时 JaCoCo 报告已经生成。只有存在 SONAR_TOKEN secret 时才运行,因此来自 fork 的 pull request 没有它也能通过。该 step 上传分析结果,不等待 quality gate:结果保存在 SonarQube Cloud 上。
[INFO] ANALYSIS SUCCESSFUL, you can find the results at: https://sonarcloud.io/dashboard?id=nerviz-ai_bank-app&branch=main每根柱子是一次 build.yml 运行,按运行顺序排列。高度是 Maven 报告的测试总数:单元加集成。跳升处就是各个用例。
build.yml · 修改| 时间 (UTC) | 提交 | 测试 | 耗时 | 结果 |
|---|---|---|---|---|
| 2026-10-06 15:56 | f5eaf3b chore: initial project scaffold — clean-architecture-single-module, m… | 5 (2 单元 · 3 集成) | 1m30s | ✓ 通过 |
| 2026-10-06 16:34 | 1a8432a docs: show the app starting and passing verify in the README | 5 (2 单元 · 3 集成) | 1m09s | ✓ 通过 |
| 2026-10-06 16:35 | 523bcc3 docs: show the app starting and passing verify in the README | 5 (2 单元 · 3 集成) | 1m12s | ✓ 通过 |
| 2026-10-06 16:38 | f561bb0 Merge pull request #1 from nerviz-ai/docs/readme-run-gifs | 5 (2 单元 · 3 集成) | 53s | ✓ 通过 |
| 2026-10-06 16:41 | dd2dd2b docs: describe the CI pipeline and what it covers in the README | 5 (2 单元 · 3 集成) | 57s | ✓ 通过 |
| 2026-10-06 16:48 | badb714 Merge pull request #2 from nerviz-ai/docs/readme-ci-pipeline | 5 (2 单元 · 3 集成) | 58s | ✓ 通过 |
| 2026-10-07 09:02 | 24558a5 docs(UC-001-create-customer): approved spec | 5 (2 单元 · 3 集成) | 1m02s | ✓ 通过 |
| 2026-10-07 09:08 | d62c8d4 commit audit-usage | 5 (2 单元 · 3 集成) | 1m03s | ✓ 通过 |
| 2026-10-07 10:24 | 0e74c8c feat(UC-001-create-customer): create customer with idempotent POST /a… | 113 (98 单元 · 15 集成) | 1m56s | ✓ 通过 |
| 2026-10-07 10:25 | 9861ede commit audit-usage | 113 (98 单元 · 15 集成) | 1m53s | ✓ 通过 |
| 2026-10-07 10:49 | 651b779 ci: run SonarQube Cloud analysis on nerviz-ai_bank-app | 113 (98 单元 · 15 集成) | 2m25s | ✓ 通过 |
| 2026-10-07 10:56 | 249c4fa docs: add SonarQube Cloud badges and public report link to README | 113 (98 单元 · 15 集成) | 2m20s | ✓ 通过 |
| 2026-10-07 11:06 | d7b62a3 chore(arch): adopt nerviz v0.17.8 and gate CI on doctor | 113 (98 单元 · 15 集成) | 2m17s | ✓ 通过 |
| 2026-10-07 12:33 | 31fc27c updating readme | 113 (98 单元 · 15 集成) | 1m36s | ✓ 通过 |
| 2026-10-07 20:43 | 940e578 report issue | 113 (98 单元 · 15 集成) | 2m32s | ✓ 通过 |
| 2026-10-07 23:13 | a59c52c arch-update | 113 (98 单元 · 15 集成) | 1m58s | ✓ 通过 |
| 2026-10-07 23:25 | 2da91cd arch-update | 113 (98 单元 · 15 集成) | 2m18s | ✓ 通过 |
| 2026-10-08 00:53 | 7c4e714 arch-update | 137 (117 单元 · 20 集成) | 2m11s | ✓ 通过 |
| 2026-10-08 01:06 | 1c966b0 chore: arch-update | 137 (117 单元 · 20 集成) | 2m04s | ✓ 通过 |
| 2026-10-08 08:51 | 7985d5d chore(arch): update .claude to nerviz v0.20.0 | 137 (117 单元 · 20 集成) | 2m12s | ✓ 通过 |
| 2026-10-08 11:34 | 3061f71 arch-update | 137 (117 单元 · 20 集成) | 2m08s | ✓ 通过 |
| 2026-10-08 12:00 | 6e57955 chore(arch): update .claude to nerviz v0.22.0 | 137 (117 单元 · 20 集成) | 2m10s | ✓ 通过 |
| 2026-10-08 12:24 | 0f96c8b chore: commit changes from before this run | 149 (126 单元 · 23 集成) | 2m11s | ✓ 通过 |
| 2026-10-08 12:26 | 4fae2c3 audit-usage | 149 (126 单元 · 23 集成) | 2m09s | ✓ 通过 |
| 2026-10-08 13:28 | 5068ff2 audit-usage | 149 (126 单元 · 23 集成) | 2m01s | ✓ 通过 |
| 2026-10-08 13:38 | b3c4896 build(sonar): align coverage exclusions with JaCoCo gate | 149 (126 单元 · 23 集成) | 3m06s | ✓ 通过 |
| 2026-10-08 22:14 | 71015af docs(UC-004-initiate-kyc-verification): approved spec | 149 (126 单元 · 23 集成) | 2m07s | ✓ 通过 |
| 2026-10-08 22:19 | 8be721f audit-usage | 149 (126 单元 · 23 集成) | 2m16s | ✓ 通过 |
| 2026-10-09 00:29 | 7bc5c8f feat(UC-004-initiate-kyc-verification): initiate KYC verification via… | 260 (211 单元 · 49 集成) | 2m48s | ✓ 通过 |
| 2026-10-11 13:05 | 31ff9e0 docs: bring README in line with the current build and CI | 260 (211 单元 · 49 集成) | 2m32s | ✓ 通过 |
| 2026-10-11 13:13 | 08773e6 Merge pull request #3 from nerviz-ai/docs/readme-current-state | 260 (211 单元 · 49 集成) | 2m25s | ✓ 通过 |
| 2026-10-11 15:12 | 1fcda1f audit-usage | 260 (211 单元 · 49 集成) | 2m31s | ✓ 通过 |
| 2026-10-11 15:14 | 13484e7 chore(arch): update .claude to nerviz v0.23.0 | 260 (211 单元 · 49 集成) | 2m12s | ✓ 通过 |
| 2026-10-11 23:12 | 4fe0f0d chore(arch): update .claude to nerviz v0.25.1 and apply single-module… | 260 (211 单元 · 49 集成) | 2m40s | ✓ 通过 |
| 2026-10-12 14:49 | be62511 feat(UC-005-record-kyc-verdict): record KYC verdict on customer | 294 (235 单元 · 59 集成) | 2m09s | ✕ 失败 |
| 2026-10-12 15:23 | 0079e7c audit-usage | 294 (235 单元 · 59 集成) | 2m25s | ✕ 失败 |
| 2026-10-12 16:00 | ba4f5ad gifs | 294 (235 单元 · 59 集成) | 2m36s | ✕ 失败 |
| 2026-10-12 16:06 | a28934c chore(arch): update .claude to nerviz v0.25.3 and pass stop-gate-runs… | 294 (235 单元 · 59 集成) | 2m48s | ✓ 通过 |
| 2026-10-12 21:30 | 076f6f1 chore(arch): update .claude to nerviz v0.26.0 | 294 (235 单元 · 59 集成) | 3m24s | ✓ 通过 |
| 2026-10-12 21:55 | 27e2456 chore(arch): update .claude to nerviz v0.27.0 | 294 (235 单元 · 59 集成) | 3m20s | ✓ 通过 |
| 2026-10-12 23:44 | 79fe59c chore(arch): update .claude to nerviz v0.28.0 | 294 (235 单元 · 59 集成) | 2m41s | ✓ 通过 |
| 2026-10-13 00:12 | 9423b11 docs(UC-006-anonymize-customer): approved spec | 294 (235 单元 · 59 集成) | 2m52s | ✓ 通过 |
| 2026-10-13 00:51 | d1527eb audit-usage | 294 (235 单元 · 59 集成) | 3m24s | ✓ 通过 |
| 2026-10-13 01:06 | 8e8bf56 chore(arch): update .claude to nerviz v0.29.0 | 294 (235 单元 · 59 集成) | 3m34s | ✓ 通过 |
| 2026-10-13 01:08 | 6037ed3 chore(audit-usage): remove stale report citing deleted UC-004-initiate | 294 (235 单元 · 59 集成) | 3m08s | ✓ 通过 |
| 2026-10-13 09:59 | 02c4c17 feat(UC-006-anonymize-customer): anonymize a customer via DELETE /api… | 355 (276 单元 · 79 集成) | 3m56s | ✓ 通过 |
| 2026-10-13 10:21 | 6b55699 feat(UC-006-anonymize-customer): add local Keycloak service to docker… | 355 (276 单元 · 79 集成) | 3m03s | ✓ 通过 |
| 2026-10-13 15:17 | 80564c1 build(sonar): exempt java:S4502 on SecurityConfig | 355 (276 单元 · 79 集成) | 4m09s | ✓ 通过 |
| 2026-10-13 22:14 | 45fc2bb refactor(api): move REST versioning to native API versioning | 359 (280 单元 · 79 集成) | 3m26s | ✓ 通过 |
| 2026-10-14 12:48 | eb89105 chore: update .claude to nerviz v0.34.0 and apply its migrations | 360 (281 单元 · 79 集成) | 3m16s | ✓ 通过 |
| 2026-10-14 17:37 | 7a5c534 chore: commit pending changes | 366 (287 单元 · 79 集成) | 3m17s | ✓ 通过 |
| 2026-10-14 19:58 | 3187bac chore(arch): update .claude to nerviz v0.35.0 | 366 (287 单元 · 79 集成) | 3m22s | ✓ 通过 |
| 2026-10-15 09:02 | c0047d8 chore(arch): update .claude to nerviz v0.36.0 | 366 (287 单元 · 79 集成) | 3m18s | ✓ 通过 |
| 2026-10-15 21:16 | a3cc28a chore: commit pending changes | 367 (287 单元 · 80 集成) | 3m40s | ✓ 通过 |
每次推送到 main,CI 的 sonar analysis step 都会把代码送到 SonarQube Cloud。报告是公开的:下面是实时徽章,以及最近一次分析的快照。
这些徽章在每次加载页面时由 SonarQube Cloud 绘制。SonarQube Cloud 不允许其报告嵌入其他网站的 frame,因此完整报告在其网站上打开。 2026-10-24 23:26 UTC 的分析,提交 948c8dc。
Sonar way 是 SonarQube Cloud 的默认关卡。它评判新代码,这里指上一个版本(2026-10-07)以来的全部代码,共六项条件:
new_reliability_ratingA要求 ≤ Anew_security_ratingA要求 ≤ Anew_maintainability_ratingA要求 ≤ Anew_coverage96.5%要求 ≥ 80%new_duplicated_lines_density0.0%要求 ≤ 3%new_security_hotspots_reviewed100%要求 = 100%142 个文件中共 3,946 行代码
在 CI 中,行覆盖率低于 80% 或分支覆盖率低于 70% 时,jacoco:check 会让构建失败。SonarQube Cloud 读取的是同一份 JaCoCo 报告。