feat: prepare versioned production Curio releases
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
# Curio 开发与验收
|
||||
|
||||
此仓库承载 Trove 正式插件与生产软件源。当前包含用于首批验收的简单插件;生产发布以 `source/index.json` 为准,本地测试材料位于 `dist/`。
|
||||
|
||||
## 底座测试套件
|
||||
|
||||
15 个插件工程(14 个插件 ID,其中升级插件有两个版本),覆盖 UI、Host 服务、Rust 原生后端、跨插件服务、可选/必需依赖、版本约束、生命周期、故障恢复和升级回滚。另有 22 个故意无效的安装包和 4 个异常软件源。
|
||||
|
||||
```sh
|
||||
pnpm install --frozen-lockfile
|
||||
|
||||
# 已安装 trove 命令时可省略此变量;也可指向本机 app 仓库构建产物。
|
||||
export TROVE_BIN=/absolute/path/to/app/target/debug/trove
|
||||
pnpm run pack
|
||||
|
||||
# 可选:使用真实底座组件在临时目录自动验证。
|
||||
export TROVE_APP_DIR=/absolute/path/to/app
|
||||
pnpm run verify
|
||||
```
|
||||
|
||||
打包需要 macOS、Rust/Cargo、Node.js 22+、pnpm、Python 3 和 Trove CLI。原生包只面向当前构建机器的架构;安装后的插件无需 Node.js、Python 或 Cargo。SDK 使用仓库内的版本化 `@trove/plugin-sdk@0.1.0` 包,离线复制到 UI 中。
|
||||
|
||||
生成结果:
|
||||
|
||||
- `dist/packages/`:15 个可安装 `.curio` 包。
|
||||
- `dist/index.json`:常规测试源,8 个插件 ID / 9 个版本包。
|
||||
- `dist/faults-index.json`:6 个故障/异常依赖插件,按需安装。
|
||||
- `dist/invalid/`:22 个无效包、4 个异常源及预期错误码。
|
||||
- `dist/verification.json`:自动验证的逐项结果、环境和观察项。
|
||||
|
||||
在 Trove 添加**本地软件源**,选择 `dist/index.json` 的绝对路径,即可安装常规测试插件。若要测试 HTTP 下载:
|
||||
|
||||
```sh
|
||||
pnpm run serve
|
||||
# 在底座添加 HTTP 软件源:http://127.0.0.1:8765/index.json
|
||||
# 用 QA_HTTP_PORT 环境变量更换端口,Ctrl-C 停止。
|
||||
```
|
||||
|
||||
完整步骤、覆盖矩阵与当前限制见 [测试指南](testing.md)。
|
||||
|
||||
插件各自通过 `curio.json.version` 管理版本;公开服务契约版本与底座兼容范围分别维护。历史发布索引只追加版本、禁止覆盖同版本产物,详见 [版本与发布](versioning.md)。`pnpm run release:prepare --base-url <HTTPS 分发目录>` 可准备保留历史的发布材料,`pnpm run test:release` 验证这些约束。
|
||||
|
||||
## 目录
|
||||
|
||||
- `curios/<name>/`:各插件独立 Manifest 与公共服务契约。
|
||||
- `shared/ui/`、`shared/backend/`:测试面板和原生后端源码;构建时复制到各插件。
|
||||
- `source/index.json`:生产软件源与历史版本索引。
|
||||
- `tools/`:构建、打包、测试源和真实底座验证适配器。
|
||||
- `vendor/`:版本化 SDK 分发包与来源说明。
|
||||
|
||||
项目依赖使用 pnpm;插件通过版本化的 `@trove/plugin-sdk` 引用 SDK,不通过 `../app` 引用源文件。仅自动验证适配器通过显式的 `TROVE_APP_DIR` 编译待测底座组件,插件构建与运行不依赖该路径。App 仓库保留协议规范和教学模板。
|
||||
|
||||
## 发布约定
|
||||
|
||||
1. 各插件独立声明版本、平台、依赖与权限。
|
||||
2. 构建并执行 trove curio check / pack。macOS 原生后端使用 Mac Runner 构建。
|
||||
3. 先上传不可变的版本包,再更新索引中的下载 URL、大小和 SHA-256。
|
||||
4. 最后原子发布 index.json。私有 Git 仓库不等于私有下载源;下载地址应符合分发对象的访问权限。
|
||||
|
||||
官网:https://trove.render.ink
|
||||
+120
@@ -0,0 +1,120 @@
|
||||
# Trove 底座测试指南
|
||||
|
||||
本套件是可安装、可运行的验收材料。以当前 Manifest v1、Wire Protocol v1 和 `@trove/plugin-sdk@0.1.0` 为基础;插件 ID 均使用 `dev.trove.qa.*`,不占用正式插件命名空间。
|
||||
|
||||
## 快速验收
|
||||
|
||||
1. 按[开发文档](development.md)执行 `pnpm install --frozen-lockfile`、`pnpm run pack`。
|
||||
2. 在底座添加本地源 `dist/index.json`,先安装「01 · Host 能力检查」「02 · 数据隔离对照」「03 · 原生后端检查」。逐一打开,点击「运行常规检查」。
|
||||
3. 安装「04 · 公共服务提供方」,再安装并打开「05 · 跨插件调用」。提供方没有 UI;调用时才启动。
|
||||
4. 安装「06 · 可选依赖缺失」,检查缺失服务报错的同时 Host 仍然可调用。
|
||||
5. 在 Host 检查页按需执行文件选择、确认对话框、通知、剪贴板、快捷键和窗口操作。结果中「已执行 · 请观察」不代表系统效果已经通过人工验收。
|
||||
6. 使用「保存 JSON 报告」将报告写入本插件的数据目录;结果会显示路径。也可展开「原始报告」查看全部错误码和返回值。
|
||||
|
||||
`pnpm run pack` 会重新构建并覆盖本地生成文件。它不安装插件、不启动桌面应用、不修改官方软件源。源码修改后生成同 ID/版本的新内容,可能被底座的版本不可变校验拒绝;重复开发时先卸载该测试插件,或主动提高版本。
|
||||
|
||||
## 插件矩阵
|
||||
|
||||
| 工程 | ID 后缀 / 版本 | 覆盖与预期 |
|
||||
| --- | --- | --- |
|
||||
| `test-host` | `host` / 1.0.0 | 无后端 UI;SDK 上下文、Unicode/JSON、32 路并发、服务发现、存储/文件 CRUD、错误码、桌面手动操作 |
|
||||
| `test-isolation` | `isolation` / 1.0.0 | 与 host 使用同一个持久化键;读到各自 ID,关闭并重新打开后保留 |
|
||||
| `test-self` | `self` / 1.0.0 | UI 打开时启动后端;`@self`、环境与参数、24 路乱序请求、200 KiB 以上消息、取消/超时、Host 回调、事件 |
|
||||
| `test-provider` | `provider` / 1.0.0 | Backend-only;服务 `dev.trove.qa.provider.probe@1.0.0`;按需启动、20 秒空闲退出 |
|
||||
| `test-consumer` | `consumer` / 1.0.0 | 必需依赖 provider 1.x;公开服务调用、事件、输入/输出契约 |
|
||||
| `test-optional` | `optional` / 1.0.0 | 可选服务不存在;UI 与 Host 正常,缺失服务调用返回 `service.not_found` |
|
||||
| `test-autostart` | `autostart` / 1.0.0 | Backend-only;重启底座后应自动运行,公开服务为 `dev.trove.qa.autostart.probe` |
|
||||
| `test-upgrade-v1` | `upgrade` / 1.0.0 | 安装基线,在面板手动写入升级标记 |
|
||||
| `test-upgrade-v2` | `upgrade` / 1.1.0 | 同 ID 更新;读取 1.0.0 写入的标记,支持回滚验收 |
|
||||
| `test-required` | `required` / 1.0.0 | 故障源:必需服务不存在;当前底座调用时返回 `service.not_found` |
|
||||
| `test-incompatible` | `incompatible` / 1.0.0 | 故障源:要求 provider 2.x;安装 provider 1.x 后调用返回 `service.version_mismatch` |
|
||||
| `test-crash` | `crash` / 1.0.0 | 故障源:按钮让自己的后端 exit 42;观察重启、连续崩溃熔断与手动重试 |
|
||||
| `test-start-timeout` | `start-timeout` / 1.0.0 | 故障源:收到 welcome 但不发送 ready;返回 `provider.start_timeout` |
|
||||
| `test-bad-handshake` | `bad-handshake` / 1.0.0 | 故障源:错误会话令牌;Host 拒绝连接,进程启动失败 |
|
||||
| `test-stubborn` | `stubborn` / 1.0.0 | 故障源:忽略 shutdown;超过 500 ms 宽限期后应被底座终止 |
|
||||
|
||||
每个工程都有自己的 `curio.json`。UI 源文件来自 `shared/ui/`,构建到 `dist/ui/`;Rust 源码在 `shared/backend/`,构建产物复制到各包的 `backend/probe`。生产包包含 SDK、静态资源和所需原生可执行文件,不依赖工作区相邻目录。
|
||||
|
||||
## 生命周期、状态与数据
|
||||
|
||||
- **按需启动**:先安装 provider,不进行任何服务调用;在底座看其未启动。打开 consumer 运行检查后应启动;停止调用约 20 秒后退出,再调用得到新 PID。查询 `host.services.getStatus` 不应启动提供方。
|
||||
- **随底座启动**:安装 autostart,完全退出并重启 Trove。在进行 `info` 调用前,用 Host 检查页的「检查随底座启动的服务」确认 `Available`,或在管理界面确认进程已运行。单纯调用成功不能证明 app-start 生效。
|
||||
- **UI 生命周期**:重复打开同一插件应聚焦已有窗口;关闭后无失效窗口。重开后读取标记仍存在;退出底座应清理所有测试后端、连接和快捷键。
|
||||
- **禁用与卸载**:禁用 provider 后 consumer 调用应报告 `provider.disabled`;启用后恢复。卸载后调用应报告 `service.not_found`。
|
||||
- **崩溃隔离**:安装 crash,先读取 PID,再触发崩溃,读取新 PID。短时间连续崩溃三次后应得到 `provider.crash_loop`。同时操作 Host 与 self 插件,确认未被连带中断;在底座管理页手动重试恢复。
|
||||
- **停止无响应进程**:打开 stubborn,记录 PID,在底座停止或禁用;约 500 ms 宽限期后该 PID 应消失。
|
||||
- **存储隔离**:分别运行 host 与 isolation;两者的 `qa.namespace-owner` 值必须是自己的 ID。后端回调 Host storage 的数据归属后端提供方,不能落到 consumer 的命名空间。
|
||||
|
||||
常规检查只清理自己创建的临时文件/键。`qa.namespace-owner` 与固定的 `qa.backend-roundtrip` 保留供人工检查,报告和升级标记也会保留。存储大小限制测试使用超过 1 MiB 的值;不会填满整个存储配额。剪贴板按钮会替换系统剪贴板;快捷键使用 Cmd+Shift+Option+F9,等待最多 15 秒,并在结束时注销。系统通知是否可见需人工确认。
|
||||
|
||||
## 升级与回滚
|
||||
|
||||
常规软件源同时包含 1.0.0 与 1.1.0;默认安装可能直接选到最新版。要测试完整路径,先手动安装基线包:
|
||||
|
||||
```sh
|
||||
"$TROVE_BIN" curio install dist/packages/dev.trove.qa.upgrade-1.0.0.curio --no-input
|
||||
```
|
||||
|
||||
打开插件,点击「写入升级基线标记」,记录 token,再安装更新:
|
||||
|
||||
```sh
|
||||
"$TROVE_BIN" curio install dist/packages/dev.trove.qa.upgrade-1.1.0.curio --no-input
|
||||
```
|
||||
|
||||
运行中更新应正确暂存或切换,不混用两个版本的 UI 资源。关闭并重新打开后应显示 1.1.0,标记仍由 1.0.0 写入、token 不变。使用底座的版本切换/回滚操作回到 1.0.0,验证数据继续保留。卸载时分别验证保留数据和删除数据,再重装读取。
|
||||
|
||||
## 故意无效的安装材料
|
||||
|
||||
`dist/invalid/cases.json` 列出每个 `.curio` 和应返回的错误码。覆盖 22 种情况:
|
||||
|
||||
- JSON 损坏、未知字段、schemaVersion 不支持、保留 ID、非法版本、引擎不兼容。
|
||||
- UI 缺失、UI/Backend 均未声明、Manifest 路径越界、覆盖保留环境变量。
|
||||
- 没有后端却提供服务、服务命名空间错误、后端/契约文件缺失、契约版本不一致、非法 JSON Schema。
|
||||
- ZIP 路径越界、绝对路径、反斜杠路径、大小写碰撞、符号链接、损坏压缩包。
|
||||
|
||||
`dist/invalid/source-cases.json` 列出 4 种合法索引携带异常下载元数据的情况:SHA-256 错误、大小错误、目标架构不匹配、索引与包身份不一致。它们不加入常规软件源。
|
||||
|
||||
无效安装应有明确错误,已安装列表和当前版本不变化,staging 清理完成。不要将所有 `.curio` 不加区分地批量安装;`dist/packages/` 才是结构合法的测试包。
|
||||
|
||||
## 自动验证
|
||||
|
||||
```sh
|
||||
export TROVE_BIN=/absolute/path/to/app/target/debug/trove
|
||||
export TROVE_APP_DIR=/absolute/path/to/app
|
||||
# 可选:复用现有 Cargo 缓存;默认使用 dist/host-target。
|
||||
export TROVE_QA_TARGET_DIR=/absolute/path/to/app/target
|
||||
pnpm run verify
|
||||
```
|
||||
|
||||
验证流程:
|
||||
|
||||
1. 编译 `tools/host-check.rs`,链接指定 app 仓库的真实 `PackageManager`、`ServiceBus`、`BackendSupervisor` 和 Unix Gateway,禁用桌面特性。
|
||||
2. 用 Trove CLI 的 `protocol test` 检查后端的握手、分片接收、并发请求 ID、结构化错误和优雅退出。
|
||||
3. 在 `/tmp/trove-qa-*` 创建隔离数据目录,安装真实包;验证无效材料、软件源本地/HTTP 下载、持久化、升级/回滚和卸载。
|
||||
4. 通过测试桥将**真实生产 SDK** 连接至真实 Service Bus。直接运行 `shared/ui/checks.js` 中的检查;后端走真实 Unix socket 和原生子进程,不使用 mock 服务。
|
||||
5. 默认策略下检查实际行为,再**单独开启严格契约模式**验证参数和返回值;随后恢复默认模式。测试取消清理、服务禁用、启动超时、认证失败、空闲退出、强制停止、崩溃隔离/熔断。
|
||||
6. 写入 `dist/verification.json`,失败时非零退出;正常结束时停止测试 HTTP 服务、后端进程,删除隔离目录。不会触碰用户的 Trove 安装注册表或现有插件数据。
|
||||
|
||||
首次编译可能需要较长时间。自动结果不等于桌面 WebView/系统交互的完整验收;真实 WebView 注入、窗口视觉、系统权限、快捷键触发、通知展示、app-start 的应用启动调度仍应按上文手动检查。
|
||||
|
||||
## 远程软件源验收
|
||||
|
||||
发布完成后,必须使用底座实际访问的索引 URL 单独验收:
|
||||
|
||||
```sh
|
||||
TROVE_APP_DIR=/absolute/path/to/app pnpm run verify \
|
||||
--remote-source https://downloads.example/source/index.json \
|
||||
--source-id trove-official
|
||||
```
|
||||
|
||||
此模式不读取本地 `.curio`:在新的临时目录中通过真实 PackageManager 从远程刷新索引、下载并安装其中的每个版本,检查 UI 入口,启动安装后的原生后端,再执行 consumer → provider 调用。结果写入 `dist/remote-verification.json`;失败时非零退出,不能视为安装通过。
|
||||
|
||||
当前运行探针适用于生产源中的首批验收插件;后续新增产品插件时,应为它们补充对应的运行验收。故障源包含故意无法启动的后端,不能以全部启动成功作为标准。示例域名须替换为真实分发地址;直接读取私有 Gitea 仓库需要登录,推送源码本身不代表已发布软件源。下载可见性和历史发布管理见 [版本与发布](versioning.md)。
|
||||
|
||||
## 当前能力边界
|
||||
|
||||
- 当前底座默认未调用 `strict_contracts(true)`。公共服务的无效返回值可能直接透传,因此 consumer 面板的「公共服务返回值契约」会报告失败;这是能力探针,不能将其误判成自动通过。验证脚本把默认策略列为观察项,严格模式断言单独标注,不修改底座源码。
|
||||
- 必需依赖与可选依赖目前都在服务调用阶段暴露缺失;不要预设安装器或打开窗口时一定拦截。两个插件用于观察和比较这一行为。
|
||||
- 以实际已注册服务为准。规范草案中的 `host.process`、`host.screen`、`host.keychain`、辅助功能、文件 watch 等未被本套件宣称为已实现;没有用模拟服务填补这些能力。
|
||||
- macOS 原生构建按当前架构出包;另一架构需在对应机器重新构建。自动测试覆盖目标架构拒绝,不验证跨架构二进制执行、签名、公证、真实公网 TLS、断电原子性或系统资源耗尽。
|
||||
- `dist/` 中本地索引包含绝对 `file://` 地址;移动仓库后重新打包生成索引。HTTP 源由 `pnpm run serve` 动态改写为本机地址,仅监听 127.0.0.1。
|
||||
@@ -0,0 +1,68 @@
|
||||
# 插件版本与发布记录
|
||||
|
||||
仓库是 monorepo:**每个 Curio 独立版本、独立兼容范围、独立更新**。不要求一次提交中的所有插件一起升级。
|
||||
|
||||
| 信息 | 唯一来源 | 作用 |
|
||||
| --- | --- | --- |
|
||||
| 插件版本 | `curios/<name>/curio.json` 的 `version` | 底座安装、更新、切换和回滚的版本 |
|
||||
| 公共服务版本 | `services.provides[].version`,与 Contract 的 `version` 一致 | 调用方依赖约束;不兼容接口升级主版本 |
|
||||
| 底座兼容范围 | `engine.trove` | 声明可运行的 Trove 版本;不是插件版本 |
|
||||
| 已发布版本索引 | `source/index.json` | 保存全部历史版本、平台、URL、大小和 SHA-256 |
|
||||
| 源码快照 | Git commit;可打 `<curio-id>/v<version>` tag | 从一个已发布插件版本定位对应源代码 |
|
||||
| 仓库工具版本 | 根 `package.json.version` | 构建/验证工具版本,不用于判断插件是否有更新 |
|
||||
|
||||
例如只修复 `dev.trove.qa.host` 的 UI,应将该插件从 `1.0.0` 升到 `1.0.1`,其他插件保持原版本。服务接口没有变化时,服务版本仍可保持 `1.0.0`。
|
||||
|
||||
## 不可变发布
|
||||
|
||||
一个产物由 **插件 ID + 插件版本 + 平台架构** 唯一标识:
|
||||
|
||||
```text
|
||||
packages/dev.trove.qa.host/1.0.0/any.curio
|
||||
packages/dev.trove.qa.self/1.0.0/aarch64-apple-darwin.curio
|
||||
packages/dev.trove.qa.self/1.0.0/x86_64-apple-darwin.curio
|
||||
```
|
||||
|
||||
同一版本可以补齐另一种架构,但不能替换已经发布的同架构内容。发布后发现问题要发新版本,不能重传覆盖旧文件。回滚切换到已有历史版本,不删除或重写坏版本对应的源码记录。服务有破坏性变更时还需要修改服务主版本和使用方依赖。
|
||||
|
||||
当前 `test-upgrade-v1` 与 `test-upgrade-v2` 是验收专用的双版本样本,共用 `dev.trove.qa.upgrade` ID。普通产品插件应只维护一份当前源码;历史通过 Git 和发布目录保存,不为每次升级复制一个源码文件夹。
|
||||
|
||||
## 准备发布
|
||||
|
||||
先修改需要发布的 Manifest,执行 `pnpm run pack` 和验证。`dist/index.json` 是可反复生成的本地开发索引;不能把它当作历史发布记录。
|
||||
|
||||
```sh
|
||||
# 必须是确定的、可由底座访问的 HTTPS 分发目录;示例域名须替换。
|
||||
pnpm run release:prepare --base-url https://downloads.example/source/
|
||||
pnpm run test:release
|
||||
```
|
||||
|
||||
命令会将本次打包的常规插件合并到生产源 `source/index.json`(源 ID 为 `trove-official`),并在 `dist/release/` 准备同目录结构的上传材料。故障注入插件和无效包不会进入生产源。未确定分发地址时不预先填入不可访问的下载地址。
|
||||
|
||||
校验规则:
|
||||
|
||||
- 从当前包计算大小和 SHA-256,与打包元数据比较,防止索引指向错误内容。
|
||||
- 保留旧版本以及其他架构;不会因为本次只发布部分内容而重建/清空历史。
|
||||
- 同 ID、版本、架构的 SHA-256、大小、URL 必须与历史完全一致;不一致会要求升级插件版本。
|
||||
- 同一已发布版本的 `engine.trove` 不得悄悄变化。
|
||||
- 重复准备相同材料不会改变首次发布日期。
|
||||
- 先完整校验本次所有条目,再复制产物和更新本地索引。
|
||||
|
||||
`--catalog <目录>` 可在隔离目录试运行。正式发布应将 `source/` 的历史索引提交回仓库。该脚本只准备本地材料,不表示上传或远程安装已经成功。
|
||||
|
||||
## 发布顺序
|
||||
|
||||
1. 提交并推送源代码,记录 Git commit;需要时为各插件打独立 tag。
|
||||
2. 构建和验证,准备发布索引;审阅本次新增的版本与产物。
|
||||
3. 上传新安装包,拒绝覆盖已存在且内容不同的文件。
|
||||
4. 从底座实际使用的网络路径下载每个新增包,核对 SHA-256 和大小。
|
||||
5. 最后原子替换远程索引,提交并推送仓库中的发布索引。
|
||||
6. 从该远程源刷新、安装并运行验证;不能用本地文件安装冒充远程源验收。
|
||||
|
||||
发布工作串行进行;两种架构先各自构建,再将产物合并至同一版本。若更新 `shared/ui/` 或 `shared/backend/`,所有受影响且需要重新发布的插件都要增加插件版本,未受影响的插件不必修改。
|
||||
|
||||
## 私有源码与下载认证
|
||||
|
||||
当前 `https://git.render.ink/trove/curios` 是私有源码仓库,匿名访问原始 JSON 会跳转到登录页。推送源代码本身不能使它成为可安装的软件源。
|
||||
|
||||
Trove 当前 HTTP 软件源没有仓库登录凭据配置。生产分发可使用免登录的安装包/索引下载入口,或在底座支持私有软件源认证后使用受保护的入口;不要把访问令牌写进 Manifest、源码索引或下载 URL。源码仓库可保持私有,安装包的可见性单独决定。
|
||||
Reference in New Issue
Block a user