t
|
6de5d52363
|
feat(version): 开发号随提交自动递增 + 首个正式版本 0.1.0
build / build (push) Successful in 51s
按使用者要求定的版本规则(自动升的是**开发标识**,发布版本与 tag 仍由人批准):
- **开发号自动递增**:display_version(development) = `<正式版本的主.次>.<自 v<正式版本> 以来的提交数>`
(正式 0.1.0 之后第 1 个提交 0.1.1、第 12 个 0.1.12;恰在发布提交上 = 正式号)。
它**不写进 CHANGELOG**(发布记录只在发版时动),由 git 算出来 ⇒ 每个提交都有自己的号、数字只增。
- **浅克隆不猜号**:`--depth` 会把条数算少 ⇒ 浅仓库里拒绝算号,退回 `<版本>-dev+g<短SHA>`;
检出步骤在仓库有 tag 时 `--unshallow` 补全历史。
- 接线三处齐全:`version.py --identity` → 门禁 `-X …CommitsSinceRelease=<n>`;Makefile 的
`COMMITS_SINCE_RELEASE`;Dockerfile 同名 build-arg;Go 侧新增 `CommitsSinceRelease` 与
DisplayVersion() 新规则;契约测试**交叉核对**"注入的提交数 == git 算出的"(防注入错号)。
- **首个正式版本 0.1.0**:CHANGELOG 的 `[Unreleased]` 提成 `## [0.1.0] - 2026-10-13`;
头部补"版本怎么走"两行;RELEASE_RUNBOOK 补递增规则与"下一次发布把次版本加一"。
- 发版预检新增:打印**当前开发号**,并挡住"候选正式版本 <= 当前开发号"(会把开发号当正式号;建议次版本加一)。
验证:version.py --self-test(含 tag 后第 2 个提交 = 0.2.2、恰在 tag 上 = 0.2.0、无 tag 不猜号);
release_preflight --self-test(21 分支,含开发号两条);go test 本地三态 + 临时仓库 tag+2 提交实测
(Python 与 Go 都得出 0.2.2);反向夹具 85/0;make verify 15/15 success。
|
2026-10-13 16:45:56 +08:00 |
|
姚章浩
|
05144309c3
|
feat(version): 构建身份(release_version/build_kind/display_version),无基线也放行
解决"开发构建沿用已发布版本号,分不清开发版与正式版":
- 新增 `scripts/version.py --identity`:release_version(无基线即空)/ build_kind /
commit_sha(完整 40 位)/ display_version / built_at。显示规则:发布 `X.Y.Z`、
开发 `X.Y.Z-dev+g<短SHA>`、无基线 `dev+g<短SHA>`、什么都拿不到 `dev`。
- `build_kind=release` 只认**显式发布上下文**(`BUILD_KIND=release` / `--release`);
声明发布构建却没有已发布版本 ⇒ 拒绝(rc=2)。普通 main 构建永远是 development,
**不许只显示上一正式版本号、不许自称正式版**。
- Go 侧 `internal/version` 加 ReleaseVersion/BuildKind/DisplayVersion()/IsRelease()/Info(),
原 Number/CommitSHA/BuildTime 语义不变(向后兼容);契约测试改成:发布构建必须等于
CHANGELOG 顶部、开发构建必须是 dev 形状;`make verify` 的 contracts 项新增
**负例**「自称正式版 ⇒ 必须红」(只有正例的契约会被静默掏空)。
- 构建接线:Makefile/Dockerfile/ci_checks `--internal-build` 统一走 identity;
Makefile 的 `make version` 打印身份 JSON;Dockerfile 新增 RELEASE_VERSION/BUILD_KIND。
- `tests-go` 的"按设计跳过"声明补上 `TestDevBuildDoesNotClaimRelease`(它的强制点在 contracts)。
验证:go test 三态实测(未注入 SKIP、开发身份 PASS、自称正式版 FAIL);
--internal-build 产出并打印 dev+g<sha>;--internal-identity 契约项 rc=0;
make verify 15/15 success;反向夹具 80/0。
|
2026-10-13 14:59:36 +08:00 |
|
姚章浩
|
40d84994cb
|
feat(ci): 版本记录检查(四节 + 正式 tag 一致性)+ 只读发版预检
check_changelog.py:正式版本条目必须四节齐备且非空(改了什么/兼容性与迁移影响/怎么验收/已知问题)、版本号三段无前导零、[Unreleased] 在最上面;新增 --tags 核对正式 tag(必须注释 tag)与它指到那个提交里的版本记录一致。只有 Unreleased 的新工程放行;没有正式 tag 不判红(开发版本不打 tag 是常态)。ci_checks.py:新增必需检查 version(门禁 15 项),策略版本 ci-checks/2。ci_checkout.sh:记录远端 tag 清单并取 tag 对象供核对。release_preflight.py:只读预检(版本建议/完整 SHA/CI 证据/CHANGELOG/远端 tag 与 Release/遗留项),写类 git 命令与 POST 在预检路径上被拒(--self-test 证明);批准后 --execute 才打注释 tag、推 tag、建 Release 并读回。CHANGELOG 0.1.0 补上原本缺的两节。
|
2026-10-12 17:57:43 +08:00 |
|
姚章浩
|
88da069e1f
|
ci(checks): 必需与可选测试按声明区分,未声明就跳过的用例判红
test-scope.json 提供声明:package/test 至少给一个、必须给 reason 与 owner、package 级要写 expected_skips(跳过数涨了要重新声明)、review_by 过期即失效。文件缺失或解析不了 = 声明不出来 ⇒ 不许默认放行。
|
2026-10-12 11:15:18 +08:00 |
|
姚章浩
|
a3a1319a11
|
feat(ci): 唯一权威门禁 make verify(14 项必需检查,汇总不认"未运行")
一次性把本地与 CI 的门禁收成一条命令:make verify = python3 scripts/ci_checks.py。
两边跑的是同一份逻辑,不再各写一套步骤(两边各写一套的结局是迟早只改一边)。
14 项必需检查:identity(检出 == 事件完整 SHA,只在 CI 必需)、commits、deps-install、
format、static-go、static-web、build-go、build-web、tests-go、tests-web、contracts、
security-secrets、security-deps、manifests-locked。make list 打印清单。
三条判据写死在代码里:
- 失败即停,但剩下的记 not_run 并如实写进报告;aggregate() 只认 success,
未运行/被跳过都不算通过(不适用要在清单里声明 required_in,不许运行时悄悄 skip)。
- 工具缺失、依赖没按锁装、输出解析不了 ⇒ 失败,不当成"检查通过"。
- 测试必须真跑:go test 加 -count=1 并盘点通过/跳过数;前端读 vitest 的 JSON 报告,
空套件不算通过。跳过原因会打进报告(当前 72 个集成用例因缺 TEST_DATABASE_URL 跳过)。
新增四个自带反向自检的脚本(--self-test 故意弄坏必须红):
scripts/check_format.py(Go 判输出而非退出码 + 前端只能减的基线)、
scripts/check_secrets.py(只打印位置与类别,绝不打印值)、
scripts/check_deps_vuln.py(govulncheck 锁 v1.1.4 + npm audit 分级 + 到期例外)、
scripts/ci_checks.py(门禁 + 汇总)。
验证(本机实跑,全部为真实退出码):
make verify → 总体 success(档案 local),identity=skipped 已在清单里声明为 CI 必需;
tests-go 执行 31 个包、通过 549 / 失败 0 / 跳过 72;tests-web 106 个套件、191 个用例全过;
security-deps:govulncheck v1.1.4 0 命中、npm audit 生产与全量均 0。
|
2026-10-12 00:10:51 +08:00 |
|