feat: 跨平台发布打包,支持 7 个目标平台交叉编译和 tar.gz 分发
- 新增 scripts/release.ts,支持 7 个编译目标(linux/darwin/windows + musl 变体) - 从 build.ts 提取共享构建逻辑到 build-common.ts,现有 build 行为不变 - 使用 tar-stream + node:zlib 创建 tar.gz,精确控制 Unix 权限位 - SHA256 校验和文件格式兼容 sha256sum -c - 支持 --target 参数选择特定平台编译 - 新增 devDependency: tar-stream、@types/tar-stream - 更新 README.md 和 DEVELOPMENT.md 文档 - 同步 openspec specs
This commit is contained in:
132
openspec/specs/cross-platform-release/spec.md
Normal file
132
openspec/specs/cross-platform-release/spec.md
Normal file
@@ -0,0 +1,132 @@
|
||||
## Purpose
|
||||
|
||||
定义多平台交叉编译发布流程,包括目标平台矩阵、可执行文件命名规范、压缩包打包、SHA256 校验和生成、CLI 接口。
|
||||
|
||||
## Requirements
|
||||
|
||||
### Requirement: Release 目标平台矩阵
|
||||
Release 流程 SHALL 支持以下 7 个编译目标,覆盖所有指定平台:
|
||||
|
||||
| Bun CompileTarget | OS | Arch |
|
||||
|---|---|---|
|
||||
| bun-linux-x64 | linux | x64 |
|
||||
| bun-linux-arm64 | linux | arm64 |
|
||||
| bun-linux-x64-musl | linux | x64-musl |
|
||||
| bun-linux-arm64-musl | linux | arm64-musl |
|
||||
| bun-windows-x64 | windows | x64 |
|
||||
| bun-darwin-x64 | darwin | x64 |
|
||||
| bun-darwin-arm64 | darwin | arm64 |
|
||||
|
||||
#### Scenario: 默认全平台编译
|
||||
- **WHEN** 开发者运行 `bun run release` 不带额外参数
|
||||
- **THEN** 系统 SHALL 依次编译上述 7 个目标
|
||||
|
||||
#### Scenario: 指定单一目标编译
|
||||
- **WHEN** 开发者运行 `bun run release --target linux-x64`
|
||||
- **THEN** 系统 SHALL 只编译 `bun-linux-x64` 目标
|
||||
|
||||
#### Scenario: 指定多个目标编译
|
||||
- **WHEN** 开发者运行 `bun run release --target linux-x64,darwin-arm64,windows-x64`
|
||||
- **THEN** 系统 SHALL 编译指定的 3 个目标
|
||||
|
||||
#### Scenario: 无效 target 参数
|
||||
- **WHEN** 开发者传入不存在的 `--target` 值
|
||||
- **THEN** 系统 MUST 报错退出,并列出所有可用的 target 值
|
||||
|
||||
### Requirement: Release 构建流水线
|
||||
Release 流程 SHALL 执行四步流水线:Vite 前端构建 → code generation → 多目标交叉编译 → 打包与校验和。
|
||||
|
||||
#### Scenario: Release 构建顺序
|
||||
- **WHEN** 开发者运行 `bun run release`
|
||||
- **THEN** 系统 MUST 依次执行 Vite build、code generation、多目标 Bun compile、tar.gz 打包和 SHA256 校验和生成
|
||||
|
||||
#### Scenario: Vite 构建失败
|
||||
- **WHEN** Vite build 步骤失败
|
||||
- **THEN** 系统 MUST 停止后续步骤,不执行 code generation 或编译
|
||||
|
||||
#### Scenario: 单目标编译失败
|
||||
- **WHEN** 某个目标的 Bun compile 失败
|
||||
- **THEN** 系统 MUST 停止后续打包,报告失败的目标
|
||||
|
||||
#### Scenario: 前端构建只执行一次
|
||||
- **WHEN** release 流程编译多个目标
|
||||
- **THEN** Vite build 和 code generation MUST 只执行一次,所有目标共用同一份前端产出
|
||||
|
||||
#### Scenario: 构建完成后清理
|
||||
- **WHEN** release 流程完成(无论成功或失败)
|
||||
- **THEN** 系统 SHALL 清理 `.build/` 临时目录
|
||||
|
||||
### Requirement: 可执行文件命名规范
|
||||
Release 产出的裸二进制 SHALL 使用 `dial-server-{version}-{os}-{arch}` 命名,Windows 平台附加 `.exe` 后缀。
|
||||
|
||||
#### Scenario: Linux x64 可执行文件命名
|
||||
- **WHEN** 编译目标为 bun-linux-x64 且版本为 0.1.0
|
||||
- **THEN** 裸二进制文件名 SHALL 为 `dial-server-0.1.0-linux-x64`
|
||||
|
||||
#### Scenario: Windows 可执行文件命名
|
||||
- **WHEN** 编译目标为 bun-windows-x64 且版本为 0.1.0
|
||||
- **THEN** 裸二进制文件名 SHALL 为 `dial-server-0.1.0-windows-x64.exe`
|
||||
|
||||
#### Scenario: musl 变体命名
|
||||
- **WHEN** 编译目标为 bun-linux-x64-musl 且版本为 0.1.0
|
||||
- **THEN** 裸二进制文件名 SHALL 为 `dial-server-0.1.0-linux-x64-musl`
|
||||
|
||||
### Requirement: 压缩包打包
|
||||
每个目标 SHALL 生成一个 tar.gz 压缩包,内含可执行文件、示例配置和许可证。
|
||||
|
||||
#### Scenario: 压缩包命名
|
||||
- **WHEN** 编译 linux-x64 目标且版本为 0.1.0
|
||||
- **THEN** 压缩包文件名 SHALL 为 `dial-server_0.1.0_linux_x64.tar.gz`
|
||||
|
||||
#### Scenario: 压缩包内部目录结构
|
||||
- **WHEN** 解压 `dial-server_0.1.0_linux_x64.tar.gz`
|
||||
- **THEN** 产出目录 SHALL 为 `dial-server_0.1.0_linux_x64/`,内含 `dial-server`(可执行文件)、`probes.example.yaml`(示例配置)、`LICENSE`(许可证)
|
||||
|
||||
#### Scenario: Windows 目标压缩包
|
||||
- **WHEN** 编译 windows-x64 目标且版本为 0.1.0
|
||||
- **THEN** 压缩包 SHALL 使用 `.tar.gz` 格式,内部可执行文件名 SHALL 为 `dial-server.exe`
|
||||
|
||||
#### Scenario: 压缩包内可执行文件权限
|
||||
- **WHEN** 在 Linux/macOS 上解压非 Windows 目标的压缩包
|
||||
- **THEN** 可执行文件 SHALL 具有 0o755 权限(可执行),配置文件和许可证 SHALL 具有 0o644 权限
|
||||
|
||||
#### Scenario: 版本号来源
|
||||
- **WHEN** release 流程执行
|
||||
- **THEN** 版本号 SHALL 从 `package.json.version` 读取,与 build 命令使用同一来源
|
||||
|
||||
### Requirement: SHA256 校验和
|
||||
每个压缩包 SHALL 附带一个 SHA256 校验和文件,格式兼容 `sha256sum -c`。
|
||||
|
||||
#### Scenario: 校验和文件命名
|
||||
- **WHEN** 压缩包为 `dial-server_0.1.0_linux_x64.tar.gz`
|
||||
- **THEN** 校验和文件名 SHALL 为 `dial-server_0.1.0_linux_x64.tar.gz.sha256`
|
||||
|
||||
#### Scenario: 校验和文件内容格式
|
||||
- **WHEN** 读取 `.sha256` 文件
|
||||
- **THEN** 内容 SHALL 为 `<hash> <filename>\n` 格式,其中 `<hash>` 为 64 位小写十六进制字符串,`<filename>` 为对应压缩包文件名,中间以两个空格分隔
|
||||
|
||||
#### Scenario: 校验和正确性
|
||||
- **WHEN** 使用 `sha256sum -c` 命令验证 `.sha256` 文件
|
||||
- **THEN** 校验 MUST 通过
|
||||
|
||||
### Requirement: 产出物目录结构
|
||||
Release 产出物 SHALL 按类型分目录存放在 `dist/release/` 下。
|
||||
|
||||
#### Scenario: 产出物目录布局
|
||||
- **WHEN** release 流程成功完成
|
||||
- **THEN** `dist/release/binaries/` SHALL 包含所有裸二进制文件,`dist/release/packages/` SHALL 包含所有压缩包和校验和文件
|
||||
|
||||
#### Scenario: 清理命令覆盖
|
||||
- **WHEN** 开发者运行 `bun run clean`
|
||||
- **THEN** 系统 SHALL 清理 `dist/release/` 目录
|
||||
|
||||
### Requirement: Release 报告
|
||||
Release 流程完成时 SHALL 输出构建报告,包含各产出物的文件大小。
|
||||
|
||||
#### Scenario: 成功构建报告
|
||||
- **WHEN** release 流程成功完成
|
||||
- **THEN** 系统 SHALL 输出每个裸二进制和压缩包的文件路径和大小
|
||||
|
||||
#### Scenario: 失败构建报告
|
||||
- **WHEN** release 流程失败
|
||||
- **THEN** 系统 SHALL 输出失败的具体步骤和目标平台
|
||||
@@ -7,6 +7,8 @@
|
||||
### Requirement: 生产构建顺序
|
||||
生产构建 MUST 通过三步流水线完成:Vite 前端构建 → code generation → Bun compile。
|
||||
|
||||
构建步骤 1-2(Vite build、code generation)的逻辑 SHALL 从 `scripts/build-common.ts` 导入,`scripts/build.ts` 只保留当前平台编译和编排逻辑。
|
||||
|
||||
#### Scenario: 运行生产构建
|
||||
- **WHEN** 开发者运行生产构建命令
|
||||
- **THEN** 系统 MUST 依次执行 Vite build、资源导入 code generation、Bun.build compile,最终输出单可执行文件
|
||||
@@ -19,6 +21,10 @@
|
||||
- **WHEN** Bun.build compile 步骤失败
|
||||
- **THEN** 系统 MUST 清理 `.build/` 临时目录,不保留 stale executable
|
||||
|
||||
#### Scenario: 重构后 build 行为不变
|
||||
- **WHEN** `scripts/build.ts` 改为从 `scripts/build-common.ts` 导入共享构建函数
|
||||
- **THEN** `bun run build` 的产出文件路径(`dist/dial-server`)、构建步骤顺序和错误处理行为 SHALL 与重构前完全一致
|
||||
|
||||
### Requirement: 单 executable 输出
|
||||
生产构建 SHALL 输出一个 standalone executable,其中包含 Bun 后端和通过 `import with { type: "file" }` 嵌入的 Vite 前端产出。
|
||||
|
||||
@@ -37,13 +43,15 @@
|
||||
### Requirement: 构建中间产物管理
|
||||
构建流程 SHALL 使用 `.build/` 临时目录存放 code generation 产物,构建完成后清理。
|
||||
|
||||
清理逻辑 SHALL 定义在 `scripts/build-common.ts` 中,供 `build.ts` 和 `release.ts` 共用。
|
||||
|
||||
#### Scenario: 构建成功后清理中间产物
|
||||
- **WHEN** 生产构建成功完成并输出 executable
|
||||
- **THEN** 系统 SHALL 删除 `.build/` 临时目录
|
||||
- **THEN** 系统 SHALL 通过 `build-common.ts` 中的 `cleanup()` 函数删除 `.build/` 临时目录
|
||||
|
||||
#### Scenario: 构建失败时清理中间产物
|
||||
- **WHEN** 生产构建在 Bun compile 步骤失败
|
||||
- **THEN** 系统 SHALL 删除 `.build/` 临时目录和 stale executable
|
||||
- **THEN** 系统 SHALL 通过 `build-common.ts` 中的 `cleanup()` 函数删除 `.build/` 临时目录和 stale executable
|
||||
|
||||
### Requirement: 外部运行时配置
|
||||
executable MUST 将环境相关运行时配置保留在嵌入的前端和 server bundle 之外。
|
||||
|
||||
Reference in New Issue
Block a user