Files
lixi 1891d9b7b4
CI / docs-build (push) Successful in 1m3s
docs: M2 开工前分析 10 份报告入档 + ADR-009~015 拍板决策
- iteration-2 报告 01-08(PM 拆解/后端/Flutter 评估/现实核查/UI 规范/埋点规划/证据基线/Git 规划),04、06 已由正式角色复核定稿
- mkdocs 挂「第二迭代」导航,build --strict 通过
- ADR-009 新建 patbond-pet 模块、ADR-010 照片剪出 M2、ADR-011 dev 主干/master 发布、ADR-012 北极星与 H1-H4、ADR-013 废弃 health_record_action、ADR-014 DEBT-1 随 M2、ADR-015 照护人邀请后置

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-07 13:54:35 +08:00

11 KiB
Raw Permalink Blame History

08 M2 Git 与 CI 工作流规划

  • 执行人:Git Workflow Master
  • 日期:2026-09-07
  • 范围:第二迭代(M2 宠物健康档案)开工前的三仓状态核查、分支/提交策略、CI 扩展与防泄漏规划。本报告只核查与规划,未改动任何代码、工作流或 mkdocs.yml。

1. 三仓当前状态核查(2026-09-07 实测)

仓库 分支 相对 origin 工作区 stash 最新提交 CI 状态
patbond-api dev 同步(fetch 后确认) 干净 success0d81c38CI / backend-testrun 6
patbond-flutter dev 同步 干净 success3f8388eCI / flutter-gatesrun 11
patbond-doc main 同步 干净 success5537f92CI / docs-build

CI 状态经 Gitea commit status API 逐仓核实,非转述。

未提交内容清单:无。 第一迭代「三仓改动长期未 commit」的教训在收官阶段已彻底闭环——包括上次报告中留给用户自决的 patbond-flutter README.md 也已入库。唯一例外是本报告文件本身(写入 patbond-doc 后为未跟踪状态),按第 3 节波次规则随下一波提交。

两处非阻塞的历史遗留(可选清理,待拍板):

  • patbond-api 本地 master 分支(ff876bc)的上游 origin/master 已在远端删除(branch -vv 显示「丢失」)。本地分支可删:git branch -D master(确认无独有提交后执行;ff876bc 是初始 README 提交,早已被 dev 包含的话可安全删除,删前用 git merge-base --is-ancestor ff876bc dev 核实)。
  • patbond-flutter 本地 main030b11f)与远端 origin/main 均落后于 dev。dev 是事实集成分支,main 处于闲置态。M2 不动它;若未来引入「main = 可发布」语义(见 2.3),届时再统一处理。

2. M2 分支与提交策略

2.1 现状评估

第一迭代的 trunk-based 小步直推 devdoc 直推 main)配合本地门禁运转良好:历史线性、无合并冲突、每个提交自带验收证据。但当时 CI 尚未上线,「门禁不绿不提交」全靠自觉;现在三仓 CI 已在 push 时执行同一套门禁,且三个 ci.yml 均已配置 pull_request: 触发器——PR 合入前门禁是零成本就绪的,只差用不用。

2.2 推荐方案(待拍板):trunk-based 为主 + 高风险改动走 PR

两人 + AI 辅助的协作模式下,日常改动走 PR 的评审收益低、流程开销高,不推荐全面切换。推荐分层:

  • 日常改动(单波次内可完成、不动 schema、不动跨仓契约):继续小步直推 devdoc 直推 main)。CI 在 push 后兜底,红了立即修——两人团队里一个红提交的传播面可控。
  • 高风险改动强制走短命分支 + Gitea PR,合入前 CI 必须绿。触发条件(满足其一):
    1. 新增/变更 Flyway 迁移(M2 的宠物健康档案必然新增 V3__*.sql,首当其冲);
    2. 跨仓契约变更(openapi.yaml 的破坏性修改);
    3. 依赖升级、大规模重构;
    4. 两人同时改同一仓库的并行期。
  • 分支命名沿用规范:feat/<主题>fix/<主题>(如 feat/pet-health-schema),合入后即删,不留长期分叉。
  • 个人分支整理历史用 git push --force-with-lease;共享分支(dev/main)依旧禁止 force push、禁止改写已推送历史。

选择理由:这是对现行 git-workflow.md 第 9 行「何时开 feature 分支」条款的最小延伸——把「破坏性风险」具体化为可判定的清单,并利用已就绪的 PR 触发器让 CI 在合入前把关,而不是引入一套全新流程。

配套(可选,待拍板):在 Gitea 仓库设置中为 dev/main 开启分支保护,勾选「合并前需状态检查通过」并选中 CI 上下文。两人团队可以不开(靠约定),开了则规则由平台强制执行,AI 辅助开发场景下多一道机械防线。

2.3 暂不引入的东西

  • 不引入 Git Flow / develop-release 双轨——没有版本化发布压力,dev 单集成分支足够。
  • 不引入 main 发布分支语义——等 M3 有部署目标后再议。

3. M2 提交节奏规范

3.1 波次即提交(第一迭代教训的制度化)

  • 每个波次收尾时,三仓凡有改动必须 commit 并 push,push 后确认 CI 绿,才算波次闭环。 波次报告中记录各仓提交哈希与 CI 结论(沿用第一迭代收官报告的做法)。
  • 波次中途允许多次小提交(鼓励),但不允许波次结束时仍有未提交改动过夜。
  • AI 会话结束前,执行者对三仓各跑一次 git status,把结果写进波次报告——「工作区干净」要有出处。

3.2 提交信息:沿用现行约定,不引入新格式

git-workflow.md 已固化的「feat/fix/refactor/docs/test/chore 前缀 + 中文主题 + 正文验收证据 + ADR 引用」在第一迭代全程执行良好(近 20 个提交无一例外),M2 原样沿用,不引入英文 conventional commits 或 scope 括号语法——现行格式已具备 conventional commits 的全部实用价值(可 grep、可归类、可回溯),改格式只会割裂历史。

M2 补充一条:涉及契约的提交,正文注明对应的 openapi.yaml 版本或 doc 仓提交哈希(见 3.3)。

3.3 契约先行时的三仓提交顺序

M2 采用契约先行,顺序固定为:

  1. patbond-doc 先行docs/api/openapi.yaml 的契约变更单独成提交(docs: 宠物健康档案 API 契约(M2 波次 N)),push 且 docs-build 绿。契约提交不与其他文档改动混杂,保证可独立引用与回退。
  2. patbond-api 跟进:实现 + 测试成一或多个提交,正文引用 doc 仓契约提交哈希,push 且 backend-test 绿。
  3. patbond-flutter 收尾:对接实现,正文同样引用契约哈希,push 且 flutter-gates 绿。

契约中途返工时,doc 仓允许在同波次内追加修订提交(契约未被下游消费前不算破坏性变更);一旦 api/flutter 已按某版契约合入,再改即视为破坏性修改,走 2.2 的 PR 通道。

4. CI 扩展规划

4.1 现状修正:任务假设的两问已被第一迭代末的事实回答

核查发现三仓 CI 均已上线且全绿,任务中「flutter 是否接入 CI」「doc 是否加 --strict 门禁」不再是开放问题:

  • patbond-flutter CI 已上线并验证可行run 11 success)。零外部 action 约束下 Flutter SDK 进容器的方案已在 ci.yml 中落地:从 flutter-io.cn 镜像 curl 下载 Flutter 3.44.6 的 tar.xz,解压到挂载的 gitea_toolcache 卷(runner container.options 配置 -v gitea_toolcache:/opt/hostedtoolcache),首跑下载约 900MB,后续 run 复用缓存秒级就绪;pub 走 pub.flutter-io.cn。门禁为 format/analyze/test 三命令,与本地一致。
  • patbond-doc 的 mkdocs build --strict 门禁已上线apt 装 mkdocs,规避 PEP 668docs-build success)。
  • patbond-api CI 全绿(82 测试,约 3m18s),Testcontainers 经 docker.sock 挂载正常工作。

4.2 M2 的 CI 增量(按优先级,均为规划,实施时再改文件)

  1. 无必做项。 三条流水线覆盖了全部本地门禁,M2 开工不被 CI 阻塞。
  2. 可选——Flutter 版本升级流程注明toolcache 以 flutter-3.44.6 目录名区分版本,升级 SDK 时改 ci.yml 中 FLUTTER_VERSION 即自动触发新版本下载,旧目录需手动清理卷(写入 ci-runner-setup.md 的常见问题即可,M2 内低优先)。
  3. 可选——api CI 增加 M2 迁移的守护./mvnw clean test 已覆盖 Flyway 迁移执行(Testcontainers 起真库跑迁移),无需新增步骤;只需坚持「已推送迁移不可变」规则。
  4. 明确不做flutter build apk 冒烟(耗时大、M2 无发布需求)、覆盖率门槛(先积累基线再谈阈值)。

5. 敏感信息防泄漏(轻量方案规划,待拍板后实施)

现状:三仓 .git/hooks 均只有样例,无任何自动检查;卫生完全靠 git-workflow.md 约定 + 提交前人工核对。api 仓敏感配置已按 *.sample 模式管理(真实 application.yml 在 gitignore 中)。AI 辅助开发下,机械防线值得补上。零外部 action 约束下推荐两层,均为纯 shell + grep,无任何外部依赖:

5.1 第一层:入库的共享 pre-commit 脚本(推荐先做)

  • 各仓新增 scripts/hooks/pre-commit(入库,可评审、可演进),检查 git diff --cached 的暂存内容:
    • 文件名黑名单:拦截 application.yml(非 .sample)、.env*.pem*.p12*.jkskey.properties 等入暂存区;
    • 内容模式:对暂存 diff 的新增行 grep 常见凭据特征——BEGIN (RSA |EC )?PRIVATE KEYpassword:/secret: 后跟非占位值(排除 changemeyour-*<placeholder> 等样例值)、长 base64/hex token 形态;
    • 命中即拒绝提交并打印命中行号(不打印命中内容全文,避免终端留痕)。
  • 启用方式为一次性 git config core.hooksPath scripts/hooks(每仓每机各执行一次,写入各仓 README)。hook 可被 --no-verify 绕过——这是特性不是缺陷:误报时有出口,且第二层兜底。

5.2 第二层:CI 侧兜底 grep(各仓 ci.yml 加一个 step

  • checkout 后加一个纯 shell step,对整棵工作树跑同一套文件名/内容模式检查(复用 5.1 的脚本,保证两层规则同源),命中则 fail。零外部 action,新增耗时秒级。
  • 与 pre-commit 的分工:hook 拦「即将提交的」,CI 拦「已经提交的」(含 --no-verify 绕过和历史遗漏的新暴露)。CI 只查工作树而不扫全历史——扫历史属一次性审计,若做一次即可,不进流水线。

5.3 不推荐

  • gitleaks/trufflehog 等外部工具:与零外部依赖约束冲突(需拉二进制或镜像),且对本项目的敏感面(一个 application.yml + 未来的第三方 key)而言是牛刀。
  • 提交后自动改写历史清除泄漏:一旦真泄漏,正确动作是立即轮换凭据,再考虑历史清理——写入规范备忘即可。

6. 待拍板事项汇总

# 事项 推荐
1 M2 分支策略:trunk-based 为主 + 高风险改动(Flyway 迁移/契约破坏性变更/依赖升级/并行期)强制短命分支 + PR 采纳 2.2
2 Gitea dev/main 分支保护 + 状态检查强制 可选,倾向开启 2.2
3 提交信息格式沿用现行中文约定,不切换英文 conventional commits 沿用 3.2
4 契约先行三仓提交顺序:doc → api → flutter,契约提交独立成提交并被下游引用 采纳 3.3
5 防泄漏两层方案(共享 pre-commit 脚本 + CI 兜底 grep 采纳,M2 第一波实施 5
6 patbond-api 本地孤儿 master 分支清理 顺手做 1

采纳后需要落实的文件改动(本报告未执行):各仓 scripts/hooks/pre-commit 与 ci.yml 的兜底 step、git-workflow.md 增补 2.2/3.1/3.3 条款、本报告挂入 mkdocs 导航。