ci: wire openapi diff workflow at root
This commit is contained in:
parent
984c6db583
commit
c66d2b9b82
@ -28,7 +28,7 @@
|
||||
|---|---|---|
|
||||
| [`rules/verification-and-anti-false-green.md`](rules/verification-and-anti-false-green.md) | ✅ | **脊柱规则**:完成=机械验证、机械门禁优先、反假绿(P0 已落地首批门禁) |
|
||||
| [`rules/bc-boundaries.md`](rules/bc-boundaries.md) | ✅ | BC 边界:禁跨域 .dal 直连,ArchUnit 机械约束(已知违例 ContentMuseWorkOwnerFacade 单点登记整改) |
|
||||
| [`rules/contract-first.md`](rules/contract-first.md) | ✅ | 契约先行:API=`docs/api-contracts/*`、DB=`sql/muse/V*` **原地 SSOT**;Flyway 卫生 + OpenAPI 结构 机械门禁(openapi-diff CI 待启用) |
|
||||
| [`rules/contract-first.md`](rules/contract-first.md) | ✅ | 契约先行:API=`docs/api-contracts/*`、DB=`sql/muse/V*` **原地 SSOT**;Flyway 卫生 + OpenAPI 结构 机械门禁(openapi-diff 已接 root workflow,远端首跑待确认) |
|
||||
| `rules/engineering-conventions.md` | ⏳ | 命名/分层/错误码/提交/PR(收敛 `docs/dev-baseline/global/01,02`) |
|
||||
| `rules/security-and-reliability.md` | ⏳ | 安全/幂等/超时重试/可观测(收敛 `docs/dev-baseline/global/05,06`) |
|
||||
|
||||
|
||||
@ -113,7 +113,7 @@ curl -s --noproxy '*' -X POST -H "Authorization: Bearer test1" -H "tenant-id: 1"
|
||||
|
||||
## 七、本地验证 openapi-diff 破坏性变更门禁(2026-06-17 实证)
|
||||
|
||||
`muse-cloud/.github/workflows/openapi-diff.yml` 用 `docker run tufin/oasdiff:v1.19.1` 在 PR 上逐域比对 base/head 契约;本地无 Docker/GHA 无法整跑,但 oasdiff 是 Go 工具,可 `go install` 同款版本验证「检测逻辑 + 逐域循环聚合」。
|
||||
`.github/workflows/openapi-diff.yml` 用 `docker run tufin/oasdiff:v1.19.1` 在 PR 上逐域比对 base/head 契约;本地无 Docker/GHA 无法整跑,但 oasdiff 是 Go 工具,可 `go install` 同款版本验证「检测逻辑 + 逐域循环聚合」。2026-06-19 已从 `muse-cloud/.github/workflows/` 移到仓库根,否则自建 Gitea Actions 不会扫描触发。
|
||||
|
||||
```bash
|
||||
# 一键复现(自举 oasdiff@v1.19.1 + 临时 venv 装 pyyaml,零全局污染;~首次 go install 稍慢)
|
||||
@ -125,4 +125,4 @@ bash muse-cloud/scripts/verify-openapi-diff.sh # → 5 场景全绿即门禁
|
||||
- **坑3:go install 自报 "version main"** 属正常——release ldflags 仅官方构建注入,源码默认 `version=main`;二进制行为仍是所钉 tag 的。
|
||||
- **坑4:跨文件 `$ref` 靠目录结构**:events 契约 `$ref: '../openapi-base.yaml'`,故 base/head 必须各自保留 `docs/api-contracts/` 完整目录(workflow 用 `git worktree` 检出整树、脚本用 `cp -R` 整目录),单独拷 `openapi.yaml` 会解析失败。
|
||||
- 实证(oasdiff v1.19.1,全部 7 域真实契约,5/5):无变更/新增可选参数/新增端点→**放行**(rc=0);参数变必填(`request-parameter-became-required`)/删端点(`api-path-removed-without-deprecation`)→**拦截**(rc=1)。
|
||||
- **残留(脚本覆盖不到)**:GHA 触发管道(`pull_request` paths 触发、`base.sha` worktree、docker 镜像拉取)须一次真实 PR(改 `docs/api-contracts/**`)首跑确认。未首跑前不得宣称"CI 已实拦破坏性变更",只能称"检测逻辑+循环逻辑已本地实证"。
|
||||
- **残留(脚本覆盖不到)**:远端 Gitea Actions 触发管道(`pull_request` paths 触发、`base.sha` worktree、docker 镜像拉取)须一次真实 PR(改 `docs/api-contracts/**`)首跑确认。未首跑前不得宣称"CI 已实拦破坏性变更",只能称"检测逻辑+循环逻辑已本地实证、root workflow 已接线"。
|
||||
|
||||
@ -36,14 +36,14 @@
|
||||
|
||||
---
|
||||
|
||||
## 四、加固:openapi-diff 破坏性变更检测(CI 级,已 materialize / 检测逻辑已本地实证 / GHA 触发待首跑)
|
||||
## 四、加固:openapi-diff 破坏性变更检测(CI 级,仓库根 workflow 已接线 / 检测逻辑已本地实证 / 远端首跑待确认)
|
||||
|
||||
存在性/结构门禁挡不住“悄悄改坏既有契约语义”(删字段、改必填、改类型)。**破坏性变更检测**用 `oasdiff` 在 PR 上比对 base 分支与 PR 的 OpenAPI,发现破坏性差异即红。
|
||||
**已落地为独立 workflow** [`muse-cloud/.github/workflows/openapi-diff.yml`](../../muse-cloud/.github/workflows/openapi-diff.yml)(PR 改 `docs/api-contracts/**` 时触发,逐域 `oasdiff breaking ... --fail-on ERR`,镜像钉 `tufin/oasdiff:v1.19.1`)。workflow 即 SSOT,此处**不复制 YAML**(避免双源漂移)。
|
||||
**已落地为独立 workflow** [`.github/workflows/openapi-diff.yml`](../../.github/workflows/openapi-diff.yml)(PR 改 `docs/api-contracts/**` 时触发,逐域 `oasdiff breaking ... --fail-on ERR`,镜像钉 `tufin/oasdiff:v1.19.1`)。workflow 即 SSOT,此处**不复制 YAML**(避免双源漂移)。2026-06-19 已从 `muse-cloud/.github/workflows/` 移到仓库根,因为自建 Gitea Actions 只扫描仓库根 `.github/workflows/`。
|
||||
|
||||
**检测逻辑 + 逐域循环聚合:已本地实证**(2026-06-17,oasdiff v1.19.1)。复现脚本 [`muse-cloud/scripts/verify-openapi-diff.sh`](../../muse-cloud/scripts/verify-openapi-diff.sh) 忠实复刻 workflow 循环,对全部 7 域真实契约跑 5 场景全绿:无变更/新增可选参数/新增端点→放行;参数变必填(`request-parameter-became-required`)/删端点(`api-path-removed-without-deprecation`)→拦截。坑与配方见 [knowledge §七](../knowledge/external-deps-and-gotchas.md)。
|
||||
|
||||
> ⚠️ **残留**:GitHub Actions 触发管道(`pull_request` paths 触发、`base.sha` worktree、docker 镜像拉取)须一次真实 PR(改 `docs/api-contracts/**`)首跑确认。**首跑前**:可宣称"破坏性变更检测逻辑已本地实证(对真实契约拦真破坏、放行安全演化)",但**不得**宣称"CI 已在线上实拦"。
|
||||
> ⚠️ **残留**:远端 Gitea Actions 触发管道(`pull_request` paths 触发、`base.sha` worktree、docker 镜像拉取)须一次真实 PR(改 `docs/api-contracts/**`)首跑确认。**首跑前**:可宣称"破坏性变更检测逻辑已本地实证(对真实契约拦真破坏、放行安全演化),root workflow 已接线",但**不得**宣称"CI 已在线上实拦"。
|
||||
|
||||
---
|
||||
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
# OpenAPI 破坏性变更门禁(契约先行加固)
|
||||
# 仅在 PR 改动 docs/api-contracts/** 时触发;逐域用 oasdiff 比对 base 与 PR 的 OpenAPI,发现破坏性差异即失败。
|
||||
# 注:独立于主 maven 构建,避免误配影响主门禁。
|
||||
# 注:本文件必须位于仓库根 .github/workflows/ 下;自建 Gitea Actions 不扫描 muse-cloud/.github/workflows/。
|
||||
# 镜像钉版本 tufin/oasdiff:v1.19.1(机械门禁须可复现,避免 :latest 漂移改变判定口径)。
|
||||
# 检测逻辑已本地验证(2026-06-17,oasdiff v1.19.1 对全部 7 域真实契约 5/5:无变更/新增可选参数/新增端点→放行,
|
||||
# 参数变必填/删端点→拦截;复现脚本见 .agents/knowledge §七)。**残留:GitHub Actions 触发管道(PR paths 触发 +
|
||||
# base.sha worktree + docker run)需一次真实 PR(改 docs/api-contracts/**)首跑确认。**
|
||||
# 参数变必填/删端点→拦截;复现脚本见 .agents/knowledge §七)。残留:远端 Gitea Actions 首次 PR 触发、base.sha
|
||||
# worktree 与 docker run 仍需一次真实 PR(改 docs/api-contracts/**)确认。
|
||||
name: OpenAPI Breaking Change Check
|
||||
|
||||
on:
|
||||
@ -25,7 +25,7 @@
|
||||
|
||||
**本仓是 monorepo,物理承载实现代码,不是"纯设计文档仓"。**
|
||||
|
||||
- `git ls-files muse-cloud` = 4468 文件、无 `.gitmodules` → `muse-cloud/`、`muse-admin/`、`muse-studio/` 三个实现仓代码**就在本工作树里、被本仓版本控制**;CI 在 `muse-cloud/.github/workflows/`。
|
||||
- `git ls-files muse-cloud` = 4468 文件、无 `.gitmodules` → `muse-cloud/`、`muse-admin/`、`muse-studio/` 三个实现仓代码**就在本工作树里、被本仓版本控制**;既有 Maven CI 在 `muse-cloud/.github/workflows/`,OpenAPI diff 因自建 Gitea Actions 扫描规则已接到仓库根 `.github/workflows/`。
|
||||
- 因此:**agent 可以也应当修改这些实现代码**(遵循各自规范 + [`.agents/rules/`](.agents/rules/))。此前"本仓不承载代码/CI"的描述与磁盘矛盾,会让 agent 误判改动边界、绕路产生文档 churn,已订正。
|
||||
- `design-docs/`、`docs/` 是设计/规格 SSOT;实现代码须反向对齐其正式文档。
|
||||
|
||||
@ -67,7 +67,7 @@ oh-my-muse/
|
||||
1. **读后动手**:复杂任务先读 [`.agents/`](.agents/) 与相关 `docs/`,对齐事实再开工。
|
||||
2. **机械门禁优先 / 完成=验证**:遵守 [`verification-and-anti-false-green`](.agents/rules/verification-and-anti-false-green.md)——无自动化绿证据不得声称完成;新规则必配机械门禁,不靠自觉。
|
||||
3. **复杂/高危先评审**:跨模块 / 改用户可见行为 / 触外部服务·支付·数据 → 评审版 → 两轮评审 → 执行版,再写代码。
|
||||
4. **契约先行**:改接口/数据结构先改契约(API=`docs/api-contracts/*`、DB=新增 `sql/muse/V*.sql`,均为原地 SSOT)再实现;遵守 [`contract-first`](.agents/rules/contract-first.md),已有 Flyway 卫生 + OpenAPI 结构机械门禁(openapi-diff 待启用)。
|
||||
4. **契约先行**:改接口/数据结构先改契约(API=`docs/api-contracts/*`、DB=新增 `sql/muse/V*.sql`,均为原地 SSOT)再实现;遵守 [`contract-first`](.agents/rules/contract-first.md),已有 Flyway 卫生 + OpenAPI 结构机械门禁(openapi-diff 已接 root workflow,远端首跑待确认)。
|
||||
5. **最小改动 + 中文注释**:只动相关代码,复用既有模式,不顺手重构;代码全简体中文注释,关键路径可追溯日志。
|
||||
6. **无孤儿/拼接设计**:任何新结构/接口/模型须带入口、使用路径、失败路径、验收标准。
|
||||
7. **证据规则**:区分已验证事实/推断/假设;无证据不声称"完成/修复/通过"。
|
||||
@ -91,9 +91,9 @@ oh-my-muse/
|
||||
- ✅ 机械门禁地基:CI 真跑测试(JDK21、触发分支已修为 `main`——此前误配 `master` 致 CI 从不运行)、门禁去硬编码(含分域计数派生化)、P0 冻结令。
|
||||
- ✅ 入口与中枢骨架:本文件 + `.agents/README.md` + 脊柱规则。
|
||||
- ✅ BC 边界 ArchUnit 门([`bc-boundaries`](.agents/rules/bc-boundaries.md)):**通用覆盖全业务 BC 间方向**;AI/knowledge 直连 content、market 直写 member 三处违例**均已整改消除**,豁免清单 `KNOWN_VIOLATION_EXEMPTIONS` **清空 → 全绿**(0 Architecture Violation;遗留:market-server pom 仍依赖 member-server,仅消除了 .dal 代码 import,见该规则 §三)。
|
||||
- ✅ 契约先行门([`contract-first`](.agents/rules/contract-first.md)):Flyway 迁移卫生 + OpenAPI **存在性/结构**(注:挡不住语义破坏;openapi-diff CI 已materialize,需首次 CI 运行验证)。
|
||||
- ✅ 契约先行门([`contract-first`](.agents/rules/contract-first.md)):Flyway 迁移卫生 + OpenAPI **存在性/结构**(注:挡不住语义破坏;openapi-diff root workflow 已接线,需远端首次 PR 运行验证)。
|
||||
- ✅ loop 机械牙([`AgentsInfraIntegrityTest`](muse-cloud/muse-server/src/test/java/cn/iocoder/muse/server/framework/arch/AgentsInfraIntegrityTest.java)):每业务 BC 有 `.agent`、README 索引每篇 `.agents` 文档、总账在——把写回/索引同步从自觉变机械。
|
||||
- ✅ knowledge 蒸馏 / skills / workflow(AI 开发协议)/ 进度总账 + 7 BC `.agent`。
|
||||
- ⏳ 后续:openapi-diff CI 首跑验证、`dev-baseline` 收敛进 rules、Meta/schema 投影真实化、前端深页继续关 MSW 活体验收。`completed=测试证据`兜底(testFiles)、跨域 `.application` 边界、market-server→member-server pom 坐标收口、ai/平台预存红测试整改均已完成。
|
||||
- ⏳ 后续:openapi-diff 远端 CI 首跑验证、`dev-baseline` 收敛进 rules、Meta/schema 投影真实化、前端深页继续关 MSW 活体验收。`completed=测试证据`兜底(testFiles)、跨域 `.application` 边界、market-server→member-server pom 坐标收口、ai/平台预存红测试整改均已完成。
|
||||
|
||||
> 进度只进 [`docs/mvp/进度总账.md`](docs/mvp/进度总账.md) + 各模块 `.agent`,不新增状态过程文档。
|
||||
|
||||
@ -9,9 +9,9 @@
|
||||
|
||||
| 砖 | 内容 | 状态 | 机械证据 / 落点 |
|
||||
|---|---|---|---|
|
||||
| P0 | CI 真跑测试(JDK21、去 `-Dmaven.test.skip`)+ 覆盖台账去硬编码 + P0 冻结令 | ✅ | `.github/workflows/maven.yml`、`P1rApiCoverageReportTest`、[脊柱规则](../../.agents/rules/verification-and-anti-false-green.md) |
|
||||
| P0 | CI 真跑测试(JDK21、去 `-Dmaven.test.skip`)+ 覆盖台账去硬编码 + P0 冻结令 | ✅ | `muse-cloud/.github/workflows/maven.yml`、`P1rApiCoverageReportTest`、[脊柱规则](../../.agents/rules/verification-and-anti-false-green.md) |
|
||||
| ① | BC 边界 ArchUnit 门——**通用覆盖全业务 BC 间方向** | ✅ **全绿**(AI/knowledge/market 三处直连他域 DAL 违例均已整改,豁免清单清空) | `BcBoundaryArchTest`(1/0F,0 Architecture Violation,`KNOWN_VIOLATION_EXEMPTIONS`=空);[bc-boundaries](../../.agents/rules/bc-boundaries.md) §三 |
|
||||
| ② | 契约先行门(Flyway 迁移卫生 + OpenAPI **存在性/结构**) | ✅ 绿;语义破坏由 openapi-diff 补强——**检测逻辑已本地实证**(2026-06-17,oasdiff v1.19.1,7 域真实契约 5/5),GHA 触发管道未接线(诊断见 §一 TODO;`mvn -B package` 已本地实证绿) | `ContractFirstGateTest`(2/0F);[openapi-diff.yml](../../muse-cloud/.github/workflows/openapi-diff.yml)+[verify 脚本](../../muse-cloud/scripts/verify-openapi-diff.sh);[contract-first](../../.agents/rules/contract-first.md) §四 |
|
||||
| ② | 契约先行门(Flyway 迁移卫生 + OpenAPI **存在性/结构**) | ✅ 绿;语义破坏由 openapi-diff 补强——**检测逻辑已本地实证**(2026-06-17,oasdiff v1.19.1,7 域真实契约 5/5),root workflow 已接线,远端 Gitea Actions 首跑待确认 | `ContractFirstGateTest`(2/0F);[openapi-diff.yml](../../.github/workflows/openapi-diff.yml)+[verify 脚本](../../muse-cloud/scripts/verify-openapi-diff.sh);[contract-first](../../.agents/rules/contract-first.md) §四 |
|
||||
| ⑦ | loop 机械牙 + CI 接电(round-2) | ✅ 绿 | `AgentsInfraIntegrityTest`(3/0F);`maven.yml` 触发分支修为 `main` |
|
||||
| ③ | knowledge 蒸馏(定位架构 / 现状基线指针 / 决策) | ✅ | [`.agents/knowledge/`](../../.agents/knowledge/) |
|
||||
| ④ | skills(黄金旅程“完成”定义 / 新增 BC 模块) | ✅ | [`.agents/skills/`](../../.agents/skills/) |
|
||||
@ -22,7 +22,7 @@
|
||||
|
||||
**market 写路径整改(2026-06-14,ultracode)**:member 暴露写端口 `MuseAccountRecordProjectionApi` + DTO(member-server 实现读写自有 DAL、tenantId 由实现侧从上下文注入防伪造、事务沿用调用方),market 5 类改消费端口、移除 member.dal 依赖 → `KNOWN_VIOLATION_EXEMPTIONS` 清空、BC 门全绿。**附带修复**:round-2 重构 `ContentKnowledgeWorkOwnerFacade` 时遗留的旧测试 `KnowledgeWorkOwnerFacadeTest`(仍断言旧 WorkMapper 行为)已删除,其装配守卫/兜底两用例并入 `ContentKnowledgeWorkOwnerFacadeTest`(5/0F)——此为 round-2 一处假绿(当时构建在平台时区用例处中止、未真正跑到 knowledge),现已补正。
|
||||
|
||||
**后续基建 TODO**:openapi-diff CI 首跑验证(🔧 检测逻辑+循环聚合已本地实证 2026-06-17:oasdiff v1.19.1 对 7 域真实契约 5/5 拦真破坏/放行安全演化,镜像钉版本+复现脚本已落地;**仅余 GHA 触发管道未接线**——诊断 2026-06-17:maven.yml 在 `muse-cloud/.github/workflows/`、**仓库根无 `.github/workflows/`**、remote 是**自建 Gitea**(`101.200.34.71:2222` 非 github.com),GHA/Gitea-Actions 只读仓库根 `.github/workflows/`,故 monorepo 层级**不触发**(真 PR 也不会跑);需 workflow 移到仓库根[带路径过滤分 muse-cloud/admin/studio]或 muse-cloud 单独成库,并确认 Gitea Actions 已启。**`mvn -B package`[CI 确切命令]已本地实证全绿(2026-06-17,全 reactor 单测 + 打包步骤),接线后即应绿**——属基建接线决策,留人类)、`dev-baseline` 收敛进 rules。✅ 已完成项:`completed=测试证据`兜底(2026-06-19:coverage JSON 增 `testFiles`;生成器 `--check` + `P1rApiCoverageReportTest` 校验 completed 必须引用真实 `src/test/java` 证据文件且不得引用 coverage/gate 自身)、跨域 `.application` 边界门(2026-06-17:BcBoundaryArchTest 0 违例 + 反向证 238 例非空转)、market-server→member-server pom 坐标收口(2026-06-17:market-server 收窄至 member-api + tenant starter 直接声明)、ai/平台预存红测试整改(2026-06-15~17:三项全清)。
|
||||
**后续基建 TODO**:openapi-diff 远端 CI 首跑验证(🔧 检测逻辑+循环聚合已本地实证 2026-06-17:oasdiff v1.19.1 对 7 域真实契约 5/5 拦真破坏/放行安全演化,镜像钉版本+复现脚本已落地;2026-06-19 已把 workflow 从 `muse-cloud/.github/workflows/` 移到仓库根 `.github/workflows/`,修正自建 Gitea Actions 只扫描根 workflow 的接线问题;**仅余远端真实 PR 首跑确认**:`pull_request` paths 触发、`base.sha` worktree、docker 镜像拉取、Gitea Actions 是否已启。**`mvn -B package`[CI 确切命令]已本地实证全绿(2026-06-17,全 reactor 单测 + 打包步骤),接线后即应绿**——属远端基建首跑,留人类)、`dev-baseline` 收敛进 rules。✅ 已完成项:`completed=测试证据`兜底(2026-06-19:coverage JSON 增 `testFiles`;生成器 `--check` + `P1rApiCoverageReportTest` 校验 completed 必须引用真实 `src/test/java` 证据文件且不得引用 coverage/gate 自身)、跨域 `.application` 边界门(2026-06-17:BcBoundaryArchTest 0 违例 + 反向证 238 例非空转)、market-server→member-server pom 坐标收口(2026-06-17:market-server 收窄至 member-api + tenant starter 直接声明)、ai/平台预存红测试整改(2026-06-15~17:三项全清)。
|
||||
|
||||
**🎯 全 reactor `mvn test` 史上首次全绿(2026-06-17)**:本特性分支 30+ commit 从未 push、maven.yml 只在 push/PR-to-main 触发故 **CI 从未在本分支真跑过**,积累若干潜伏红。以 `mvn -pl muse-server -am test -fae` 全 reactor 排查,逐模块解锁(上游失败 fail-fast 会 SKIP 下游),共清 **6 处**:① market `AppMuseMarketPublishControllerTest` 9 参 `PublishRecordItem` 构造(record 自 a00c758 加 marketAssetId/appealStatus 变 10 参)② coverage 台账 33 op serviceFiles 陈旧引用(本会话 facade 移 member-api 所致)③④ knowledge/ai 的 `Content*WorkOwnerFacadeTest` 仍断言 `@ConditionalOnBean`(2026-06-14 单体修复已去除、改 @Primary)⑤ ai `MuseAiEventPublishOutboxMapperTest` 真 PG 用例无 PG 时硬 fail→改 `assumeTrue` skip(与 P1r external-acceptance env 缺失即 skip 约定一致、honest 非假绿)⑥ muse-server `P1rKnowledgeMigrationSqlTest` 元测试钉死 `TARGET_VERSION="14"`(IT 已按 4d46d7a 动态自适应)→版本无关化。**全 reactor BUILD SUCCESS、0 失败**(真 PG 类无 PG 时 skip)。教训:跨模块重构后须跑 `-fae` 全量,勿只跑改动模块。**前端 muse-studio 同步复验绿(2026-06-17:`tsc -b` 0 错误 + `vitest run` 12 文件/47 用例全过;本分支前端改动 35 文件全在 studio、admin 未动)**——故**整分支(后端 `mvn -B package` + 前端 `tsc`/`vitest`)deterministic CI 检查全绿,均本会话实证**(e2e/playwright 需活体后端+浏览器,未在本轮跑;真 PG IT 多数 2026-06-17 已人工批准且本会话变更为 import-only+单测已覆盖,未重跑)。
|
||||
|
||||
|
||||
@ -124,6 +124,33 @@ class ContractFirstGateTest {
|
||||
"缺少必备业务域 API 契约,期望包含 " + REQUIRED_API_DOMAINS + ",实际 " + foundDomains);
|
||||
}
|
||||
|
||||
/**
|
||||
* OpenAPI 破坏性变更门禁的 workflow 必须放在仓库根。
|
||||
*
|
||||
* <p>背景:本仓是 monorepo,但自建 Gitea Actions 只扫描仓库根 {@code .github/workflows/}。
|
||||
* 若 workflow 被放回 {@code muse-cloud/.github/workflows/},本地脚本仍可能绿,远端 PR 却不会触发,
|
||||
* 这会把契约语义破坏门重新变成假绿。因此这里用静态门禁锁住位置与关键配置。</p>
|
||||
*
|
||||
* @throws IOException 读取 workflow 失败时抛出
|
||||
*/
|
||||
@Test
|
||||
void openapi_diff_workflow_must_live_at_repo_root() throws IOException {
|
||||
Path root = findRepoRoot();
|
||||
Path rootWorkflow = root.resolve(".github/workflows/openapi-diff.yml");
|
||||
Path misplacedWorkflow = root.resolve("muse-cloud/.github/workflows/openapi-diff.yml");
|
||||
assertTrue(Files.exists(rootWorkflow), "openapi-diff workflow 必须位于仓库根: " + rootWorkflow);
|
||||
assertFalse(Files.exists(misplacedWorkflow),
|
||||
"openapi-diff workflow 不得放在 muse-cloud/.github/workflows/,否则 Gitea Actions 不会扫描触发: "
|
||||
+ misplacedWorkflow);
|
||||
|
||||
String workflow = Files.readString(rootWorkflow);
|
||||
assertTrue(workflow.contains("pull_request"), "openapi-diff workflow 必须由 PR 触发");
|
||||
assertTrue(workflow.contains("docs/api-contracts/**"), "openapi-diff workflow 必须只监听 API 契约变更");
|
||||
assertTrue(workflow.contains("github.event.pull_request.base.sha"), "openapi-diff workflow 必须比对 PR base sha");
|
||||
assertTrue(workflow.contains("tufin/oasdiff:v1.19.1"), "openapi-diff workflow 必须钉 oasdiff 镜像版本");
|
||||
assertTrue(workflow.contains("--fail-on ERR"), "openapi-diff workflow 必须在破坏性变更达到 ERR 时失败");
|
||||
}
|
||||
|
||||
/** 解析一份 OpenAPI 规格并校验其为含必备顶层键的 OAS3 文档(解析失败会抛异常 → 测试红,即“写坏即拦截”)。 */
|
||||
private static void assertValidOpenApi(Path spec) throws IOException {
|
||||
assertTrue(Files.exists(spec), "OpenAPI 契约文件必须存在: " + spec);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user