Files
patbond-doc/docs/development/releases.md
T
lixi 1bcfe444c6
CI / docs-build (push) Successful in 1m14s
docs: 补记 v0.3.0 分支保护实配与后续发布流程变更
- checklist 第 6 步执行记录:api/flutter 的 main 已保护(经 Gitea API 核实
  protected=true、禁直推、状态检查上下文显式填写),dev 保持直推流
- 说明状态检查上下文为何显式填写而非留空(留空时空集为真会反而放行)
- ⚠️ 明确后续发布姿势变更:main 禁直推后,dev→main 须走 PR + CI 门禁,
  首次发布用的直推写法仅适用于保护启用前;checklist 第 4 步相应作废

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-10 16:16:26 +08:00

79 lines
6.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 发布记录(常设)
> **定位**:跨迭代常设文档——每次 `dev → main` 发布在此追加一条记录:版本号、三仓 tag 与哈希、门禁证据、已知遗留。
> **维护约定**:按[发布 checklist](iterations/iteration-3/08-git-workflow-plan.md)(§3.3) 执行,完成后在此登记。最新版本在最上。
> 发布分支为 `main`(ADR-011 原写 master,ADR-021 更正);日常开发直推 `dev`。
---
## v0.3.0 — M3 社区(2026-09-10
**首次正式发布**,发布流程首次演练。
### 三仓 tag
| 仓库 | tag | 提交 | 内容 |
| --- | --- | --- | --- |
| patbond-api | `v0.3.0` | `8089c06` | 五模块(common/auth:8081/user:8082/pet:8083/community:8084),334 测试 |
| patbond-flutter | `v0.3.0` | `0e87413` | 502 测试 + 三份 E2E 烟囱脚本(M1/M2/M3) |
| patbond-doc | `v0.3.0` | 本记录所在提交 | 契约 v1.3.0 + 三迭代全部报告(20+30+30 份) |
### 版本内容
- **M1 认证纵切**:JWT RS256、refresh 轮换、多设备会话、登录锁定
- **M2 宠物健康档案**:宠物 CRUD + 三角色权限 + 体重/疫苗/健康事件/提醒 + 档案聚合(18 操作)
- **M3 社区**:图片媒体上传闭环(自托管 MinIO,ADR-016)+ 帖子草稿/发布/删除 + 公共 Feed 游标分页 + 单层评论 + 点赞收藏幂等 + 关注(13 路径/19 操作)
- **契约**:openapi.yaml **v1.3.0 冻结**,31 路径/43 操作/72 schema;契约一致性测试矩阵 173 格、43/43 操作零漂移
- **部署形态**:docker compose 六容器(postgres:18 + MinIO + auth + user + pet + community),应用容器无状态(ADR-007)
- **数据库**:Flyway V1~V5(identity/media、platform 埋点、pet_health、字典种子、community)
- **决策**:ADR-001~021
### 发布门禁证据
| 门禁项 | 结果 | 证据 |
| --- | --- | --- |
| 三仓 CI 绿 | ✅ | Gitea commit status API 直查 success |
| 全量测试 | ✅ | api 334 / flutter 502,`mvnw clean test``flutter test` 双绿 |
| E2E 回归(M2+M3 同环境) | ✅ | **M2 11/11 + M3 14/14**,各连跑 3 轮零 flake,契约偏差 0 — [30 号报告](iterations/iteration-3/30-release-e2e-regression.md) |
| M3 验收标准逐条取证 | ✅ | 四条全过 — [28 号报告](iterations/iteration-3/28-e2e-smoke-report.md) |
| 契约向后兼容 | ✅ | v1.2.0→v1.3.0 结构化比对:paths/schemas **removed 与 changed 均为 NONE**(严格增量) |
| 共享代码面回归分析 | ✅ | M3 全区间 `patbond-pet/src/main/` 0 文件变更;`patbond-common` 仅 ErrorCode +9 行纯新增 |
| 凭证防泄漏 | ✅ | `check-secrets.sh --all` 三仓 exit 0(9 规则两层检查,ADR-021) |
### 发布操作记录(首次一次性项)
1. **命名统一**:ADR-011 的 `master` 更正为 `main`(ADR-021);api 本地孤儿 master 已删。
2. **api main 重建**(方案 A,用户拍板):远端 main 原为建仓自动生成的单提交 `ff876bc "Add README"`,与 dev **无共同祖先**,无法 ff 也不宜缝合孤儿历史。操作:Gitea 默认分支临时切 dev → 删除远端 main → `git push origin dev:refs/heads/main` 重建 → 默认分支切回 main。结果:main 41 提交、与 dev 同点位、零 force push。原孤儿提交保留本地备份 ref `refs/backup/old-main-ff876bc`
3. **flutter main 快进**:main 本就是 dev 祖先,用 `git push origin dev:main` 完成——**较 checklist 第 4 步的 `checkout main && merge --ff-only` 改进**:不切换工作区(当时有 E2E 脚本正在该工作区运行),且非快进推送会被 git 自动拒绝,等于内建 ff-only 保护。
4. **分支保护启用**(checklist 第 6 步,Gitea 平台):api 与 flutter 的 `main` 均已启用,经 Gitea API `GET /repos/{owner}/{repo}/branches/main` 核实:
| 仓库 | protected | 推送 | 状态检查上下文 | 所需批准 |
| --- | --- | --- | --- | --- |
| patbond-api | `true` | 禁用直接推送 | `CI / backend-test (push)` | 0 |
| patbond-flutter | `true` | 禁用直接推送 | `CI / flutter-gates (push)` | 0 |
| patbond-doc | 未启用 | —— | —— | —— |
两仓 `dev` 均保持 `protected=false`(直推流,ADR-021 分层策略);doc 仓 main 即日常分支、不参与发布分支语义,按规划不设保护。**状态检查上下文显式填写而非留空**:留空时 Gitea 语义为「所有上报的检查都通过」,若某次工作流未触发则空集为真反而放行;写死检查名消除该歧义。
### 已知遗留(不阻塞发布)
**真机验证四项挂起**(步骤已备齐在[真机验证清单](device-verification.md)):媒体上传弱网、乐观更新手感、Feed 图片加载、社区事件落库;另有 M2 两项(Android 事件落库、SessionTracker 30min)。桌面/脚本不可替代——`platform=linux` 埋点整批 400 属契约内行为。
**功能遗留**:完整草稿列表与自动保存、大图下滑关闭手势、`widthPx/heightPx` 恒 null(单图帖回落 4:3)、`eventVersion` 口径未定型、uploading 超时清理任务、429 限流(连带客户端 Retry-After 分支)、话题/关注列表/作者主页(ADR-018 剪出)。
**跨迭代技术债**:access token 黑名单(退出后已签发 access 在剩余 ≤15 分钟内仍有效)、`/internal` 改 mTLS。
### 发布后生效的纪律
- **`main` 已禁止直接推送**——影响 `main` 的一切变更(含发布本身与 hotfix)一律走 PR,CI 状态检查通过方可合并(ADR-021 强制情形之二正式生效)。`dev` 保持直推流不变。
- **⚠️ 下次发布的姿势与本次不同**:本次首发用 `git push origin dev:main` 直推(当时 main 尚未保护);保护启用后该命令会被拒绝。**此后发布流程为**:
1. 完成 checklist 第 1~2 步(三仓 CI 绿 + E2E 双份回归 PASS);
2. 在 Gitea 上创建 PR:`dev``main`(标题写版本号,正文贴门禁证据链接);
3. 等 PR 的 CI 状态检查转绿(即上表的 `status_check_contexts`);
4. 在 Gitea 上合并 PR——因 dev 与 main 无分叉,合并应为快进;
5. 继续 checklist 第 5、7 步(打 tag、写本页记录)。
故 checklist 第 4 步的本地 `merge --ff-only && push` 写法**仅适用于首次发布**(保护启用前),后续版本以上述 PR 流程替代;第 3、6 步为一次性项,不再重复。
- 若某次 PR 显示 `dev``main` 有分叉(无法快进),说明 main 被绕过 dev 改动过,**先查明原因再合并**,不要用合并提交掩盖。