- 根 Cargo.toml `[workspace.package] version` 0.2.1 → 0.2.2;`crates/{agent,app-iced,cli,palette-extract,
presenter}` 里 9 处 intra-workspace path 依赖的 version 约束一并对齐(M137 既定做法)。`crates/app` 是
workspace `exclude` 的 Slint 退役树,manifest 不参与解析,原样保留。
- Cargo.lock 由 cargo 再生成:只有 8 个 `unlucky-*` 成员条目从 0.2.1 变 0.2.2,第三方依赖(含版本号恰好
也是 0.2.1 的 hexf-parse / windows-link / windows-threading / xkeysym / yazi)一字未动。这一步不是可选:
CI 与发布流水线全走 `--locked`(ci.yml:236,274 / release-build.yml:135,142 / make_artifacts.py:50),
lock 不跟就是「tag 一打就红」。
- packaging 文档里的**示例 tag** 跟到 v0.2.2:docs/artifacts-and-version.md 两处(命名规则示例 + 「tag 说
X、产物里写 Y」的事故示例)、docs/build-and-ci.md 三处(`--version v…`、两次 `gh workflow run --ref v…`)、
docs/profiles-and-measurements.md 的「同一槽位现在叫 `unlucky-launcher_0.2.2_windows_x64.exe`」、
make_manifest.py 四处(Usage 示例 / `normalize_version` docstring / `--version` 的 argparse help)。
- **历史注记一律不动**:docs/runtime-deps.md 的「v0.2.1 首次真跑即红在工具链体检」(M140 事故记录)、
`.github/workflows/release.yml:71` 同一事故的另一处记录、`crates/core` 更新模块测试里的样本版本串
(`checker_cases.rs` / `version_cases.rs`,是解析器测试夹具,不是发布事实)、`microsoft.rs:224` 的
`21.0.13.0.2.1` 负例。
- README.md / README.zh-CN.md、packaging/release-notes.md 核实后**无需改动**:三份文件里没有任何写死的
版本号——下载表是 `<version>` / `<版本>` 占位符(M153 刚统一的口径,含非发布档位标「暂未发布」的行,
原样保留未回退),release-notes 正文是 `{{VERSION}}` / `{{SUMS}}` 模板占位符。
验证:`cargo check -p unlucky-cli --all-targets --locked` 过(编译日志里 unlucky-core/agent/cli 均报 v0.2.2)、
`cargo test -p unlucky-cli --lib --locked` 42 passed 0 failed、`cargo metadata --locked --offline` 过(全
workspace manifest + lock 一致)、`python3 packaging/make_manifest.py --self-test` ok、
`ull --version` 实跑输出 `ull 0.2.2(unlucky-cli)`。
5.0 KiB
5.0 KiB
产物矩阵与版本来源(M145 拆自 packaging/README.md)
本文承载原 packaging/README.md 的 §1、§2,节号沿用原编号(全仓 packaging/README.md §N 这类引用照旧有效,
对照表在 packaging/README.md 的索引里)。内容一字未改、只搬家:本行以上是 M145 新增的导航说明,
以下逐行取自原文件。
1. 产物矩阵
| 槽位 | 本版发布 | 产物文件名 | 形态 | 归档内容 |
|---|---|---|---|---|
windows-x64 |
✅ 发布 | unlucky-launcher_<ver>_windows_x64.exe |
裸 exe(双击即用) | exe 单文件;三份合规文本作为并列 Release 资产 |
windows-arm64 |
❌ 不发布(构建照跑取证) | unlucky-launcher_<ver>_windows_arm64.exe |
裸 exe(同 x64 策略) | 同上;CI 仍在原生 windows-11-arm runner 上构建(M140 起不交叉),红了不挡 x64 发布(M142,见 §3) |
linux-x64 |
❌ 不构建(未验证) | unlucky-launcher_<ver>_linux_x64.tar.gz |
单二进制归档 | unlucky-launcher + LICENSE + NOTICE + README.md |
linux-arm64 |
❌ 不构建(未验证) | unlucky-launcher_<ver>_linux_arm64.tar.gz |
单二进制归档(原生 ARM64 runner 构建) | 同上 |
macos-arm64 |
❌ 不构建(未验证) | unlucky-launcher_<ver>_macos_arm64.tar.gz |
单二进制归档 | 同上 |
macos-x64 |
❌ 不构建(未验证) | unlucky-launcher_<ver>_macos_x64.tar.gz |
单二进制归档 | 同上 |
| 每槽位 | 随所属槽位 | ull_<ver>_<平台>_<架构>[.exe] |
裸 CLI 文件(独立资产,不进 tar.gz) | 零 UI 依赖的 ull 本体,进同一份 SHA256SUMS.txt |
| 全平台 | 仅已发布资产 | SHA256SUMS.txt |
校验清单 | 每行 <sha256>␠␠<文件名>(sha256sum -c 可直吃) |
| 全平台 | 仅已发布资产 | manifest.json |
更新清单(D50,见 README.md §13) |
渠道 + 版本 + 各平台产物(target/format/url/size/sha256);生成器 make_manifest.py |
约定细节:
- 「不构建」= CI 默认根本不跑(M139):那四档未验证,产物不给用户、构建配额也不花;要整表六槽位取证走
gh workflow run release.yml -f all_slots=true(§3)。发布白名单只有windows-x64(M142:arm64 照构建、不发布)。 - 产物命名:
<名字>_<版本号>_<平台>_<架构>,下划线分段、不带实现细节字样(不出现iced);真相源是make_artifacts.py::asset_stem()。 - "单文件"指可执行文件本身零运行时依赖(无 WebView、无 JRE、无 sidecar、无 DLL 旁挂);归档里的三份合规文本是许可义务、不是运行时依赖,Windows 因为"一个 exe 装不下文本",
把
LICENSE/NOTICE/README.md作为 Release 的并列资产分发,条款同样随下载走。 - 归档解压后是一个顶层目录
unlucky-launcher_<ver>_<平台>_<架构>/,用户不会解压出一堆散文件。 ull是并列的裸资产,不塞进 tar.gz:headless 用户要的就是「下一个小文件直接跑」;归档里放 LICENSE/NOTICE/README.md 是许可义务,而这三份本来就作为并列 Release 资产分发,裸ull不缺条款。unlucky-launcher本体也认全部 CLI 子命令(M82),ull不是第二个界面,而是不链接图形栈的同一套命令(差异见 §4 与 §7.4),两者不是重复品。 M118:GUI 的构建产物名是unlucky-launcher-iced(crates/app已被 workspaceexclude,不再产出unlucky-launcher);对外文件名仍是unlucky-launcher,改名在make_artifacts.py落盘时(LAUNCHER_BIN找产物 /LAUNCHER_ASSET定对外名),所以下载链接 /SHA256SUMS/ 本文矩阵不变。<ver>不带前导v(tag 是v0.2.2,文件名是0.2.2)——由脚本统一裁剪。- UNIX 归档内
mtime/uid/gid归零、权限固定(二进制 0755、文本 0644), 同源构建的 sha256 不受打包时刻影响。 - 架构不靠猜:脚本打包前回读二进制的可执行文件头(PE 机器码 / ELF
e_machine/ Mach-Ocputype),与槽位声明的架构不符即失败——不会出现"名字是 arm64、内容还是 x64"的假产物。
2. 版本来源(唯一真相源)
版本号只有一个来源:Cargo.toml 的 [workspace.package] version。
<ver>由make_artifacts.py通过cargo metadata --no-deps读出(不是正则扒文件), 任何一个 workspace member 版本不一致时直接失败。- 带 tag 构建时(CI)额外传
--version "$TAG":脚本裁剪v后与Cargo.toml交叉校验, 不一致即失败——避免出现 tag 说 0.2.2、产物里写 0.2.1 的发布事故。 ull --version必报同一版本(脚本打包前跑一次冒烟ull --version断言版本串在其中), 这是env!("CARGO_PKG_VERSION")的实际输出,不是估算。- 发布流程:先改
Cargo.toml版本 + 提交 →git tag v<ver>→ 推送 tag 触发流水线。