Merge branch 'feat/m139-ciwin-trim-release-ci-to-two-window'
Guards / 依赖许可与来源(cargo-deny) (push) Canceled after 0s
Guards / 文件行数 ≤400 守门 (push) Canceled after 0s
Guards / unsafe 落点守门(集合必须恰好一个文件) (push) Canceled after 0s
Guards / design 零第三方依赖守门 (push) Canceled after 0s
Guards / presenter 零 UI 守门 (push) Canceled after 0s
Guards / core 零 UI 守门 (push) Canceled after 0s
Dev Guards / 架构与合规守门(同 main 口径) (push) Canceled after 0s
Dev Guards / fmt (rustfmt --check) (push) Canceled after 0s
Dev Guards / clippy (ubuntu) (push) Canceled after 0s
Guards / 依赖许可与来源(cargo-deny) (push) Canceled after 0s
Guards / 文件行数 ≤400 守门 (push) Canceled after 0s
Guards / unsafe 落点守门(集合必须恰好一个文件) (push) Canceled after 0s
Guards / design 零第三方依赖守门 (push) Canceled after 0s
Guards / presenter 零 UI 守门 (push) Canceled after 0s
Guards / core 零 UI 守门 (push) Canceled after 0s
Dev Guards / 架构与合规守门(同 main 口径) (push) Canceled after 0s
Dev Guards / fmt (rustfmt --check) (push) Canceled after 0s
Dev Guards / clippy (ubuntu) (push) Canceled after 0s
This commit is contained in:
commit
1a290a15a3
3 files changed
+126
-120
No files matched your search
@@ -1,21 +1,18 @@
|
||||
name: Release
|
||||
|
||||
# 发布流水线:tag `v*` → 四平台(六槽位)矩阵**全部构建** → 单文件产物 + SHA256SUMS
|
||||
# → 上传 artifact + 创建 GitHub Release(pre-release 默认开)。同一 tag 重跑幂等:
|
||||
# Release 已存在时覆盖资产与说明,不再 `gh release create`(见 release job 末步);
|
||||
# 重跑**不碰** pre-release 标记,该标记只在 `inputs.prerelease` 显式给出时才被断言。
|
||||
# 发布流水线:tag `v*` → **只构建两个 Windows 槽位** → 单文件产物 + SHA256SUMS → artifact + GitHub Release
|
||||
# (pre-release 默认开;同 tag 重跑幂等 = 覆盖资产与说明而不 create;重跑不碰该标记,只在显式 inputs.prerelease 时才断言)
|
||||
#
|
||||
# **构建 ≠ 发布**:六槽位一律构建取证,但只有 release job 的 `PUBLISH_SLOTS` 白名单里的槽位会进 Release
|
||||
# 与 SHA256SUMS。当前只有两个 Windows 槽位 —— Linux/macOS 四档从未真构建成功过一次、也没在真机跑过,
|
||||
# 未验证的产物不推给用户(开关与打开办法见该处注释)。
|
||||
# **构建 ≠ 发布**:只有 release job 的 `PUBLISH_SLOTS` 白名单里的槽位才会进 Release 与 SHA256SUMS。
|
||||
# **CI 只跑两个 Windows 槽位**(M139):Linux x64/arm64、macOS arm64/x64 四档从未真构建成功过一次、
|
||||
# 也没在真机跑过,默认**一个都不跑**(省 CI 配额、不留没意义的红叉);要整表六槽位取证走手动入口
|
||||
# `gh workflow run release.yml -f all_slots=true`(槽位表在 `plan` job 里,唯一真相源)。
|
||||
#
|
||||
# 契约唯一真相源:packaging/README.md(命名/目录/运行时依赖/发布白名单)。
|
||||
# 打包本体在 packaging/make_artifacts.py(本地与 CI 同一份脚本,逐字节同布局)。
|
||||
# 手动触发(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」并不矛盾。
|
||||
# 契约唯一真相源:packaging/README.md(命名/目录/运行时依赖/发布白名单);打包本体在
|
||||
# packaging/make_artifacts.py(本地与 CI 同一份脚本,逐字节同布局)。`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:
|
||||
@@ -23,6 +20,10 @@ on:
|
||||
- "v*"
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
all_slots:
|
||||
description: "构建全部六个槽位(含未验证的 Linux/macOS 四档);默认只跑两个 Windows"
|
||||
type: boolean
|
||||
default: false
|
||||
prerelease:
|
||||
description: "标记为 pre-release(仅在 tag ref 上 dispatch 时才生效)"
|
||||
type: boolean
|
||||
@@ -40,51 +41,55 @@ concurrency:
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
# M139:矩阵不写死在 `build` 里,改由本 job 按 `inputs.all_slots` 生成 —— 矩阵不能带 `if`,而
|
||||
# `jobs.<id>.strategy` 可读 `needs`,所以「默认两个 Windows / 手动整表六槽位」用
|
||||
# `fromJSON(needs.plan.outputs.matrix)` 实现。**槽位表只在下面这一处**,改槽位只改这里。
|
||||
plan:
|
||||
name: 选槽位(默认两个 Windows)
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
matrix: ${{ steps.pick.outputs.matrix }}
|
||||
steps:
|
||||
- name: 生成 build 矩阵(`all_slots=true` 才整表六槽位)
|
||||
id: pick
|
||||
shell: bash
|
||||
env:
|
||||
ALL_SLOTS: ${{ inputs.all_slots }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
python3 - "$ALL_SLOTS" >> "$GITHUB_OUTPUT" <<'PY'
|
||||
import json, sys
|
||||
# 槽位表(唯一真相源)。mode:"ci" = 默认在 CI 里构建;"probe" = 未验证,仅 all_slots=true 时构建。
|
||||
SLOTS = [
|
||||
# Windows x64:MSVC + 静态 CRT(+crt-static)→ exe 不依赖 VC++ 可再发行包,双击即用的单文件。
|
||||
dict(slot="windows-x64", os="windows-latest", target="", build_dir="target/release", rustflags="-C target-feature=+crt-static", mode="ci"),
|
||||
# Windows arm64:在 windows-latest(x64 宿主)**交叉编译**到 aarch64-pc-windows-msvc,产物在
|
||||
# target/<triple>/release(故 build_dir 参数化);不用原生 windows-11-arm 的理由见 README §4。
|
||||
dict(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", mode="ci"),
|
||||
# ↓ 四档**未验证,不纳入 CI**:从未真构建成功过一次、也没在真机跑过,默认一个都不编;
|
||||
# `all_slots=true` 时照编(那是将来验证 Linux/macOS 的唯一入口,别删)。真机验证通过后:
|
||||
# 把该行 mode 改成 "ci"(一行一改,不用重写矩阵)+ 槽位键加进 PUBLISH_SLOTS + 同步
|
||||
# packaging/README.md §1/§9 与 release-notes.md 的 published 列 —— 三处不一致即是假话。
|
||||
# Linux 固定 22.04 而非 latest:否则 glibc 地板跟着 runner 漂移(依据见 README §4)。
|
||||
dict(slot="linux-x64", os="ubuntu-22.04", target="", build_dir="target/release", rustflags="", mode="probe"),
|
||||
dict(slot="linux-arm64", os="ubuntu-22.04-arm", target="", build_dir="target/release", rustflags="", mode="probe"),
|
||||
# macOS:latest = arm64;Intel x64 用 macos-15-intel(macos-13 已下线)。
|
||||
dict(slot="macos-arm64", os="macos-latest", target="", build_dir="target/release", rustflags="", mode="probe"),
|
||||
dict(slot="macos-x64", os="macos-15-intel", target="", build_dir="target/release", rustflags="", mode="probe"),
|
||||
]
|
||||
keep = [s for s in SLOTS if s["mode"] == "ci" or sys.argv[1] == "true"]
|
||||
print("matrix=" + json.dumps({"include": keep}, separators=(",", ":")))
|
||||
print("本次构建槽位:" + " ".join(s["slot"] for s in keep), file=sys.stderr)
|
||||
PY
|
||||
|
||||
build:
|
||||
name: build (${{ matrix.slot }})
|
||||
needs: plan
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
# Windows x64:MSVC + 静态 CRT(+crt-static)→ exe 不依赖 VC++ 可再发行包,
|
||||
# 双击即用的单文件形态;UCRT 本身就是 Win10+ 的系统组件。
|
||||
# 产物根 target/release;自检与打包都从 matrix.build_dir 取路径(不硬编码)。
|
||||
- slot: windows-x64
|
||||
os: windows-latest
|
||||
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 已把它列为公开仓库免费 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(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
|
||||
# macOS:latest = arm64;Intel x64 用 macos-15-intel(macos-13 已下线)。
|
||||
- slot: macos-arm64
|
||||
os: macos-latest
|
||||
build_dir: target/release
|
||||
- slot: macos-x64
|
||||
os: macos-15-intel
|
||||
build_dir: target/release
|
||||
matrix: ${{ fromJSON(needs.plan.outputs.matrix) }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
@@ -130,11 +135,9 @@ jobs:
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# M118(D26):**Slint 版停发** —— GUI 来源只有 `unlucky-launcher-iced`;`crates/app` 已在根
|
||||
# Cargo.toml 被 `exclude`,不参与任何 workspace 构建(它连 `--manifest-path` 都编不了)。
|
||||
# 对外产物名由 packaging/make_artifacts.py 的 `asset_stem()` 统一生成
|
||||
# `<名字>_<版本号>_<平台>_<架构>`(下划线分段、不带 `iced` 这类实现细节字样);`LAUNCHER_BIN`
|
||||
# 只用来在构建产物里找文件。
|
||||
# M118(D26):**Slint 版停发** —— GUI 来源只有 `unlucky-launcher-iced`(`crates/app` 已被根
|
||||
# Cargo.toml `exclude`,不参与任何 workspace 构建)。对外产物名由 make_artifacts.py 的
|
||||
# `asset_stem()` 生成 `<名字>_<版本号>_<平台>_<架构>`;`LAUNCHER_BIN` 只用来在产物里找文件。
|
||||
- name: cargo build --release --locked
|
||||
shell: bash
|
||||
env:
|
||||
@@ -152,9 +155,8 @@ jobs:
|
||||
if: runner.os == 'Windows'
|
||||
shell: bash
|
||||
env:
|
||||
# 跨槽位的关键点:产物在 target/<triple>/release 而不是 target/release。
|
||||
# M118:校验的是**构建产物**(iced bin 的原始文件名);对外名 `unlucky-launcher` 由
|
||||
# packaging/make_artifacts.py 在落盘时才换上,那一步之后才存在。
|
||||
# 跨槽位的关键点:产物在 target/<triple>/release;校验的是**构建产物**(iced bin 原始名),
|
||||
# 对外名 `unlucky-launcher` 由 make_artifacts.py 落盘时才换上,那一步之后才存在。
|
||||
EXE: ${{ matrix.build_dir }}/unlucky-launcher-iced.exe
|
||||
run: |
|
||||
set -euo pipefail
|
||||
@@ -179,8 +181,7 @@ jobs:
|
||||
done
|
||||
fi
|
||||
if [ -z "$DUMPBIN" ]; then
|
||||
# 镜像里的 VS 根形如 <年>/<版次>(2022/Enterprise、2022/BuildTools……),
|
||||
# 固定层数的 glob 会在 <年>/<版次> 这两级踩空,所以按路径模式扫。
|
||||
# VS 根形如 <年>/<版次>(2022/Enterprise、2022/BuildTools……),固定层数的 glob 会踩空,按模式扫。
|
||||
for root in "C:/Program Files/Microsoft Visual Studio" \
|
||||
"C:/Program Files (x86)/Microsoft Visual Studio"; do
|
||||
[ -d "$root" ] || continue
|
||||
@@ -263,7 +264,7 @@ jobs:
|
||||
release:
|
||||
name: GitHub Release
|
||||
needs: build
|
||||
# `always()` + `!cancelled()`:白名单外的槽位(Linux/macOS)只是构建取证,它们红了**不能连坐**
|
||||
# `always()` + `!cancelled()`:白名单外的槽位(只有 `all_slots` 取证跑里才存在)红了**不能连坐**
|
||||
# Windows 发布。真正拦发布的是下面「发布白名单齐全性」那一步:白名单里少任何一个就 fail。
|
||||
if: always() && !cancelled() && github.ref_type == 'tag'
|
||||
runs-on: ubuntu-latest
|
||||
@@ -272,11 +273,11 @@ jobs:
|
||||
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 同步成「已发布」——三处不一致即是假话。
|
||||
# 更没在真机上跑过**,未验证的产物不推给用户;它们默认连构建都不跑(M139),只有 `all_slots=true`
|
||||
# 的取证跑里才有产物,留在本次运行的 `dist-<slot>` artifact 里可下载验证,不进 Release/SHA256SUMS。
|
||||
# 将来某槽位真机验证通过后「打开」它需同时改三处(缺一即是假话):① `plan` 槽位表里把它的 mode
|
||||
# 改成 `ci`;② 把槽位键加进这一行(齐全性检查与 SHA256SUMS 自动跟着扩);③ packaging/README.md
|
||||
# §1/§9 与 packaging/release-notes.md 的 Downloads / Support matrix。
|
||||
PUBLISH_SLOTS: "windows-x64 windows-arm64"
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
@@ -318,6 +319,8 @@ jobs:
|
||||
# GUI 与 CLI 两个资产——只按「槽位名出现过」判会被其中一个掩盖。档位比对用下划线形态:
|
||||
# 资产名自 D49 起是 `unlucky-launcher_<ver>_windows_x64.exe`,旧写法 `dist/$prefix-*-$slot*`
|
||||
# (连字符)对现行命名永远匹配不上,已一并修正。
|
||||
# 矩阵裁到两个槽位(M139)后这条检查依然有效:它比的是**下载下来的产物**,不看矩阵大小 ——
|
||||
# 白名单里的槽位没编(比如忘了改 plan 里的 mode)或编挂了,就在这里因缺产物 fail,不会永远过。
|
||||
for slot in $PUBLISH_SLOTS; do
|
||||
stem=${slot//-/_}
|
||||
for prefix in unlucky-launcher ull; do
|
||||
|
||||
+37
-36
@@ -10,15 +10,17 @@
|
||||
|------|---------|-----------|------|---------|
|
||||
| `windows-x64` | ✅ 发布 | `unlucky-launcher_<ver>_windows_x64.exe` | **裸 exe**(双击即用) | exe 单文件;三份合规文本作为并列 Release 资产 |
|
||||
| `windows-arm64` | ✅ 发布 | `unlucky-launcher_<ver>_windows_arm64.exe` | **裸 exe**(同 x64 策略) | 同上;在 x64 宿主上交叉编译到 `aarch64-pc-windows-msvc` |
|
||||
| `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` | 单二进制归档 | 同上 |
|
||||
| `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` 可直吃) |
|
||||
|
||||
约定细节:
|
||||
|
||||
- **「不构建」= CI 默认根本不跑**(M139):那四档未验证,产物不给用户、构建配额也不花;要整表六槽位取证走
|
||||
`gh workflow run release.yml -f all_slots=true`(§3)。发布白名单仍只有两个 Windows 槽位。
|
||||
- **产物命名**:`<名字>_<版本号>_<平台>_<架构>`,下划线分段、**不带实现细节字样**(不出现 `iced`);真相源是 `make_artifacts.py::asset_stem()`。
|
||||
- **"单文件"指可执行文件本身零运行时依赖**(无 WebView、无 JRE、无 sidecar、无 DLL 旁挂);归档里的三份合规文本是许可义务、不是运行时依赖,Windows 因为"一个 exe 装不下文本",
|
||||
把 `LICENSE` / `NOTICE` / `README.md` 作为 Release 的并列资产分发,条款同样随下载走。
|
||||
@@ -74,43 +76,42 @@ python packaging/make_artifacts.py --slot windows-arm64 \
|
||||
|
||||
`--slot` 与宿主槽位不一致时,`ull --version` 冒烟会**自动跳过并打印原因**(arm64 产物在 x64
|
||||
宿主机上根本执行不了;拿"跳过"当通过是假证据,所以跳过永远带原因)——那条路径的验证只能落在
|
||||
CI 真机上:`windows-arm64` 由 cross 构建产物 + M50 的 dumpbin 导入表门禁覆盖,`linux-arm64`
|
||||
由 `ubuntu-22.04-arm` 原生 runner 上真跑冒烟覆盖。
|
||||
CI 真机上:`windows-arm64` 由 cross 构建产物 + M50 的 dumpbin 导入表门禁覆盖;`linux-arm64` 的同类
|
||||
冒烟只在 `all_slots=true` 的取证跑里出现(`ubuntu-22.04-arm` 原生 runner 上真跑 `ull --version`)。
|
||||
|
||||
### CI(四平台六槽位矩阵)
|
||||
### CI(默认只跑两个 Windows 槽位;`all_slots=true` 才整表六槽位)
|
||||
|
||||
`.github/workflows/release.yml`:
|
||||
|
||||
- 触发:`push` tag `v*`;`workflow_dispatch` 只构建不发布(验证矩阵仍编得过)。
|
||||
`inputs.prerelease` **只在 tag ref 上 dispatch 才可达**——Actions 页面的 "Run workflow" 只能选分支,
|
||||
要跑 tag 得 `gh workflow run release.yml --ref v0.2.1`。分支 ref 的 dispatch 与 push 一样被
|
||||
`release` job 的 `if: github.ref_type == 'tag'` 挡在发布之外,所以「dispatch 只构建不发布」
|
||||
与「dispatch 能关 pre-release」是两条互不冲突的规则。
|
||||
- 矩阵(六槽位;`matrix.build_dir` 参数化产物根,脚本不再假设产物一定在 `target/release`):
|
||||
`windows-latest` x64(MSVC + `-C target-feature=+crt-static`)、`windows-latest` **交叉编译**到
|
||||
`aarch64-pc-windows-msvc`(产物在 `target/aarch64-pc-windows-msvc/release`)、`ubuntu-22.04`
|
||||
(glibc 2.35 地板)、`ubuntu-22.04-arm`(原生 ARM64 runner,**与 x64 同 2.35 地板**)、`macos-latest`(arm64)、
|
||||
`macos-15-intel`(Intel x64;`macos-13` 已下线,`macos-26-intel` 为更新替位)。
|
||||
- 触发:`push` tag `v*`;`workflow_dispatch` 只构建不发布,且多一个 `all_slots` 开关(**默认 false =
|
||||
只跑两个 Windows 槽位**,true = 整表六槽位都编一遍取证)。`inputs.prerelease` **只在 tag ref 上 dispatch
|
||||
才可达**——Actions 页面的 "Run workflow" 只能选分支,要跑 tag 得 `gh workflow run release.yml --ref v0.2.1`。
|
||||
分支 ref 的 dispatch 与 push 一样被 `release` job 的 `if: github.ref_type == 'tag'` 挡在发布之外,所以
|
||||
「dispatch 只构建不发布」与「dispatch 能关 pre-release」是两条互不冲突的规则。
|
||||
- 矩阵**由 `plan` job 按 `all_slots` 生成**(`matrix: ${{ fromJSON(needs.plan.outputs.matrix) }}`:矩阵本身
|
||||
不能带 `if`,而 `strategy` 可读 `needs`),槽位表只在该 job 里有一份:`windows-latest` x64(MSVC +
|
||||
`-C target-feature=+crt-static`,产物在 `target/release`)与 `windows-latest` **交叉编译**到
|
||||
`aarch64-pc-windows-msvc`(产物在 `target/aarch64-pc-windows-msvc/release`)标 `mode: ci`(默认编);
|
||||
`ubuntu-22.04`(glibc 2.35 地板)/ `ubuntu-22.04-arm`(原生 ARM64,同地板)/ `macos-latest` /
|
||||
`macos-15-intel` 标 `mode: probe`——**未验证,默认一个都不编**,只有 `all_slots=true` 才进矩阵。
|
||||
- 每个槽位 `cargo build --release --locked`(交叉槽位多两步:`rustup target add` + ARM64 库体检
|
||||
——查 VC 的 `lib/arm64/libcmt.lib`(`+crt-static` 靠它)与 SDK 的 `um/arm64/kernel32.lib`,
|
||||
缺了直接给出"给 VS 加 `VC.Tools.ARM64` 或改用原生 `windows-11-arm`"的可执行提示)→
|
||||
`make_artifacts.py --slot … --build-dir …` → 归档内容自检 → 上传 artifact。
|
||||
- **发布白名单(`PUBLISH_SLOTS`,唯一开关)**:六槽位一律构建取证,只有白名单里的槽位进 Release 与
|
||||
`SHA256SUMS.txt`——当前 = `windows-x64 windows-arm64`;Linux x64/arm64、macOS arm64/x64 四档**从未真构建
|
||||
成功过一次、也没在真机跑过**,不推给用户(产物留在本次运行的 `dist-<slot>` artifact 里取证,它们红了也
|
||||
不连坐 Windows 发布)。手动入口 `workflow_dispatch`(分支 ref)把六槽位整体编一遍、不发布;将来某槽位
|
||||
真机验证通过,把它的键加进这一行即打开(齐全性检查与 SHA256SUMS 自动跟着扩),并同步 §1/§9 与本文件。
|
||||
- **发布白名单(`PUBLISH_SLOTS`,唯一开关)**:默认只构建两个 Windows 槽位,只有白名单里的槽位进 Release 与
|
||||
`SHA256SUMS.txt`——当前 = `windows-x64 windows-arm64`;四档未验证的(默认连构建都不跑)不推给用户。
|
||||
将来某槽位真机验证通过:`plan` 槽位表里把它的 `mode` 从 `probe` 改成 `ci`、把键加进这一行(齐全性检查
|
||||
与 `SHA256SUMS` 自动跟着扩)、再同步 §1/§9 与 `release-notes.md`——三处缺一即是假话。
|
||||
- `release` job:下载全部 artifact → **按白名单裁剪** → 重算 `SHA256SUMS.txt` → 用 `packaging/release-notes.md`
|
||||
模板渲染支持矩阵 → `gh release create`(**pre-release 默认开**:首建时 `push` 触发按 pre-release,`workflow_dispatch` 可关)。
|
||||
- **同一 tag 重跑幂等**:`gh release view` 命中已存在的 Release 时改走 `gh release upload --clobber`
|
||||
+ `gh release edit`,覆盖资产与说明而不是再 `create`(`create` 遇已存在会失败,把流水线最后一步染红)。
|
||||
- **pre-release 标记只按显式输入断言**:`gh release edit` 分支在默认重跑(`push` 触发的 Re-run,
|
||||
`inputs.prerelease` 为空)时**不传** `--prerelease`,所以重跑**不会**翻转标记;只有 tag ref 上的
|
||||
`workflow_dispatch` 显式给了输入才断言——`prerelease=true` → `--prerelease`,`prerelease=false` →
|
||||
`--prerelease=false`。要改标记两条路等价且互不打架:① 走流水线
|
||||
`gh workflow run release.yml --ref v0.2.1 -f prerelease=false`(会落到 edit 分支显式断言)
|
||||
② 直接 `gh release edit <tag> --prerelease=false`(不经流水线;后续默认重跑不碰该标记,
|
||||
不会被翻回去)。首建(`create`)仍保持「pre-release 默认开」的老契约,空输入按 `true` 处理。
|
||||
`workflow_dispatch` 显式给了输入才断言(`prerelease=true` → `--prerelease`,`false` → `--prerelease=false`)。
|
||||
要改标记两条路等价且互不打架:① 走流水线 `gh workflow run release.yml --ref v0.2.1 -f prerelease=false`
|
||||
(会落到 edit 分支显式断言)② 直接 `gh release edit <tag> --prerelease=false`(不经流水线;后续默认重跑
|
||||
不碰该标记,不会被翻回去)。首建(`create`)仍保持「pre-release 默认开」的老契约,空输入按 `true` 处理。
|
||||
|
||||
Windows 为什么用 MSVC 静态 CRT 而不是本机这套 GNU 工具链:两者都属"标准工具链"(D21),
|
||||
但发布产物要**不依赖 VC++ 可再发行包**,`+crt-static` 把 CRT 静态链进 exe,Win10+ 的 UCRT 本身是
|
||||
@@ -149,7 +150,7 @@ Windows ARM64 原生库(Mojang/LWJGL 只发 x64/x86),实际游玩仍走系
|
||||
|
||||
| 依赖 | 说明 |
|
||||
|------|------|
|
||||
| glibc ≥ 2.35 | 由 `ubuntu-22.04` 构建决定;更老的发行版请自行重建或等 musl 版 |
|
||||
| glibc ≥ 2.35 | 由 `ubuntu-22.04` 构建决定(该槽位默认不编,`all_slots=true` 取证跑才有产物);更老的发行版请自行重建或等 musl 版 |
|
||||
| `libxkbcommon.so.0` | winit 键盘处理 |
|
||||
| `libfontconfig.so.1` + `libfreetype.so.6` | 文本渲染 |
|
||||
| `libGL.so.1` / `libEGL.so.1` | Slint 版:femtovg 的 GL 渲染;iced 版:wgpu 的 GL/EGL 后端(**推断,未实测**)。两者缺失都退到 CPU 软渲染(tiny-skia) |
|
||||
@@ -166,7 +167,7 @@ arm64 侧同理(同一份依赖树;历史口径里的「winit + femtovg」
|
||||
### Linux arm64(aarch64)
|
||||
|
||||
依赖与 x64 完全同一套(`libxkbcommon` / `fontconfig` / `libGL` / `libxcb` / `libwayland-client`),
|
||||
**glibc 地板也相同**:arm64 槽位跑在原生 `ubuntu-22.04-arm` runner 上,地板 = **2.35**,与 x64
|
||||
**glibc 地板也相同**:arm64 槽位跑在原生 `ubuntu-22.04-arm` runner 上(默认矩阵不编它,只有 `all_slots=true` 取证跑才出产物),地板 = **2.35**,与 x64
|
||||
用的 `ubuntu-22.04` 一致。选 22.04 而不是 24.04 就是为了这个地板——24.04 的 glibc 更高,会把
|
||||
Debian 12(2.36)、Raspberry Pi OS Bookworm(2.36)这些实际在跑的 ARM 发行版挡在门外。
|
||||
要抬地板(例如将来 ARM 生态整体上移)换 `release.yml` 里那个槽位的 `os` 即可,脚本与产物名都不用动;
|
||||
@@ -334,19 +335,19 @@ runner 上的真跑(本机连 `raw.githubusercontent.com` 都解析不了,
|
||||
|------|---------|------|-----------|
|
||||
| Windows 10/11 x64 | ✅ | 一等 | 无(UCRT 系统自带) |
|
||||
| Windows 11 ARM64 | ✅ | 一等(启动器产物) | 无额外库;启动器原生运行,游戏本体走系统 x64 模拟层 + x64 JDK |
|
||||
| macOS 12+(arm64 / x64) | ❌ 只构建取证 | 一等(未真机验证) | 无第三方库;未签名需去 quarantine |
|
||||
| Linux x64 X11 | ❌ 只构建取证 | 一等(未真机验证) | glibc 2.35+、xkbcommon、fontconfig、libGL、xcb |
|
||||
| Linux x64 Wayland | ❌ 只构建取证 | 支持 | 上述 + wayland-client |
|
||||
| Linux arm64 X11 | ❌ 只构建取证 | 一等(未真机验证) | glibc 2.35+(`ubuntu-22.04-arm` 原生构建,**与 x64 同地板**)、xkbcommon、fontconfig、libGL、xcb |
|
||||
| Linux arm64 Wayland | ❌ 只构建取证 | 支持 | 上述 + wayland-client |
|
||||
| macOS 12+(arm64 / x64) | ❌ 不构建 | 一等(未真机验证) | 无第三方库;未签名需去 quarantine |
|
||||
| Linux x64 X11 | ❌ 不构建 | 一等(未真机验证) | glibc 2.35+、xkbcommon、fontconfig、libGL、xcb |
|
||||
| Linux x64 Wayland | ❌ 不构建 | 支持 | 上述 + wayland-client |
|
||||
| Linux arm64 X11 | ❌ 不构建 | 一等(未真机验证) | glibc 2.35+(`ubuntu-22.04-arm` 原生构建,**与 x64 同地板**)、xkbcommon、fontconfig、libGL、xcb |
|
||||
| Linux arm64 Wayland | ❌ 不构建 | 支持 | 上述 + wayland-client |
|
||||
| Windows 8.1/8/7 | — | 不支持 | 基线已上调(D21) |
|
||||
| Android Termux + X11 | — | 试验级(不承诺) | 仅 CLI(源码自建),GUI 未验证,不在本发布矩阵内 |
|
||||
|
||||
`packaging/release-notes.md` 的 "Support matrix" 表与上表逐行对应(英文版同样带 published / not
|
||||
published 一列,Termux 行标注 experimental)——改一边必须同步另一边,否则标题里的"一致"就是假话。
|
||||
|
||||
两个 arm64 槽位都是**正式矩阵槽位**(不是 Termux 那种源码自建旁路),但**本版只有 `windows-arm64`
|
||||
发布**:`linux-arm64` 由原生 runner 编、尚未真机验证,发布开关就是 `release.yml` 的 `PUBLISH_SLOTS`。
|
||||
两个 arm64 槽位都是**正式矩阵槽位**(不是 Termux 那种源码自建旁路),但本版只有 `windows-arm64` 发布;`linux-arm64` 连构建都不跑
|
||||
(默认矩阵只有两个 Windows 槽位),发布开关是 `release.yml` 的 `PUBLISH_SLOTS`,取证入口是 `all_slots=true`。
|
||||
|
||||
## 10. 已知边界 / 后续
|
||||
|
||||
|
||||
+15
-13
@@ -14,10 +14,12 @@ Asset names are `<name>_<version>_<platform>_<arch>`, underscore separated — t
|
||||
| Windows 10/11 x64 | `unlucky-launcher_{{VERSION}}_windows_x64.exe` | single exe, double-click to run |
|
||||
| Windows 11 ARM64 | `unlucky-launcher_{{VERSION}}_windows_arm64.exe` | single exe, runs natively on ARM64 Windows |
|
||||
|
||||
**This release ships Windows only.** The Linux (x64 / arm64) and macOS (Apple Silicon / Intel) slots are
|
||||
built by CI but are not assets of this release: they have not been verified on real machines yet, so
|
||||
nothing unverified is handed out. They stay out of the download list and out of `SHA256SUMS.txt` until
|
||||
that verification happens — the support matrix below marks them accordingly.
|
||||
**This release ships Windows only, and CI builds Windows only.** The Linux (x64 / arm64) and macOS
|
||||
(Apple Silicon / Intel) slots are not built by the release workflow at all — they have not been verified
|
||||
on real machines yet, so nothing unverified is handed out and no build minutes are spent on them. They
|
||||
stay out of the download list and out of `SHA256SUMS.txt` until that verification happens; a manual
|
||||
workflow run can build all six slots for that purpose, but the four extra slots are never published. The
|
||||
support matrix below marks those slots accordingly.
|
||||
|
||||
The Windows assets are bare `.exe` files, so `LICENSE`, `NOTICE` and `README.md` are attached to this
|
||||
release next to them: the license terms travel with every download. Slots that ship an archive (Linux /
|
||||
@@ -45,19 +47,19 @@ Published = shipped as a download of **this** release, listed in `SHA256SUMS.txt
|
||||
| --- | --- | --- | --- |
|
||||
| Windows 10/11 x64 | **published** | first class | nothing beyond the OS (UCRT is part of Win10+) |
|
||||
| Windows 11 ARM64 | **published** | first class (launcher artifact) | nothing extra; the launcher runs natively, the game itself runs through the OS x64 emulation layer with an x64 JDK |
|
||||
| macOS 12+ Apple Silicon | built by CI, not published | first class (unverified) | nothing; unsigned build, needs the Gatekeeper workaround |
|
||||
| macOS 12+ Intel | built by CI, not published | first class (unverified) | same as above |
|
||||
| Linux x64, X11 | built by CI, not published | first class (unverified) | `libxkbcommon`, `fontconfig`, `libGL` (or software renderer), `libxcb` |
|
||||
| Linux x64, Wayland | built by CI, not published | supported (unverified) | `wayland-client`, `libxkbcommon`, plus the X11 set for XWayland apps |
|
||||
| Linux arm64, X11 | built by CI, not published | first class (unverified) | glibc 2.35+, `libxkbcommon`, `fontconfig`, `libGL`, `libxcb` |
|
||||
| Linux arm64, Wayland | built by CI, not published | supported (unverified) | the above plus `wayland-client` |
|
||||
| macOS 12+ Apple Silicon | not built (unverified) | first class (unverified) | nothing; unsigned build, needs the Gatekeeper workaround |
|
||||
| macOS 12+ Intel | not built (unverified) | first class (unverified) | same as above |
|
||||
| Linux x64, X11 | not built (unverified) | first class (unverified) | `libxkbcommon`, `fontconfig`, `libGL` (or software renderer), `libxcb` |
|
||||
| Linux x64, Wayland | not built (unverified) | supported (unverified) | `wayland-client`, `libxkbcommon`, plus the X11 set for XWayland apps |
|
||||
| Linux arm64, X11 | not built (unverified) | first class (unverified) | glibc 2.35+, `libxkbcommon`, `fontconfig`, `libGL`, `libxcb` |
|
||||
| Linux arm64, Wayland | not built (unverified) | supported (unverified) | the above plus `wayland-client` |
|
||||
| Windows 8.1/8/7 | not built | unsupported | the baseline is Windows 10 |
|
||||
| Android — Termux + X11 | not built (no CI slot) | experimental, not promised | CLI only and only when built from source; GUI unverified |
|
||||
|
||||
Both arm64 rows are formal matrix slots, not the experimental Termux path: Windows ARM64 ships here and
|
||||
is cross-built with the same static-CRT gate as x64; Linux arm64 builds on a native ARM64 runner and
|
||||
joins this list once someone has run it on real hardware. The rows above and the matrix table in
|
||||
`packaging/README.md` §9 are the same list — change one, change the other.
|
||||
is cross-built with the same static-CRT gate as x64; Linux arm64 is kept as a matrix slot but is not built
|
||||
by default — someone has to run it on real hardware (via a manual all-slots run) before it joins this list.
|
||||
The rows above and the matrix table in `packaging/README.md` §9 are the same list — change one, change the other.
|
||||
|
||||
## Install
|
||||
|
||||
|
||||
Reference in new issue
Block a user