merge latest master
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Successful in 6m31s
Project CI / AI game creator shell Rust crates (pull_request) Successful in 3m6s
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Failing after 4m34s
Project CI / Frontend tests (pull_request) Successful in 2m46s
Project CI / Backend tests (pull_request) Successful in 6m57s
Project CI / AI game creator shell web tests (pull_request) Successful in 2m39s
Project CI / Native shell tests (pull_request) Successful in 6m31s
Project CI / Repository checks (pull_request) Successful in 5m39s
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Successful in 6m31s
Project CI / AI game creator shell Rust crates (pull_request) Successful in 3m6s
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Failing after 4m34s
Project CI / Frontend tests (pull_request) Successful in 2m46s
Project CI / Backend tests (pull_request) Successful in 6m57s
Project CI / AI game creator shell web tests (pull_request) Successful in 2m39s
Project CI / Native shell tests (pull_request) Successful in 6m31s
Project CI / Repository checks (pull_request) Successful in 5m39s
This commit is contained in:
@@ -21,6 +21,7 @@
|
||||
### 渠道与安装身份合同
|
||||
|
||||
- 渠道同时决定**更新端点**与**安装身份**,两者都由构建期写入产物。默认渠道 `dev` 保持基线身份 `productName = 陶泥儿开发版`、`identifier = world.genarrative.ai-game-creator`;`release` 渠道使用正式产品名 `陶泥儿` 并派生 `identifier = world.genarrative.ai-game-creator.release`;其它自定义渠道派生 `productName = 陶泥儿 <渠道显示名>`(如 `beta-2` → `陶泥儿 Beta-2`)与 `identifier = world.genarrative.ai-game-creator.<渠道>`。渠道显示名按连字符分段首字母大写,不改动渠道本身。
|
||||
- Windows 主程序文件名也是渠道安装身份的一部分:`dev` 保留 `genarrative-ai-game-creator-shell.exe` 以延续既有升级链,`release` 使用 `genarrative-ai-game-creator-shell-release.exe`,其它渠道使用 `genarrative-ai-game-creator-shell-<channel>.exe`。NSIS 更新/卸载按该文件名查找进程,保证更新一个渠道不会结束另一个渠道。
|
||||
- 默认渠道身份**不可变更**:既有安装目录、卸载项、快捷方式与已发布客户端的升级链都建立在基线身份上。渠道身份由 `apps/ai-game-creator-shell/scripts/channel-identity.mjs` 单点定义,构建入口、macOS 发布入口与配置门禁共同消费;基线 `tauri.conf.json` 必须逐字等于默认渠道身份。
|
||||
- 安装身份决定的持久与可见事实:Windows 安装目录 `%LOCALAPPDATA%\<产品名>`、卸载项与 `HKCU\Software\genarrative\<产品名>`、WebView2 数据目录 `%LOCALAPPDATA%\<identifier>`、客户端数据目录 `%APPDATA%\<identifier>`;macOS `.app` 名、bundle id、DMG 卷名与菜单栏应用名。
|
||||
- 同机并存:不同渠道的包体可以在同一台设备上同时安装并同时运行,互不覆盖、互不顶掉;同一渠道的新版本仍是原地升级,因为更新端点与安装身份同属一个渠道。
|
||||
@@ -124,19 +125,20 @@
|
||||
|
||||
- 渠道安装身份映射(`<channel>` 为 `dev`、`release` 或自定义名称;`<Channel>` 为渠道显示名):
|
||||
|
||||
| 渠道 | productName | identifier | Windows 安装目录 | 客户端数据目录 |
|
||||
| -------------------- | ------------------ | ---------------------------------------------- | ----------------------------------- | ----------------------------------------------- |
|
||||
| `dev`(默认) | `陶泥儿` | `world.genarrative.ai-game-creator` | `%LOCALAPPDATA%\陶泥儿` | `%APPDATA%\world.genarrative.ai-game-creator` |
|
||||
| `release` / 自定义 | `陶泥儿 <Channel>` | `world.genarrative.ai-game-creator.<channel>` | `%LOCALAPPDATA%\陶泥儿 <Channel>` | `%APPDATA%\world.genarrative.ai-game-creator.<channel>` |
|
||||
| 渠道 | productName | 主程序文件名 | identifier | Windows 安装目录 | 客户端数据目录 |
|
||||
| -------------------- | ------------------ | ------------------------------------------------- | ---------------------------------------------- | ----------------------------------- | ----------------------------------------------- |
|
||||
| `dev`(默认) | `陶泥儿开发版` | `genarrative-ai-game-creator-shell.exe` | `world.genarrative.ai-game-creator` | `%LOCALAPPDATA%\陶泥儿开发版` | `%APPDATA%\world.genarrative.ai-game-creator` |
|
||||
| `release` | `陶泥儿` | `genarrative-ai-game-creator-shell-release.exe` | `world.genarrative.ai-game-creator.release` | `%LOCALAPPDATA%\陶泥儿` | `%APPDATA%\world.genarrative.ai-game-creator.release` |
|
||||
| 自定义渠道 | `陶泥儿 <Channel>` | `genarrative-ai-game-creator-shell-<channel>.exe` | `world.genarrative.ai-game-creator.<channel>` | `%LOCALAPPDATA%\陶泥儿 <Channel>` | `%APPDATA%\world.genarrative.ai-game-creator.<channel>` |
|
||||
|
||||
- 安装身份迁移:`dev` 客户端保持原身份,升级链路连续;`release` 与自定义渠道首次以新身份安装,**不接管也不迁移**任何既有 `dev` 安装、本地项目或登录态,设备上因此可以同时存在两个渠道的客户端,由用户自行决定是否卸载其一。
|
||||
- 安装身份迁移:`dev` 客户端保持原 identifier 与主程序文件名,升级链路连续;dev Windows 包继续清理历史展示名 `陶泥儿` / `Genarrative AI Game Creator` 的旧快捷方式。release 从旧展示名 `陶泥儿 Release` 迁移安装目录与快捷方式到当前 `陶泥儿` 身份;release 与自定义渠道不接管也不迁移其它渠道的数据或登录态。
|
||||
|
||||
## 构建与发布
|
||||
|
||||
- 发布入口:`npm run ai-game-creator-shell:release:upload`(构建 + 按渠道上传);仅构建不发布的 smoke 使用 `--no-bundle` 分支,不读远端版本、不改版本、不生成清单。
|
||||
- 发布入口只解析一次目标,优先级为 CLI `--target value` / `--target=value` / `-t value`、`AGC_BUILD_TARGET`、Windows 默认值;重复/空目标与不支持目标失败关闭。版本高水位、构建 feature/渠道端点、bundle 路径、产物后缀、清单平台键及摘要必须消费同一个发布上下文,不能分别回读默认目标。
|
||||
- 渠道由 `AGC_UPDATE_CHANNEL` 显式指定,默认 dev;Windows 与 macOS 目标均支持 dev、release 和自定义渠道,目标校验独立进行。
|
||||
- 渠道 `--config` 在 Tauri 构建前最后合并,同时注入 `productName`、`identifier`、updater 端点与窗口标题:安装身份与更新端点必须来自同一个渠道,不能各自回读默认值。macOS 发布入口构建 `*.app`、updater 归档与 DMG 前先按发布渠道解析产品名,产物名一律派生而不写死。
|
||||
- 渠道 `--config` 在 Tauri 构建前最后合并,同时注入 `productName`、`identifier`、`mainBinaryName`、updater 端点与窗口标题:安装身份与更新端点必须来自同一个渠道,不能各自回读默认值。macOS 发布入口构建 `*.app`、updater 归档与 DMG 前先按发布渠道解析产品名,产物名一律派生而不写死。
|
||||
- 渠道配置走 Tauri 的 JSON Merge Patch 语义:对象递归合并,**数组整体替换**。因此 `app.windows` 必须按基线 `tauri.conf.json` 的完整 client 窗口对象下发、只覆盖 `title`(脚本从基线读取后展开);任何"只写 `{ title }`"的写法都会让 `label` / `decorations` / 尺寸回落成 Tauri 默认值(`label=main`、`decorations=true`、800x600),表现为打包产物重新出现系统标题栏,并按 label 连带失效承载平台 HTTP 权限等 capability。守卫用例:`build-release.test.mjs` 的渠道配置合并用例与 `check-config.mjs` 的 `decorations` 门禁。
|
||||
- 定时调度分别判断服务端与客户端 scope:dev 小时调度在提交含 AGC 相关路径时发布对应渠道,纯文档或流水线自身的提交仍只跑 Full Build;release 每日调度在服务端相关路径变化时发布正式 Full Build,在 AGC 相关路径变化时发布 release 客户端,并在同一调度内等待、汇总各 lane 结果,失败 lane 下一轮补发。判定失败或勾选强制触发时按"需要发布"处理。
|
||||
- 更新摘要不再自动生成:发布脚本不读取提交记录生成 `notes`;只有 `AGC_UPDATE_RELEASE_NOTES` 非空时,才把显式手动文案写入渠道清单和旧协议清单的 `releaseNotes`。未设置时清单不携带更新说明,归档文件 `release-notes.txt` 记录“本次没有可用的更新摘要”。
|
||||
@@ -184,10 +186,11 @@
|
||||
|
||||
| 条款 | 验收方式 | 结果 |
|
||||
| --- | --- | --- |
|
||||
| 渠道身份派生与默认渠道不变 | `node --test apps/ai-game-creator-shell/scripts/build-release.test.mjs` | 通过;`dev` 逐字等于基线 `陶泥儿开发版` / `world.genarrative.ai-game-creator`,`release` 使用 `陶泥儿` 并保持独立 identifier,`beta-2` 派生带后缀的产品名与独立 identifier,非法渠道失败关闭 |
|
||||
| 渠道身份派生与默认渠道不变 | `node --test apps/ai-game-creator-shell/scripts/build-release.test.mjs` | 通过;`dev` 逐字等于基线 `陶泥儿开发版` / `world.genarrative.ai-game-creator` / `genarrative-ai-game-creator-shell`,`release` 使用 `陶泥儿` 并保持独立 identifier 与 `-release` 主程序名,`beta-2` 派生带后缀的产品名、identifier 与主程序名,非法渠道失败关闭 |
|
||||
| 身份与端点同批注入 | 同上的渠道 `--config` 用例 | 通过;`productName` / `identifier` 与 `/<channel>-win|mac/latest.json` 来自同一次解析 |
|
||||
| 渠道产物首装包选择 | 同上的渠道 DMG 夹具用例 | 通过;`陶泥儿_<版本>_aarch64.dmg` 仍按 `<版本>_<架构>.dmg` 唯一匹配 |
|
||||
| 基线配置等于默认渠道身份 | `node apps/ai-game-creator-shell/scripts/check-config.mjs` | 通过;基线漂移与非默认渠道身份不隔离都会失败关闭 |
|
||||
| Windows 更新进程与快捷方式隔离 | `build-release.test.mjs` 渠道配置/NSIS 钩子用例 | 通过;dev/release 主程序文件名不同,release 迁移旧 `陶泥儿 Release` 安装目录与快捷方式 |
|
||||
| 全量发布脚本回归 | `node --test build-release.test.mjs release-oss.test.mjs prepare-macos-codex.test.mjs cargo-features.test.mjs` | 通过(64/64,含 macOS 入口按渠道解析产品名的守卫) |
|
||||
| AGC 自有 AppData 提权 ACL 范围 | `cargo test --locked --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml --bin genarrative-ai-game-creator-shell -- config::private_path_elevation_policy_tests` | 通过(12/12;含基线、`<基线>.release`、`<基线>.beta-2` 与相似前缀 `-backup` 的反向断言) |
|
||||
| 渠道身份进入真实构建产物 | `AGC_UPDATE_CHANNEL=release npm --prefix apps/ai-game-creator-shell run build -- --no-bundle --debug` | 通过;Tauri 接受 `productName=陶泥儿` / `identifier=world.genarrative.ai-game-creator.release` 并完成构建;产物字符串实测 `陶泥儿` × 1、`agc/release-win/latest.json` × 1、`world.genarrative.ai-game-creator.release` × 1、`agc/dev-win/latest.json` × 0 |
|
||||
|
||||
Reference in New Issue
Block a user