chore(release): M137 版本升到 0.2.1,发布只发两个 Windows 槽位
版本:`[workspace.package] version` 0.2.0 → 0.2.1,并把全部 intra-workspace path
依赖的 version 约束一并对齐(`"0.2"` → `"0.2.1"`,M121 的教训)。Cargo.lock 里只有
8 个 unlucky-* 成员条目变化。`crates/app` 是 workspace `exclude` 的 Slint 退役树(manifest
连解析都过不了),不参与解析,故原样保留。
release.yml:新增 `PUBLISH_SLOTS` 白名单(唯一开关)= `windows-x64 windows-arm64`。
六槽位一律构建取证,release job 先按白名单裁掉 Linux/macOS 四档产物再重算 SHA256SUMS,
所以 tag 触发的 Release 只有 4 个资产 + SHA256SUMS.txt。release job 改成
`always() && !cancelled()`:未验证槽位构建失败不连坐 Windows 发布,真正的门禁是白名单
齐全性检查。将来某槽位真机验过后把它加进那一行即打开。
顺手修掉一处从未生效的门禁:齐全性检查的 glob 用的是连字符形态
(`dist/$prefix-*-$slot*`),对 D49 之后的下划线资产名永远匹配不上,改成
`dist/${prefix}_*_${stem}*`。资产命名规则 / SHA256SUMS / 合规文本并列资产 /
`--version` 与 tag 交叉校验一律未动。
packaging/release-notes.md:清掉 v0.1.0 / Slint 时代的说明,Downloads 与 Support matrix
只描述本版实际发布的 Windows 两个槽位(其余标「built by CI, not published」)。
packaging/README.md §1/§3/§9 同步 gate(矩阵加「本版发布」列、§3 写清白名单与打开办法)。
起手顺带把示例 tag 从 v0.2.0 更到 v0.2.1,并把「winit / femtovg」更正为「winit / wgpu」。
This commit is contained in:
1 parent
a03e90fc1a
commit
54b81cbb7f
10 files changed
+192
-161
No files matched your search
@@ -1,17 +1,21 @@
|
||||
name: Release
|
||||
|
||||
# 发布流水线:tag `v*` → 四平台(六槽位)矩阵构建 → 单文件产物 + SHA256SUMS
|
||||
# 发布流水线:tag `v*` → 四平台(六槽位)矩阵**全部构建** → 单文件产物 + SHA256SUMS
|
||||
# → 上传 artifact + 创建 GitHub Release(pre-release 默认开)。同一 tag 重跑幂等:
|
||||
# Release 已存在时覆盖资产与说明,不再 `gh release create`(见 release job 末步);
|
||||
# 重跑**不碰** pre-release 标记,该标记只在 `inputs.prerelease` 显式给出时才被断言。
|
||||
#
|
||||
# 契约唯一真相源:packaging/README.md(命名/目录/运行时依赖)。
|
||||
# **构建 ≠ 发布**:六槽位一律构建取证,但只有 release job 的 `PUBLISH_SLOTS` 白名单里的槽位会进 Release
|
||||
# 与 SHA256SUMS。当前只有两个 Windows 槽位 —— Linux/macOS 四档从未真构建成功过一次、也没在真机跑过,
|
||||
# 未验证的产物不推给用户(开关与打开办法见该处注释)。
|
||||
#
|
||||
# 契约唯一真相源:packaging/README.md(命名/目录/运行时依赖/发布白名单)。
|
||||
# 打包本体在 packaging/make_artifacts.py(本地与 CI 同一份脚本,逐字节同布局)。
|
||||
# 手动触发(workflow_dispatch)默认只跑构建不建 Release —— 用来验证矩阵仍然编得过。
|
||||
# 注意 `inputs.prerelease` 只在 **tag ref** 上 dispatch 才可达:Actions 页面的
|
||||
# "Run workflow" 只能选分支,要跑 tag 得 `gh workflow run release.yml --ref v0.1.0`。
|
||||
# 分支 ref 的 dispatch 与 push 事件一样被 release job 的 `if: github.ref_type == 'tag'`
|
||||
# 挡在发布之外,所以「dispatch 只构建不发布」与「dispatch 可关 pre-release」并不矛盾。
|
||||
# 手动触发(workflow_dispatch)默认只跑构建不建 Release —— 用来把六槽位矩阵整体编一遍取证。
|
||||
# `inputs.prerelease` 只在 **tag ref** 上 dispatch 才可达(Actions 页面只能选分支,要跑 tag 得
|
||||
# `gh workflow run release.yml --ref v0.2.1`);分支 ref 的 dispatch 与 push 一样被 release job 的
|
||||
# `if: github.ref_type == 'tag'` 挡在发布之外,所以「dispatch 只构建不发布」与「dispatch 可关
|
||||
# pre-release」并不矛盾。
|
||||
|
||||
on:
|
||||
push:
|
||||
@@ -50,31 +54,27 @@ jobs:
|
||||
build_dir: target/release
|
||||
rustflags: -C target-feature=+crt-static
|
||||
# Windows arm64:在 windows-latest(x64 宿主)上**交叉编译**到 aarch64-pc-windows-msvc。
|
||||
# 为什么不用 windows-11-arm 原生 runner(GitHub 文档 2026 已把 `windows-11-arm` 与
|
||||
# `windows-11-vs2026-arm` 列为公开仓库**免费**的标准 arm64 runner,原生路线可行):
|
||||
# ① 双 Windows 槽位共用同一套已验证镜像/工具链,tag 重跑行为与既有槽位一致;
|
||||
# ② M50 的 dumpbin 定位链取的是 `Hostx64/x64/dumpbin.exe`,dumpbin 读 ARM64 PE 的
|
||||
# 导入表没问题,而原生 ARM 宿主上那条链得再长一条 `Hostarm64/arm64` 分支——为一个
|
||||
# 槽位放宽刚立的门禁不值得;
|
||||
# ③ 交叉编译产物路径变成 target/<triple>/release,已用 matrix.build_dir 参数化。
|
||||
# 若将来改成原生:只需把 os 换成 windows-11-arm、删掉 target/rustflags 依赖并给 dumpbin
|
||||
# 定位链补 Hostarm64 分支(届时再评估,不在这里预先放宽)。
|
||||
# 不用 windows-11-arm 原生 runner(GitHub 文档 2026 已把它列为公开仓库免费 runner)的理由:
|
||||
# ① 双 Windows 槽位共用同一套已验证镜像/工具链,tag 重跑行为与既有槽位一致;② M50 的 dumpbin
|
||||
# 定位链取 `Hostx64/x64/dumpbin.exe`,它读 ARM64 PE 的导入表没问题,而原生 ARM 宿主上那条链
|
||||
# 还得再长一条 `Hostarm64/arm64` 分支——为一个槽位放宽刚立的门禁不值得;③ 交叉产物路径变成
|
||||
# target/<triple>/release,已用 matrix.build_dir 参数化。将来改原生:os 换 windows-11-arm、
|
||||
# 去掉 target/rustflags 依赖并给 dumpbin 定位链补 Hostarm64 分支(届时再评估)。
|
||||
- slot: windows-arm64
|
||||
os: windows-latest
|
||||
target: aarch64-pc-windows-msvc
|
||||
build_dir: target/aarch64-pc-windows-msvc/release
|
||||
rustflags: -C target-feature=+crt-static
|
||||
# ↓ 下面四档(Linux x64/arm64、macOS arm64/x64)只**构建取证**、不进本次 Release(从未真构建
|
||||
# 成功过一次、也没在真机跑过);发哪几个槽位由 release job 的 `PUBLISH_SLOTS` 白名单唯一决定。
|
||||
# Linux:固定 ubuntu-22.04(glibc 2.35 地板)而不是 latest,
|
||||
# 否则产物的 glibc 底线会跟着 runner 漂移(24.04 的 glibc 明显更高)。
|
||||
- slot: linux-x64
|
||||
os: ubuntu-22.04
|
||||
build_dir: target/release
|
||||
# Linux arm64:公开仓库免费的原生 ARM64 runner(原生构建,不做交叉)。
|
||||
# 用 `ubuntu-22.04-arm` 而**不是** 24.04:与 x64 同 glibc 地板(2.35),
|
||||
# 覆盖 Debian 12 / Ubuntu 22.04 arm64 / Raspberry Pi OS Bookworm(2.36)这类实际在跑的
|
||||
# ARM 发行版;换 24.04 会把地板抬高、把上面前两个挡在门外。该家族标签有
|
||||
# `ubuntu-22.04-arm` / `ubuntu-24.04-arm` / `ubuntu-26.04-arm`,均 4C/16GB、
|
||||
# 公开仓库免费不限量(GitHub 文档 Standard runners for public repositories)。
|
||||
# Linux arm64:公开仓库免费的原生 ARM64 runner(4C/16GB,原生构建不交叉)。用 22.04-arm
|
||||
# 而非 24.04 是为了与 x64 同 glibc 地板(2.35),覆盖 Debian 12 / Ubuntu 22.04 arm64 /
|
||||
# Raspberry Pi OS Bookworm(2.36);该家族标签还有 `ubuntu-24.04-arm` / `ubuntu-26.04-arm`。
|
||||
- slot: linux-arm64
|
||||
os: ubuntu-22.04-arm
|
||||
build_dir: target/release
|
||||
@@ -89,7 +89,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Linux 图形栈构建依赖(winit / femtovg 编译期需要)
|
||||
- name: Linux 图形栈构建依赖(winit / wgpu 编译期需要)
|
||||
if: runner.os == 'Linux'
|
||||
shell: bash
|
||||
run: |
|
||||
@@ -101,8 +101,7 @@ jobs:
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
|
||||
# 只有交叉编译槽位需要额外 target(原生槽位留空 → 本步整体跳过)。
|
||||
# 不把 `${{ }}` 直接拼进 bash:与后面的打包步骤同一纪律,一律经 env 传入再展开。
|
||||
# 只有交叉槽位需要额外 target(原生槽位留空 → 本步跳过);`${{ }}` 一律经 env 传入再展开,不拼进 bash。
|
||||
- name: 追加交叉编译目标 ${{ matrix.target }}
|
||||
if: matrix.target != ''
|
||||
shell: bash
|
||||
@@ -110,9 +109,8 @@ jobs:
|
||||
TARGET: ${{ matrix.target }}
|
||||
run: rustup target add "$TARGET"
|
||||
|
||||
# 交叉链接的前提是镜像里真有 ARM64 的 MSVC 库(VC `/lib/arm64/libcmt.lib`,+crt-static
|
||||
# 就靠它)与 Windows SDK 的 ARM64 导入库(`um/arm64/kernel32.lib`)。缺了照样是失败,
|
||||
# 但先给一句能照做的话,而不是让链接器吐一屏乱码才发现方向:门禁不降级,只把失败说清楚。
|
||||
# 交叉链接的前提是镜像里真有 ARM64 的 MSVC 库(VC `/lib/arm64/libcmt.lib`,+crt-static 就靠它)
|
||||
# 与 SDK 的 ARM64 导入库(`um/arm64/kernel32.lib`):缺了照样失败,只是先给一句能照做的话。
|
||||
- name: Windows ARM64 交叉工具链体检
|
||||
if: matrix.target == 'aarch64-pc-windows-msvc'
|
||||
shell: bash
|
||||
@@ -132,13 +130,11 @@ jobs:
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# M118(D26):**Slint 版停发**。旧写法 `--bin unlucky-launcher` 打的是 `crates/app`
|
||||
# (Slint 退役树)的 bin —— 也就是说这条流水线一直在发 Slint 版二进制,而 D26 早已把
|
||||
# iced 定为产品 UI。现在 GUI 来源只有 `unlucky-launcher-iced`;`crates/app` 也已在根
|
||||
# M118(D26):**Slint 版停发** —— GUI 来源只有 `unlucky-launcher-iced`;`crates/app` 已在根
|
||||
# Cargo.toml 被 `exclude`,不参与任何 workspace 构建(它连 `--manifest-path` 都编不了)。
|
||||
# 对外产物名由 `packaging/make_artifacts.py` 的 `asset_stem()` 统一生成,格式是
|
||||
# `<名字>_<版本号>_<平台>_<架构>`(用户令 2026-11-05):下划线分段,且**不带实现细节
|
||||
# 字样**(产物名里不出现 `iced`)。`LAUNCHER_BIN` 只用来在构建产物里找文件。
|
||||
# 对外产物名由 packaging/make_artifacts.py 的 `asset_stem()` 统一生成
|
||||
# `<名字>_<版本号>_<平台>_<架构>`(下划线分段、不带 `iced` 这类实现细节字样);`LAUNCHER_BIN`
|
||||
# 只用来在构建产物里找文件。
|
||||
- name: cargo build --release --locked
|
||||
shell: bash
|
||||
env:
|
||||
@@ -157,20 +153,16 @@ jobs:
|
||||
shell: bash
|
||||
env:
|
||||
# 跨槽位的关键点:产物在 target/<triple>/release 而不是 target/release。
|
||||
# M118:校验的是**构建产物**(iced bin 的原始文件名)。对外名 `unlucky-launcher`
|
||||
# 由 packaging/make_artifacts.py 在落盘时才换上,那一步之后才存在。
|
||||
# M118:校验的是**构建产物**(iced bin 的原始文件名);对外名 `unlucky-launcher` 由
|
||||
# packaging/make_artifacts.py 在落盘时才换上,那一步之后才存在。
|
||||
EXE: ${{ matrix.build_dir }}/unlucky-launcher-iced.exe
|
||||
run: |
|
||||
set -euo pipefail
|
||||
# +crt-static 是否真的生效,只看导入表:出现 VCRUNTIME/MSVCP/msvcr/ucrtbase 说明还得装
|
||||
# 可再发行包,那就不是"单文件"了,直接 fail。
|
||||
# +crt-static 是否真生效只看导入表:出现 VCRUNTIME/MSVCP/msvcr/ucrtbase 就是还得装可再发行包,fail。
|
||||
#
|
||||
# dumpbin 定位链(三级,全不命中才 fail —— 门禁不降级,只是把"猜路径"换成官方定位):
|
||||
# ① vswhere:VS 官方定位器,安装器自身路径固定,与 VS 版本/版次/安装布局无关;
|
||||
# ② find 兜底:Program Files 与 Program Files (x86) 两个 VS 根都扫(Build Tools 落在 x86 根);
|
||||
# ③ PATH:镜像若已把工具链预置进 PATH 则直接可用。
|
||||
# PATH 排最后是刻意的:PATH 最不可控,官方定位器优先。
|
||||
# Hostx64 的 dumpbin 读 ARM64 PE 的导入表没问题,所以 arm64 槽位共用同一条链。
|
||||
# ① vswhere(VS 官方定位器,安装器路径固定)② find 兜底(两个 VS 根都扫,Build Tools 在
|
||||
# x86 根)③ PATH(镜像预置则直接可用;排最后是刻意的:PATH 最不可控,官方定位器优先)。
|
||||
VSWHERE="C:/Program Files (x86)/Microsoft Visual Studio/Installer/vswhere.exe"
|
||||
DUMPBIN=""
|
||||
VIA=""
|
||||
@@ -208,8 +200,7 @@ jobs:
|
||||
VIA="PATH"
|
||||
fi
|
||||
fi
|
||||
# 工具缺失同样 fail:windows-latest 自带 VS 工具链,基本找得到;
|
||||
# "找不到就跳过"等于让这道门禁在最需要它的时候静默失效。
|
||||
# 工具缺失同样 fail:"找不到就跳过"等于让这道门禁在最需要它的时候静默失效。
|
||||
if [ -z "$DUMPBIN" ]; then
|
||||
echo "::error::找不到 dumpbin,无法校验导入表(静态 CRT 门禁不降级)"
|
||||
exit 1
|
||||
@@ -272,10 +263,21 @@ jobs:
|
||||
release:
|
||||
name: GitHub Release
|
||||
needs: build
|
||||
if: github.ref_type == 'tag'
|
||||
# `always()` + `!cancelled()`:白名单外的槽位(Linux/macOS)只是构建取证,它们红了**不能连坐**
|
||||
# Windows 发布。真正拦发布的是下面「发布白名单齐全性」那一步:白名单里少任何一个就 fail。
|
||||
if: always() && !cancelled() && github.ref_type == 'tag'
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
env:
|
||||
# ── 发布白名单:唯一决定「哪几个槽位进 Release」的开关(空格分隔,键同 matrix.slot)──
|
||||
# 为什么只有两个 Windows 槽位:Linux x64/arm64、macOS arm64/x64 这四档**从未真构建成功过一次、
|
||||
# 更没在真机上跑过**,未验证的产物不推给用户;它们照跑构建,产物留在本次运行的 `dist-<slot>`
|
||||
# artifact 里取证(可下载验证),不进 Release、不进 SHA256SUMS。
|
||||
# 将来某槽位真机验证通过后「打开」它只改这一行(把槽位键加进列表,如 `macos-arm64`):齐全性检查
|
||||
# 与 SHA256SUMS 自动跟着扩;同时把 packaging/README.md §1/§9 与 packaging/release-notes.md 的
|
||||
# Downloads / Support matrix 同步成「已发布」——三处不一致即是假话。
|
||||
PUBLISH_SLOTS: "windows-x64 windows-arm64"
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
@@ -284,23 +286,48 @@ jobs:
|
||||
path: dist
|
||||
merge-multiple: true
|
||||
|
||||
- name: 矩阵完整性 + 重算全量 SHA256SUMS
|
||||
- name: 裁掉白名单外的槽位产物(构建取证 ≠ 发布)
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
# 槽位键 `windows-x64` 落到文件名是 `windows_x64`(make_artifacts.py::asset_stem),故取文件名里的
|
||||
# 「平台_架构」两段跟白名单比:`<名字>_<版本>_<平台>_<架构>[.exe]`。
|
||||
keep=" "
|
||||
for slot in $PUBLISH_SLOTS; do keep+="${slot//-/_} "; done
|
||||
for f in dist/*; do
|
||||
base=${f##*/}
|
||||
[ "$base" = "SHA256SUMS.txt" ] && continue
|
||||
platform_arch=${base%.exe}; platform_arch=${platform_arch%.tar.gz}; platform_arch=${platform_arch#*_*_}
|
||||
case "$keep" in
|
||||
*" $platform_arch "*)
|
||||
echo "publish: $base"
|
||||
;;
|
||||
*)
|
||||
echo "drop: $base($platform_arch 未在真机验证,不进 Release;仍留在 dist-<slot> artifact 里取证)"
|
||||
rm -f "$f"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
- name: 发布白名单齐全性 + 重算全量 SHA256SUMS
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
ls -l dist
|
||||
# 六槽位全齐才发版:缺任意一个就 fail(宁可不出 Release,也不出少一档的 Release)。
|
||||
# 每个槽位都要 GUI 与 CLI 两个资产——只按「槽位名出现过」判会被其中一个掩盖。
|
||||
for slot in windows-x64 windows-arm64 linux-x64 linux-arm64 macos-arm64 macos-x64; do
|
||||
# 白名单内槽位必须**全齐**才发版(宁可不出 Release,也不出少一档的 Release)。每个槽位都要
|
||||
# GUI 与 CLI 两个资产——只按「槽位名出现过」判会被其中一个掩盖。档位比对用下划线形态:
|
||||
# 资产名自 D49 起是 `unlucky-launcher_<ver>_windows_x64.exe`,旧写法 `dist/$prefix-*-$slot*`
|
||||
# (连字符)对现行命名永远匹配不上,已一并修正。
|
||||
for slot in $PUBLISH_SLOTS; do
|
||||
stem=${slot//-/_}
|
||||
for prefix in unlucky-launcher ull; do
|
||||
if ! compgen -G "dist/$prefix-*-$slot*" >/dev/null; then
|
||||
echo "::error::矩阵缺产物:$prefix / $slot"
|
||||
if ! compgen -G "dist/${prefix}_*_${stem}*" >/dev/null; then
|
||||
echo "::error::发布白名单缺产物:$prefix / $slot"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
done
|
||||
# 各平台任务各写一份 SHA256SUMS.txt,合并后只有一份是真的 —— 在 Release 侧重算。
|
||||
# GUI 与 CLI 都要进清单:漏了 ull 就是「发了但没有校验和」。
|
||||
# 各槽位各写一份 SHA256SUMS.txt,合并后只有一份是真的 —— 在 Release 侧按已发布的资产重算。
|
||||
cd dist
|
||||
rm -f SHA256SUMS.txt
|
||||
sha256sum unlucky-launcher_* ull_* > SHA256SUMS.txt
|
||||
|
||||
Reference in new issue
Block a user