模板库线上对齐仓库源:递增版本重发并把说明文档纳入发布
Project CI / AI game creator shell Rust smoke (push) Successful in 1m56s
Project CI / AI game creator shell Rust crates (push) Successful in 1m23s
Project CI / AI game creator shell Rust lane 2/2 (push) Failing after 4m48s
Project CI / AI game creator shell Rust lane 1/2 (push) Failing after 7m38s
Project CI / Frontend tests (push) Successful in 10m0s
Project CI / Native shell tests (push) Successful in 11m37s
Project CI / Repository checks (push) Successful in 8m49s
Project CI / Backend tests (push) Successful in 12m24s
Project CI / AI game creator shell web tests (push) Successful in 4m50s
Project CI / AI game creator shell Rust smoke (push) Successful in 1m56s
Project CI / AI game creator shell Rust crates (push) Successful in 1m23s
Project CI / AI game creator shell Rust lane 2/2 (push) Failing after 4m48s
Project CI / AI game creator shell Rust lane 1/2 (push) Failing after 7m38s
Project CI / Frontend tests (push) Successful in 10m0s
Project CI / Native shell tests (push) Successful in 11m37s
Project CI / Repository checks (push) Successful in 8m49s
Project CI / Backend tests (push) Successful in 12m24s
Project CI / AI game creator shell web tests (push) Successful in 4m50s
- 7 个内容已变的模板 templateVersion 升到 0.1.1,blank-2d-canvas 与 blank-web 保持 0.1.0 - 发布脚本把仓库 README.md 覆盖写到 templates/README.md(上限 64 KiB,写在清单之前并回读校验),线上说明文档不再是手工副本 - 修复守卫拒绝时直接 process.exit(1) 触发 libuv 断言崩溃、看不到拒绝原因的问题 - 新增发布用例:说明文档随发布覆盖写且写在清单之前、源目录没有 README 时不写线上文档 - 模板库新增仓库侧 README.md 源文件(发布后与线上逐字节一致) - 技术方案补说明文档契约与 2026-09-21 重发布记录;决策记录与踩坑记录各补一条 - 验证:node --test 27 项、真实发布 28 个对象回读通过、线上清单与 README 核对一致、AGC 壳 3 项线上用例重跑通过、check:doc-index、check:encoding、eslint、git diff --check
This commit is contained in:
@@ -1,5 +1,14 @@
|
||||
# 决策记录
|
||||
|
||||
## 2026-09-21 模板库线上产物对齐仓库源:递增版本重发 + 说明文档纳入发布
|
||||
|
||||
- 背景:`agc-dev` 上的 `templates/` 产物停在 2026-09-17 发布的那一版,仓库源在那之后改过(`5e4ff54a9` 删掉模板内嵌 `package-lock.json`、`game.js` / `main.js` 等内容调整),9 个模板里 7 个的 ZIP 与线上不一致;dry-run 被「同一 `templateVersion` 的 ZIP 不得变」门禁拒绝,发布器因此无法把仓库状态发上去。
|
||||
- 决策:按门禁要求为内容已变的 7 个模板递增 `templateVersion` 到 `0.1.1`(`blank-2d-canvas`、`blank-web` 内容未变,保持 `0.1.0`),并完成一次真实发布;对象使用内容寻址键 `v1/<id>/sha256/<摘要>/…`,`index.json` 与说明文档在发布锁内最后提交,历史对象不删除。
|
||||
- 决策(说明文档):`templates/README.md` 不再是手工副本——它由发布脚本从仓库源 `apps/ai-game-creator-shell/template-library/README.md`(≤64 KiB)覆盖写入并回读校验,写在清单之前;改契约只改仓库源。
|
||||
- 决策(CLI 行为):发布器遇到门禁拒绝时用 `process.exitCode = 1` 正常退出,不再 `process.exit(1)` 让 Node 在 fetch 句柄未关闭时抛 libuv 断言(此前现场只剩 `Assertion failed`,看不到拒绝原因)。
|
||||
- 影响范围:`apps/ai-game-creator-shell/template-library/v1/*/meta.json`、`apps/ai-game-creator-shell/template-library/README.md`、`scripts/agc-template-library-publish.mjs` 与其测试、本文件与模板库技术方案。
|
||||
- 验证方式:`node --test scripts/agc-template-library-publish.test.mjs`(27 项,含新增「说明文档随发布覆盖写且写在清单之前」「源目录没有 README 时不写线上文档」);真实发布 28 个对象回读通过;匿名读取线上清单(9 个模板、7 个 `0.1.1`、全部内容寻址键)与 `templates/README.md`(与仓库源逐字节一致);AGC 壳 3 项线上用例(读清单、下载安装、下载并原生建项 Cocos)重跑通过。
|
||||
|
||||
## 2026-09-21 macOS 发布改为只出 arm64 单架构(Intel 暂不支持)
|
||||
|
||||
- 背景:Mac 发布管线按 `universal-apple-darwin` 构建,但随包 Node 便携运行时只有**单架构官方发行版**(`stage-node-runtime.mjs` 从 `process.execPath` 取材),于是 macOS Job #7~#13 连续失败在「Node 运行时不支持发布目标:universal-apple-darwin」。期间出现过一版「按宿主架构放行」的过渡实现,它能骗过通用包自检(`check-macos-bundle.mjs` 按 `process.arch` 校验),但 Intel 上那份 arm64 侧车不可执行,并且已发布的 dev-mac 0.1.86 就带着这个缺陷。
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
# 踩坑与排障记录
|
||||
|
||||
## 发布器守卫拒绝时不要把 process.exit 用在 fetch 句柄未关闭处
|
||||
|
||||
- 现象:`agc-template-library-publish.mjs --dry-run` 撞上「同一 `templateVersion` 的 ZIP 不得变」门禁时,终端只剩一句 `Assertion failed: !(handle->flags & UV_HANDLE_CLOSING), file src\win\async.c`,看不到任何拒绝原因,看起来像脚本崩溃而不是被拒绝。
|
||||
- 原因:`main().catch(...)` 里直接 `process.exit(1)`;此时 dry-run 刚用 fetch 读过公共清单,句柄仍在关闭流程中,Node/libuv 在 Windows 上先抛断言,把真实错误信息挤掉。
|
||||
- 处理:`catch` 里只设 `process.exitCode = 1`,让事件循环自然退出;同批把说明文档纳入受管发布(见决策记录 2026-09-21 条目)。
|
||||
- 验证:把模板源复制到临时目录、把某个模板的 `templateVersion` 改回与线上同版本并改动一个字节,`--dry-run` 应打印 `同版本 ZIP 内容或尺寸变化,请递增 templateVersion` 且退出码为 1,不再出现 `Assertion failed`。
|
||||
- 关联:`scripts/agc-template-library-publish.mjs`。
|
||||
|
||||
## macOS 只出 arm64 单架构,universal 必须失败关闭
|
||||
|
||||
`stage-node-runtime.mjs` 只把**构建宿主的 Node**打成便携运行时(官方发行版是单架构,没有 universal 发行版),而 2026-09-21 之前 `build-macos-ci.mjs` 构建的是 `universal-apple-darwin`:macOS Job #7~#13 因此在 `stageNodeRuntime` 直接抛「Node 运行时不支持发布目标:universal-apple-darwin」。期间出现过一版「按宿主架构放行」的过渡实现(`targetRuntime` 对 universal 返回宿主架构),它能骗过通用包自检(`check-macos-bundle.mjs` 按 `process.arch` 校验),但**Intel Mac 上这份 arm64 侧车不可执行**,等于把坏包发出去。当前决策:macOS 固定只构建 `aarch64-apple-darwin`,清单只登记 `darwin-aarch64`,`targetRuntime('universal-apple-darwin')` 保持失败关闭。恢复 Intel 的正确路径是先在 staging 支持按架构各带一份**同版本**运行时(另下载另一架构官方发行版)并让通用包自检按架构分别校验,再切回 universal 目标、把 `darwin-x86_64` 键登记回去;不得用「只带宿主架构」充数,也不得把 arm64 产物登记成 x86_64 键。
|
||||
|
||||
@@ -68,6 +68,7 @@ templates/
|
||||
- 模板源在仓库 `apps/ai-game-creator-shell/template-library/`:`v1/<id>/{meta.json, project/**, cover.(png|jpg|webp|svg)}`,`template.zip` **不落仓库**,由脚本按 `project/` 现场打包(条目排序、固定时间戳,同内容重复打包摘要一致)。
|
||||
- 上传与校验由 [`scripts/agc-template-library-publish.mjs`](../../scripts/agc-template-library-publish.mjs) 完成:`--source apps/ai-game-creator-shell/template-library [--dry-run] [--only <id,id,...>]`。ZIP、封面和元数据分别以自身字节的 SHA-256 定位,只创建新对象或复用逐字节校验一致的已有对象;全部对象回读一致后才更新 `index.json`。失败不回收已上传对象,旧清单及其引用始终可读。
|
||||
- 只更新指定模板时使用 `--only <id,id,...>`,在发布锁内读取最新清单,只替换指定 ID,其余条目和未知扩展字段保留。首次清单 404 可由本次选择初始化;读取异常或清单非法时停止。全量发布也遵守相同锁与版本门禁。
|
||||
- `templates/README.md` 与上述正文不同:它不是内容寻址对象,而是**覆盖写的说明文档**,源在仓库 `apps/ai-game-creator-shell/template-library/README.md`(上限 64 KiB),由同一次发布在清单之前写入并回读校验。客户端从不读它,改契约只改仓库源即可,不要再手工维护线上副本。
|
||||
- 正式发布先通过 `GetBucketVersioning` 确认 Bucket 从未开启版本控制,再用 `x-oss-forbid-overwrite: true` 原子创建 `.publish-lock.json`;版本控制 Enabled、Suspended、检查无权限或无法判定时均在写入前停止。所有写同一清单的发布进程必须使用此锁,发布期间不得改变 Bucket 版本控制配置。锁没有自动过期或抢占机制,已被占用时直接失败,重新执行须重新获取锁并读取最新清单。
|
||||
- 只释放本任务已明确获取且 owner 标识仍一致的锁。获取结果不明时不猜测删除。正文对象不可变,其写入失败可安全释放本任务的锁;清单 PUT 已发起后若遇到断连、超时或服务端 5xx 等不确定结果,必须保留锁并报错,防止旧在途请求晚于下一发布者写入。清单收到确定成功或确定拒绝响应后才进入正常解锁路径;不自动重发清单写入,也不凭一次 GET 猜测在途 PUT 已结束。遗留锁须在确认原请求及进程已终止或完成后由运维处理;释放失败必须报告,不伪装为发布成功。
|
||||
- `--dry-run` 仅构造和读取合并计划,不读取凭据、不获取锁、不 PUT/DELETE。发布不删除历史对象,也不提供随发布清理的选项;旧客户端缓存和未完成下载可能仍引用旧键。
|
||||
@@ -117,6 +118,8 @@ Cocos 回归分别覆盖仓库模板和线上真实 ZIP 的安装、连续建项
|
||||
|
||||
`2026-09-21` 客户端接入复核:Rust 定向 24 项通过(新增清单来源判定 5 项:合法远端正文优先并标 `network`、远端失败回退缓存并标 `cache`、无缓存时暴露远端错误、远端正文非法时不用缓存掩盖、缓存损坏时失败关闭;新增建项目失败清理 1 项;并在大小/摘要不一致、越界归档两条用例上补「拒绝后不留安装目录、不产生已下载判据」断言)。3 项线上用例(读线上清单、下载安装线上模板、下载并原生建项 Cocos 模板)本轮全部真实执行通过;匿名 `GET https://agc-dev.oss-rg-china-mainland.aliyuncs.com/templates/index.json` 返回 200、`schemaVersion=agc-template-library.v1`、9 个模板。前端 38 项通过(模型 9、网格 6、页面 12、控制器 11),`appSurface` 首页模板用例 2 项通过(灰度外隐藏入口与推荐位、点击进入模板库不建项),AGC `typecheck` 通过。仍未验证:Creator 内场景运行,以及真机 iOS / Android 观感。
|
||||
|
||||
`2026-09-21` 模板库重发布:把线上库从 09-17 的旧产物对齐到仓库当前源。线上 9 个模板里 7 个(`blank-3d-scene`、`cocos-empty-2d/3d/3d-hq/hello-world`、`phaser-2d-starter`、`threejs-3d-starter`)的 ZIP 与仓库不一致(旧产物来自 PR 定稿前的源,例如模板内嵌 `package-lock.json` 已由 `5e4ff54a9` 删除、`game.js` / `main.js` 后来改过),其中 2 个原本一致(`blank-2d-canvas`、`blank-web`)。按「同版本 ZIP 不得变」门禁,为这 7 个模板递增 `templateVersion` 到 `0.1.1` 后重发:28 个内容寻址对象逐个回读校验通过,`index.json` 与 `templates/README.md` 在锁内提交;线上清单现在全部指向 `v1/<id>/sha256/<摘要>/` 键,`libraryVersion=1`、9 个模板、无下架条目。发布脚本本次同时补齐说明文档受管写入(源文件即 `apps/ai-game-creator-shell/template-library/README.md`)并修掉「守卫拒绝后直接 `process.exit(1)` 触发 libuv 断言崩溃、看不到原因」的问题;线上 README 与仓库源已逐字节一致。
|
||||
|
||||
## 本地压测假数据注入(feature 控制)
|
||||
|
||||
模板库的数据源在 Rust 侧(清单校验、安装状态、下载与建项目都在这里),TS 只消费快照做渲染,所以假数据注入也放在 Rust 侧,走与真实完全一致的链路。
|
||||
|
||||
Reference in New Issue
Block a user