0974d8dfa2
build / build (push) Successful in 57s
按已确认的契约实现(口径见 docs/VERSION_HISTORY.md):
- **版本号口径(只给有证据的)**:注释 tag + tag 指向该提交 + 该提交内 CHANGELOG 顶部三者一致 ⇒ 正式版本;
tag 之后的提交按 `<主>.<次>.<自该 tag 的提交数>` 显示开发号(与 scripts/version.py **同规则**);
证据不足 ⇒ 「历史提交 · 短SHA」+ 原因码,**不补造版本号**。完整 SHA 是唯一身份、版本号不是唯一键
(tag 之后两条并行分支各自的第 1 个提交都算 0.1.1 ⇒ 两条都保留,用短 SHA 区分)。
- **迁移 000046**:version_history_commits(提交记录,主键 repo_key+commit_sha)+ version_history_sync_runs
(同步状态)。快照 = 一次同步:抓完并与 X-Total-Count 对账通过才切换;失败不切换快照、不清空历史、
last_success_at 不动(页面显示"上次同步失败(原因)· 仍展示上次成功数据");「同步成功」≠「历史完整」。
- **只读客户端(匿名,不使用任何凭据)**:白名单 origin + 固定仓库、拒绝任意 URL 与跨主机重定向、
响应上限 5MB / 超时 15s、仅 5xx/429 退避重试(最多 3 次);逐页抓到短页为止;每次全量扫 tag
⇒ 旧提交后补的 tag 会更新既有记录(不新增第二行)。
- **接口**(三个都登记进 api/openapi.yaml):GET /api/v1/build-info(viewer)、
GET /api/v1/version-history(viewer;游标绑定快照,过期返回 409 cursor_expired;不返回伪造 total)、
POST /api/v1/version-history/sync(admin;并发同步复用同一作业,靠 IdempotencyKey)。
- **「当前运行」只认精确匹配**:产物注入的完整 SHA 命中某条记录才标该条;开发构建显式标注"开发构建";
没有可用标识 ⇒ "当前运行版本未知";**不拿最新 main / 最新 tag 顶替**,CI 成功不等于已部署。
- **前端**:一级菜单第 5 项(版本记录)+ 时间线页面(全部/正式/开发/历史四段筛选、正文展开、
加载更多、760px 单列无横向溢出、提交正文与变更记录按纯文本渲染);无打 tag / 发布 / 部署入口。
新增配置(留空即未接线,页面降级):VERSION_HISTORY_GITEA_BASE_URL / _REPO / _ALLOWED_ORIGINS /
_HTTP_TIMEOUT / _MAX_PAGES。
验证:`make verify` 15/15 success(tests-go 578 通过 / 0 失败;tests-web 209 通过 / 0 失败);
新增 Go 用例 30(版本口径与图遍历 12、客户端守卫 6、同步编排 5、接口 7);前端新增 18(组件 10 + 客户端 8);
真实仓库匿名快照拉取(`VERSION_HISTORY_LIVE_BASE_URL=… go test -run TestLiveSyncAgainstRealRepository`):
抓到 113 条与 X-Total-Count 一致、v0.1.0 是注释 tag 且目标与 `git rev-parse v0.1.0^{commit}` 一致、
开发号逐个等于 `git rev-list --count v0.1.0..<sha>`(正式 1 / 开发 22 / 历史 90)。
64 lines
3.4 KiB
JSON
64 lines
3.4 KiB
JSON
{
|
||
"_doc": [
|
||
"测试范围声明:**哪些跳过是允许的**。judge 在 scripts/ci_checks.py 里读这个文件。",
|
||
"极性是『默认必需』:没在这里声明的测试,一旦被 SKIP / PENDING ⇒ 门禁红(必需项不能报通过)。",
|
||
"只有『确实需要外部环境、本仓拿不到』的集成/外部依赖用例才写进来,每条必须写清理由。",
|
||
"package 级条目 = 该包里所有 skip 都算『可选未运行』(例如整个包都依赖 TEST_DATABASE_URL)。",
|
||
"test 级条目 = 只豁免那一个用例(包里其它用例仍是必需的)。",
|
||
"报告里会把这些『可选未运行』的条数与原因如实列出 —— 记录,不等于通过。",
|
||
"⚠️ 文件缺失或解析不了 ⇒ 门禁红:范围声明不出来时,不许默认放行。"
|
||
],
|
||
"optional": [
|
||
{
|
||
"package": "knowledge-governance/internal/platform/postgres",
|
||
"reason": "整个包的集成用例都要 TEST_DATABASE_URL 指向可销毁测试库;本仓不连生产库,CI 无库 ⇒ 跳过(补验路径:起一次性 PG 后设 TEST_DATABASE_URL)"
|
||
},
|
||
{
|
||
"package": "knowledge-governance/internal/releaseadapter/v071",
|
||
"reason": "v0.7.1 源/目标库与 MinIO 集成环境;无环境即跳过"
|
||
},
|
||
{
|
||
"package": "knowledge-governance/cmd/pp-ledger-import",
|
||
"reason": "导入器集成用例需要 TEST_DATABASE_URL"
|
||
},
|
||
{
|
||
"package": "knowledge-governance/cmd/release-worker",
|
||
"reason": "release runtime 集成用例需要受限文件与运行时环境变量"
|
||
},
|
||
{
|
||
"package": "knowledge-governance/internal/monitoring",
|
||
"reason": "真实服务健康矩阵 / 指标窗口用例需要外部服务可达"
|
||
},
|
||
{
|
||
"package": "knowledge-governance/internal/httpapi",
|
||
"test": "TestUISettingsWriteReadBackIntegration",
|
||
"reason": "系统设置写回读用例需要一个运行中的实例"
|
||
},
|
||
{
|
||
"package": "knowledge-governance/internal/httpapi",
|
||
"test": "TestUISettingsWriteReadBackWithLiveVerification",
|
||
"reason": "同上(带实时校验的那条)"
|
||
},
|
||
{
|
||
"package": "knowledge-governance/internal/version",
|
||
"test": "TestNumberMatchesChangelog",
|
||
"reason": "未注入版本号时按设计 SKIP(本地跑全量测试不该被迫先构建);**它的强制点在 contracts 项**:那里带 -ldflags 跑它并断言真的 PASS、且出现 SKIP 就判红"
|
||
},
|
||
{
|
||
"package": "knowledge-governance/internal/version",
|
||
"test": "TestDevBuildDoesNotClaimRelease",
|
||
"reason": "构建身份未注入时按设计 SKIP(本地跑全量测试不该被迫先构建);**它的强制点在 contracts 项**:那里带 -ldflags 跑它并断言真的 PASS、且出现 SKIP 就判红"
|
||
},
|
||
{
|
||
"package": "knowledge-governance/internal/version",
|
||
"test": "TestReleaseBuildRequiresEvidence",
|
||
"reason": "构建身份未注入时按设计 SKIP(本地跑全量测试不该被迫先构建);**它的强制点在 contracts 项**:那里带 -ldflags 跑它并断言真的 PASS、且出现 SKIP 就判红"
|
||
},
|
||
{
|
||
"package": "knowledge-governance/internal/versionhistory",
|
||
"test": "TestLiveSyncAgainstRealRepository",
|
||
"reason": "真实仓库的只读同步用例需要内部可达的 Gitea(**匿名**,不读凭据);无环境即跳过(补验路径:设 VERSION_HISTORY_LIVE_BASE_URL 后单跑这条)"
|
||
}
|
||
]
|
||
}
|