首页
/ Motrix 2.0.0-beta.4 发布说明全解:一次"未发布"的 v2 预发布尝试与隔离签名流水线恢复修复

Motrix 2.0.0-beta.4 发布说明全解:一次"未发布"的 v2 预发布尝试与隔离签名流水线恢复修复

2026-09-07 12:53:01作者:魏侃纯Zoe

Motrix 2.0.0-beta.4 是一次并未对外发布的预发布尝试:5 个桌面构建 job 全部成功,但隔离的 Windows 最终处理在 fail-closed 校验阶段终止、macOS 签名环境未获审批、Snap amd64 中途取消,最终没有任何 GitHub Release、容器镜像或 Snap Store revision 产生。本文以仓库 docs/release-notes/2.0.0-beta.4.zh-CN.md 为主体,结合 .gitattributesscripts/release-signing-input.mjsdocs/docker-server.zh-CN.md 等源码与配置,还原这次发布尝试的技术背景、v2 原计划功能范围、恢复修复细节与产物清单,并说明如何在发布说明的历史语境中正确理解该版本。

发布背景:为什么需要保留一份"零分发"的历史记录

beta.4 所在的 Motrix v2 系列是一次整体重构:桌面应用与全新的 Headless Server 共用下载内核,并引入 MDXP 任务交接与沙箱化插件系统。这份发布说明的开头用醒目的 [!IMPORTANT] 块交代了本次尝试的结局——发布未完成、外部分发为零,文档中所有描述均为"原计划范围"的历史记录,而非可用的下载产物。

文档同时给出明确的替代指引:实际使用请改用 2.0.0-beta.5 发布说明(及其后续版本)。同一段落在 beta.5 的说明中亦有呼应——beta.4 说明"保留了前序失败记录"。因此阅读本文及原始文档时,应把 beta.4 视为发布流水线的故障档案与版本演进里程碑,而非可安装的软件版本。

本次发布尝试的执行结果:一次逐步 fail-closed 的流水线

从源码与发布说明可以拼出这次发布尝试的完整轨迹:

  • 5 个桌面构建 job 全部成功:macOS arm64/x64、Windows x64、Linux arm64/x64。Windows 的 LF 固定修复使全部 10 个固定摘要的签名控制文本在 Windows checkout 后保持 canonical LF,固定 SHA-256 校验通过。
  • Windows 隔离 finalize 在读取任何 Authenticode secret 前 fail closed。失败根因是清单排序约定不一致:真实签名 manifest 包含 2,434 个无重复条目,按目录优先的 DFS 顺序排列;而 verifier 要求每个 canonical 相对路径按全路径字典序排列。首个逆序出现在 js-yaml/lib/schema/… 目录下的条目排在同级文件 js-yaml/lib/schema.js 之前,触发了校验失败。
  • macOS 签名环境未获审批,两个 macOS finalize job 被取消;Snap amd64 在 strict build 期间取消(arm64 已成功构建并上传)。
  • 由于 finalize 阶段整体失败,assemble、GitHub Release、R2 更新数据源发布、container publish、Store upload 与 latest/edge release 均未执行——这也解释了为何产物矩阵中的镜像地址需要与"并未发布"的声明并列阅读。

这一"先构建、后隔离校验、任一环节失败即整体停止"的顺序,正是仓库在隔离签名管线中反复强调的 fail-closed 设计(详见下文对 verifier 源码的解读)。

已包含的发布恢复修复:把字节确定性带进隔离签名管线

发布说明列出的四类恢复修复,全部指向同一个目标:让发布产物可复现、可验证、可被审计

text eol=lf:Windows checkout 的字节稳定性

.gitattributes 中把全部 10 个固定摘要的隔离签名控制文本路径声明为 text eol=lf,使 Windows checkout 保留 canonical LF 字节,同时不放宽原始字节 SHA-256 校验。

仓库根目录 .gitattributes 正是文档描述的实现。文件开头注释解释了设计动机:这些文件"byte-for-byte hash-pinned"(逐字节固定摘要),需要让 Windows 上的 checkout(默认 autocrlf)与提交的 blob 保持字节一致。第 9–18 行恰好列全了这 10 个控制文本:

  • electron-builder.signing.json
  • build/entitlements.mac.plist
  • build/installer.nsh
  • scripts/release-signing-tool/package.jsonpackage-lock.json
  • scripts/electron-package-size-budgets.json
  • scripts/electron-package-utils.mjs
  • scripts/before-build-use-staged-dependencies.mjs
  • scripts/native-binary-target.mjs
  • scripts/release-signing-input.mjs
  • scripts/verify-electron-package.mjs

与之配套,同一文件第 5 行把 THIRD_PARTY_LICENSES/** 声明为 -text,即彻底禁用换行转换,保证第三方许可文本在三种平台 checkout 后与提交 blob 逐字节相同。两者共同构成"签名/许可输入在跨平台传递中不被隐式改写"的防线,而摘要校验仍然严格——eol=lf 只是固定了 checkout 表示,并未放宽对原始字节 SHA-256 的验证。

隔离交接前的 commit 信息保留与依赖补全

  • 保留完整触发 commit 信息:在进入隔离最终处理前,为 Windows signing-input 交接保留触发 commit 的完整信息。这一点在 scripts/release-signing-input.mjs 的 manifest 结构中得到印证——verifier 会校验 manifest.commit 必须与 job 传入的 options.commit 完全一致(第 772–784 行),任何不匹配都会导致校验抛错并中止。没有完整的 commit 信息,就无法建立"产物来源于哪个源码版本"的可追溯链条。
  • 补全 Electron runtime 依赖:确保打包后的桌面应用包含启动时所需的 module。仓库维护了一份显式的运行时依赖清单 scripts/electron-runtime-dependencies.json,其中 common 段列出了所有受支持目标共用的打包期模块(如 @motrix/mdxpbetter-sqlite3electron-updaterquickjs-emscriptenwsundicizod 等),并按平台细分 required/optional 依赖(例如 darwin 的 @resvg/resvg-wasm 为必需、electron-liquid-glass 为可选)。这类"显式声明 + 打包校验"的组合(对应脚本 scripts/verify-electron-package.mjs)正是用来防止运行时才发现缺 module 的手段。
  • 暂存已确定的 Snap 产物:在发布到 Store 前,先暂存经过验证且确定的 amd64arm64 两份 Snap 产物,避免发布环节对构建产物的竞态依赖。

verifier 源码中的 fail-closed 校验链

scripts/release-signing-input.mjs 提供了上述修复的可执行实现,值得细读其 verifySigningInput(第 754–824 行)暴露的验证链:

  1. manifest 元数据强校验schemaVersioncommittarget.platform/arch/keytools.electron/tools.electronBuilder 版本、limits 均须与 job 逐项相等,否则抛 signing input manifest metadata does not match the job(第 772–785 行)。
  2. 清单排序与唯一性校验:verifier 要求 manifest.files 中每个 entry 的 path 排序后与去重后完全一致,否则抛 signing input file inventory must be sorted and unique(第 792–799 行)——这正是 beta.4 中"2,434 条目、目录优先 DFS 顺序"与"全路径字典序"不一致而 fail 的规则所在;到了 beta.5,creator 改用完整路径 code-unit 排序修复了同级文件与子目录条目的先后次序(对比 2.0.0-beta.5 发布说明 的对应修复条目)。
  3. 实际目录与 manifest 逐字节比对:重新对目录做 inventory,与 manifest 记录比对(第 811–819 行),杜绝"清单与实际不符"。
  4. 受信输入摘要校验verifyTrustedInputDigests(第 560 行起)按 TRUSTED_INPUT_SHA256 常量表逐一比对受信控制文件(文件头第 36–73 行列出了 electron-builder.signing.json、各类 .icns/.ico/.bmp 资源、installer.nsh 等的固定 SHA-256);assertSafeTree(第 302 行起)则对目录树做路径安全断言。

任何一步不通过都会抛出异常,主入口将其打印后置 process.exitCode = 1(第 833–835 行)——这就是"fail closed"的落地形态:在读取任何 Authenticode secret 之前,任何与预期不符的输入都会让流水线整体终止

v2 原计划的主要变化:重构全景

发布说明的"主要变化"一节勾勒了 v2 的整体蓝图,其中每一条都能在当前仓库结构中找到对应实现(需要说明:beta.4 记录的是当时规划,仓库代码随后续 beta 持续演进)。

桌面应用从头重建

使用 Electron 43、React 19 和 TypeScript 7 从头重建桌面应用,提供可自定义 Dashboard、深色模式、跨平台应用菜单,以及更清晰的任务检查器反馈。

注意这里的版本号是 beta.4 时代的快照。当前仓库根目录 package.json 中 devDependencies 已演进为 Electron 44.1.1(第 108 行)、React ^19.2.8(第 154 行)、TypeScript ~7.0.2(第 115 行)——与 scripts/release-signing-input.mjs 中冻结的 ELECTRON_BUILDER_VERSION/ELECTRON_VERSION26.15.7/44.1.1)一致。UI 部分对应 src/renderer/componentsrouteshookslayouts 等),跨平台应用菜单与任务检查器在 src/main/menusrc/core/inspector-activity 等模块实现。

共用与宿主无关的下载内核

桌面应用和全新的 Node/Web Server 共用与宿主无关的下载内核,支持 SQLite session 恢复、Tracker 管理、UPnP/NAT-PMP,以及 HTTP、FTP、BitTorrent 和磁力链接下载。

仓库把与 UI 无关的核心逻辑集中放在 src/core 下,可见其模块划分与文档一一对应:

  • SQLite session 恢复src/core/session/(如 session-manager.tsmotrix-database.tsmigrations/)负责会话与数据库;Engine 侧目录 src/core/engine/ 提供监督与任务选项。
  • Tracker 管理src/core/tracker/(共 11 个文件)。
  • UPnP/NAT-PMPsrc/core/nat/settings-nat-provider.tssrc/main/nat/
  • 多协议下载src/core/task/src/core/torrent/,BT/磁力解析在 src/core/torrent/ 下。

"与宿主无关"体现在共享模块可同时被桌面主进程与 Server 端复用——桌面进程入口 src/main/index.ts 与 Server 入口 src/server/index.ts 分别装配,但底层能力统一收敛于 src/core

MDXP 任务交接与 device-code 配对

官方 CLI 和浏览器任务交接统一使用 MDXP,并支持本地安全发现及远程 Server 的 device-code 配对。

MDXP(Motrix 的跨端交接协议)贯穿 src/core/bridgesrc/main/bridgesrc/server/bridge,配套 src/core/bridge/mbp1/ 协议实现、web-socket-bridge-server.ts 与证书固定的 *.pem 文件。CLI 与浏览器扩展交接、device-code 配对、配对提示与撤销流程在 e2e/bridge 下有可直接阅读的 Playwright 用例(如 pair-and-submit.spec.tsremote-extension-wss.spec.ts)。

QuickJS 插件沙箱与签名插件

提供带能力授权的 QuickJS 插件沙箱、已签名的内置插件和应用内插件市场。

QuickJS 沙箱对应 src/core/plugin/ 下能力模块的 src/core/plugin/capabilities/host/runtime/permissions/grants/,运行时依赖 quickjs-emscripten(已列入 scripts/electron-runtime-dependencies.json 的 common 依赖)。签名机制可参考 scripts/builtins-signing.pub.pemsrc/shared/builtin-signing.ts,插件市场相关命令位于 src/main/plugin/src/server/plugin/

面向 NAS 的持久化 Server 容器

面向 NAS 和家庭服务器提供持久化、多架构 Server 容器,原计划同时发布到 Docker Hub 与 GHCR。

容器镜像的发布形态在仓库 docs/docker-server.zh-CN.md 中有详细说明:正式带 tag 发布会把同一镜像发布到两个 registry——docker.io/motrixapp/motrix-serverghcr.io/agalwood/motrix-servercompose.yaml 通过 MOTRIX_IMAGE 环境变量(默认 motrixapp/motrix-server:latest)选择镜像源,并内置非 root 用户、只读根文件系统、no-new-privileges、数据/下载卷与 MDXP 端口等部署参数。beta.4 阶段并未真正发布这两个地址的镜像,这一点以发布说明原文为准。

重建发布流水线

隔离 macOS 签名步骤,并明确支持未签名的 Windows 最终处理,同时加入安装包验证、第三方声明和 SPDX SBOM。

对应脚本散落在仓库 scripts 目录:before-pack-verify.mjsverify-electron-package.mjsgenerate-third-party-notices.mjs(配套 scripts/third-party-notices.config.json 与生成的 THIRD_PARTY_NOTICES.zh-CN.md)、verify-snap-artifact.mjsverify-appimage-artifact.mjsverify-container-publication.mjs 等。spdx/SBOM 相关配置见 electron-builder.json 与 Dockerfile 上下文。

预发布测试须知与测试项

发布说明明确把本版本定性为预发布软件,并列出了两条对用户至关重要的安全边界:

  1. 安装前备份现有 Motrix 应用数据与下载文件;v2 尚处于"从头重建"阶段,Motrix v1 数据的迁移路径未经验证,禁止让 beta 使用唯一一份 v1 数据。
  2. 并行测试:条件允许时,通过独立的系统账户、设备或 Docker 数据目录与现有环境并行测试 v2,不要让 beta 成为重要下载文件的唯一存储位置。这条建议在 Docker 部署语境下对应 docs/docker-server.zh-CN.md 中关于数据目录与 MOTRIX_DATA_DIR 的隔离说明。

原计划的测试项聚焦三块:

  • 下载协议覆盖:HTTP、FTP、BitTorrent 与磁力链接下载,包括暂停/继续与 session 恢复。
  • 交接与插件:桌面集成、通过 MDXP 的浏览器和 CLI 任务交接、沙箱化插件。
  • Server 形态:Headless Server 部署、数据持久化与远程配对。

这些测试项与当前仓库 e2etests 下覆盖下载生命周期、会话恢复、bridge 配对的用例类型高度对应,可作为验证 v2 稳定性的检索起点。

原计划下载与容器产物矩阵(均未实际发布)

下表完整继承自发布说明,标示了当时规划的分发矩阵。文档特别注明这些产物 并未发布,仅供理解 v2 的分发规划:

发布方式 架构 原计划产物
macOS 12 或更高版本 arm64(Apple Silicon)、x64(Intel) DMG 和 ZIP
Windows x64 NSIS 安装包(.exe)和 ZIP
Linux x64arm64 DEB 和 RPM
Docker Hub / GHCR linux/amd64linux/arm64 两个 registry 中均发布不可变 tag 2.0.0-beta.4
Snap Store amd64arm64 latest/edge

容器地址(原计划):docker.io/motrixapp/motrix-server:2.0.0-beta.4ghcr.io/agalwood/motrix-server:2.0.0-beta.4。若在镜像源中检索这些 tag 返回 404 或 manifest unknown,属于预期结果——正如 docs/docker-server.zh-CN.md 所述,首个实际发布容器镜像的版本出现前不应期待镜像存在,也不要改拉取未经校验的替代镜像。需要理解镜像 tag 语义与数据持久化/网络/升级方法时,可查阅该部署指南。

已知发布限制

发布说明在"已知发布限制"中明确列出了 beta.4 的范围边界,这些内容不应被误读为遗漏:

  • 未发布 AppImage;Flatpak 已单独验证,但未随该版本 tag 发布。
  • 不提供 Windows arm64 与任何 32 位安装包
  • 原计划的 Windows 安装包不会进行 Authenticode 签名,可能触发 Windows SmartScreen 警告——由于本次发布整体未完成,实际并未产出 Windows 安装包。
  • 原计划的 beta container tag 是不可变的,不会更新 lateststable 或其他稳定版浮动 tag。这与当前 docs/docker-server.zh-CN.md 中"预发布版本不更新 floating tag、只有两个 registry 的不可变 manifest digest 一致后才推进浮动 tag"的现行规则一脉相承。

从 beta.4 到 beta.5:发布问题的接力修复

理解 beta.4 的最佳方式是与 2.0.0-beta.5 发布说明 对照阅读:beta.5 明确记录了"排序不一致"修复的完整方案——在序列化前以完整相对路径为 key,把每份 Windows signing-input manifest 按 canonical code-unit 顺序排序,creator 在 inventory 收集完成后做一次全局排序,verifier 使用同一 comparator。这会让同级文件 js-yaml/lib/schema.js 排在 js-yaml/lib/schema/… 目录条目之前,取代目录优先的 DFS 顺序,同时保持路径唯一性、路径安全、固定摘要验证与 fail-closed 隔离不变。

由此可以清晰看到这一版发布恢复修复的演进脉络:beta.4 定位并暴露了 manifest 排序语义的分歧,beta.5 给出了 creator 与 verifier 统一排序规则的修复。这也是系列发布说明作为"发布流水线工程档案"的独特价值——它记录了真实发布系统中字节级可复现性(eol=lf)、可审计交接(commit 溯源)、fail-closed 验证(摘要与清单强校验)等生产级工程实践。

反馈与后续追踪

按发布说明的建议,遇到可复现问题时应向仓库提交 Issue,并附上操作系统、架构、安装包类型与复现步骤——这些信息对定位隔离流水线问题尤为关键(beta.4 的排序失败正是因为真实 manifest 与 verifier 预期不一致才暴露)。进一步追溯该版本技术细节时,可在仓库中顺藤摸瓜阅读以下文件:

登录后查看全文
热门项目推荐
相关项目推荐