5f3a71cade
build / build (push) Successful in 26s
背景:本仓此前没有任何版本/构建元信息 —— 没有 ldflags 注入、也没有产物可读的 版本号,"线上跑的是哪个提交"答不出来;"这次改了什么、怎么验收"也没有载体。 落地: - CHANGELOG.md:**版本号的唯一来源**(正本 §6.1:版本号只准有一处)。刻意不放 VERSION 文件、也不靠 git tag —— CI 是 `git fetch --depth 50`,取不到 tag, `git describe` 会静默退化。每个已发布版本必须有两节:### 改了什么 与 ### 怎么验收。 - scripts/version.py:从 CHANGELOG 顶部解析版本号;解析不到即非 0 退出(构建据此失败)。 - scripts/check_changelog.py:结构自检(两节齐、带日期、版本号不重复且严格递减、 小节不为空),带 --self-test 反向自检。 - internal/version:三个构建期注入变量 + 契约测试(注入的号必须等于 CHANGELOG 顶部)。 - Makefile:build 带 -ldflags 注入;verify 增加 changelog-check 与 version-contract。 - Dockerfile:ARG VERSION/COMMIT_SHA/BUILD_TIME + ldflags(未透传时落 dev —— 故意显眼, 好过看起来正常的假版本号)。 - CI:新增「版本与变更记录契约」步,并显式断言契约测试真的 PASS(被跳过的断言等于没有断言)。 - docs/提交规范.md(ci_gate.py 的报错文案一直在指它)、docs/agents/traps.md(7 条实测陷阱)。 验证(都真跑过): - make version → 0.1.0;make changelog-check → 合规 - make version-contract → PASS;注入 9.9.9(CHANGELOG 里没有)→ FAIL(反向自检) - 删掉真实 CHANGELOG 的「怎么验收」小节 → 报红(对真实文件做,不只是夹具) - go build ./... 与 go vet ./internal/version/... 通过 未做(会与在审 PR #2 冲突,待其合并后在 main 上补): - GET /version 端点(internal/httpapi/server.go)与 cmd/api 的 -version 开关 - compose.yaml 透传 build args(当前由 compose 构建的镜像会报 dev) ⚠️ 未跑 make verify 全量(含 go test ./... 与前端),CI 是本次的测试证据。