feat(release,docs): M149 发布构建烘入微软登录 id(仓库 Secret),文档改为「官方构建开箱即用」

构建侧:release-build.yml 声明 on.workflow_call.secrets.ULL_MSA_CLIENT_ID(required: false),
cargo build 步以 env 注入它,option_env! 把它烘进二进制;release.yml 的 build job 按名显式透传
(与 PUBLISH_TOKEN 同一模式,不用 inherit)。真值放仓库 Secret,不进任何 git 文件;Secret 未录入
或 Actions 之外求值为空串时,client_id.rs 的 blank_env_value_counts_as_missing 保证「空白=没配」,
不会拿空 id 去联网。

文档:README 两版 / help.rs 的 accounts topic / packaging/release-notes.md /
packaging/docs/build-and-ci.md 统一成「官方构建已内置登录所需配置、开箱即用,仍可用环境变量
ULL_MSA_CLIENT_ID 覆盖;自建想自带就构建时注入」的功能性口径 —— 不出现 id 本身,也不出现归属描述。
client_id.rs 的模块注释与测试注释同步(原文写「id 不进仓库(用户定案)」,已随 Secret 方案改写),
并记下「别把 ULL_MSA_CLIENT_ID 导出到跑 cargo test 的 shell」——presenter 的 M132 入口锚会在
已烘焙 id 的构建里故意红。

实测:ULL_MSA_CLIENT_ID=<id> cargo build --bin ull 后,清空 env 跑 ull accounts add msa 打出
用户码与链接(无「未配置」提示);同二进制设一个假 env id 则 AADSTS700016 点名该假 id(env 覆盖生效)。
单测:core auth 28、unlucky-cli 全套、i18n 30、presenter 222 全绿;M132 锚在烘焙构建里按设计红、
在不带 id 的构建里绿。cargo fmt --all --check 通过。
This commit is contained in:
AskaEth committed 2026-11-06 21:08:53 +08:00
1 parent 1c53c29f76
commit 5597a4cc18
8 files changed
+76 -32

No files matched your search

+8
View File
@@ -75,6 +75,14 @@ python packaging/make_artifacts.py --slot windows-arm64 \
逐字搬进 `.github/workflows/release-publish.yml`(同 `workflow_call`,`secrets.GITHUB_TOKEN` 改为调用方显式透传
的 secret)。触发(`on`)、`env`、顶层 `permissions`、`concurrency` 与 `plan` 的槽位表**一字未动**;改槽位仍只改
`release.yml` 那一处(`PUBLISH_SLOTS` 白名单在 `release-publish.yml`,两个 arm64 修复时要改的仍是那两行)。
- **M149 微软登录 id 的烘焙**:`release-build.yml` 的 `cargo build` 步带 `env.ULL_MSA_CLIENT_ID`(值
`${{ secrets.ULL_MSA_CLIENT_ID }}`),`option_env!` 把它烘进二进制,于是发布产物装完即可登录。id **不进
git 文件**:真值放仓库 Secret,由 `release.yml` 的 `build` job 按名显式透传(可复用工作流拿不到未显式传入的
secret;这里刻意不用 `secrets: inherit`——那会把仓库全部 secret 一起透进被调方)。Secret 未录入、或在整个
Actions 之外求值时该表达式为空串,`client_id.rs` 把空白当「没配」⇒ 非官方构建只是不烘 id,不会拿空 id 去
联网;本地自烘仍走 `ULL_MSA_CLIENT_ID=<id> cargo build`。**别把这个 env 导出到跑 `cargo test` 的 shell**:
presenter 的 M132 入口锚会在「已烘焙 id」的构建里**故意红**(它要求一个两处都没有 id 的构建)。
- 发布说明模板(`release-notes.md`)的 "Known limitations" 里,微软登录一条已改为「开箱即用、env 可覆盖」。
Windows 为什么用 MSVC 静态 CRT 而不是本机这套 GNU 工具链:两者都属"标准工具链"(D21),
但发布产物要**不依赖 VC++ 可再发行包**,`+crt-static` 把 CRT 静态链进 exe,Win10+ 的 UCRT 本身是
+9 -7
View File
@@ -100,14 +100,16 @@ Get-FileHash .\unlucky-launcher_{{VERSION}}_windows_x64.exe -Algorithm SHA256
## Known limitations of this build
- Microsoft (MSA) sign-in needs an Azure public client id, and release binaries do not carry one: set
`ULL_MSA_CLIENT_ID=<id>` before launching, or build with that variable set. Without it sign-in stops
- Microsoft (MSA) sign-in works out of the box: this build carries the Azure public client id it needs
(a public client id, not a credential — it ships inside the binary), so there is nothing to configure
before signing in. Setting `ULL_MSA_CLIENT_ID=<id>` before launching still overrides it; the variable
is read at startup, so restart the launcher after changing it. A build with no id anywhere stops
before any network call, and the GUI banner says so plainly: the title "Microsoft sign-in is not
configured", a body naming `ULL_MSA_CLIENT_ID=<id>` (set it, or build with it, then restart the
launcher — a running process does not pick up a new variable) and `Code: msa_not_configured`, with
no Retry button. Every other sign-in failure keeps the generic banner plus its own `Code:` line,
with the full reason only in the launcher log. `ull accounts add msa` prints the same fix on the
command line. Offline profiles and authlib-injector servers need no id.
configured", a body naming `ULL_MSA_CLIENT_ID=<id>` (set it, or build with it, then restart) and
`Code: msa_not_configured`, with no Retry button. Every other sign-in failure keeps the generic
banner plus its own `Code:` line, with the full reason only in the launcher log. `ull accounts add
msa` prints the same fix on the command line. Offline profiles and authlib-injector servers need no
id.
- Binaries are not code-signed / notarized yet: Windows SmartScreen and macOS Gatekeeper warn on first
launch. The checksums above are the integrity reference for now.
- When the macOS slot ships it is the bare binary (single-file promise), not a `.app` bundle: no Dock