DeepChat Linux ARM64 支持:从 CI 任务清单到可复用打包工作流的全链路解析
【免费下载链接】deepchat🐬DeepChat - A smart assistant that connects powerful AI to your personal world项目地址: https://gitcode.com/GitHub_Trending/dee/deepchat
本文以 DeepChat 的 Linux ARM64 支持任务清单(docs/features/linux-arm64-support/tasks.md)为主线,完整还原该特性的七项任务(T01–T07)、每项任务在 CI 工作流中的落点,以及配套的验证证据与完成定义(Done Definition)。读完后,你将掌握:如何在 Electron 桌面项目中为 ARM64 Linux 新增原生打包链路、如何用workflow_call可复用工作流统一 Build/Release/回归三条调用方,以及为什么 CUA 插件在linux/arm64上必须被"按契约排除"而不是简单删掉。
背景:为什么需要一份专门的 ARM64 任务清单
在实现之前,DeepChat 仓库里其实已经存在大部分 Linux ARM64 打包原语——Electron Builder 配置、ARM64 原生依赖映射、按架构区分 runtime 的installRuntime脚本(见 package.json 中的installRuntime:linux:arm64、build:linux:arm64等脚本定义)。但当时的问题在于:
- Build 与 Release 工作流只为 Linux x64 排程,硬编码 x64 的 unpacked 输出路径;
- 打包流程无条件捆绑 CUA(Computer Use)插件。
而 CUA 在 Linux ARM64 上是有意不支持的:其锁定的上游 driver 发布版本没有匹配的 ARM64 runtime 资产。因此该特性的目标很明确——在 Build 与 Release CI 中产出 Linux ARM64 应用产物,同时让 CUA 在该目标上保持"隐藏、不捆绑、不验证"。这个契约在 plugins/cua/plugin.json 中有直接证据:engines.targets列表为darwin/arm64、darwin/x64、win32/x64、win32/arm64、linux/x64,不含linux/arm64,即插件可见性门控天然排斥 ARM64 Linux。
任务清单(T01–T07)完整解析
任务清单本身是该文档的核心骨架。T01–T06 已完成(勾选),T07 尚待维护者授权的远端运行,逐项说明如下:
| 任务 | 状态 | 内容要点 |
|---|---|---|
| T01 | 完成 | 在 Build CI 中新增 Linux ARM64 矩阵项:新增原生 ARM64 runner;安装目标架构 runtime 并参数化 unpacked 路径;在 ARM64 上跳过 CUA 捆绑与验证 |
| T02 | 完成 | 在 Release CI 中新增 Linux ARM64:镜像 Build 的矩阵与 CUA 跳过逻辑;上传架构专属构建产物;收集 ARM64 包并更新 Release 元数据 |
| T03 | 完成 | 新增回归覆盖:校验两条工作流的矩阵与输出目录、工作流级 CUA 跳过、保留业务可见性与直接打包拒绝的测试覆盖 |
| T04 | 完成 | 本地验证:跑聚焦测试 + 格式化、i18n、lint 检查 |
| T05 | 完成 | 提交并推送特性分支,手动触发 Linux Build CI 确认 ARM64 job 打包成功,向dev开 Draft PR |
| T06 | 完成 | 将 Linux 打包所有权收敛到单一可复用工作流_package-linux.yml:Build、Release、回归三方复用;生成精确的架构专属包清单与独立的 Linux 更新元数据;用契约测试覆盖调用方、CUA 排除、产物命名与发布组装 |
| T07 | 未完成 | 远端验证可复用工作流:仅在维护者授权后推送;让两个 Linux 目标都跑完 distribution 与 verification 两种模式;确认latest-linux-arm64.yml只引用 ARM64 AppImage |
T01/T02:Build 与 Release 的 ARM64 矩阵
两个调用方工作流现在的写法高度对称,矩阵定义在 build.yml 与 release.yml 中:
# .github/workflows/build.yml(release.yml 的 package-linux job 同理) package-linux: name: build-linux(${{ matrix.arch }}) if: inputs.platform == 'all' || inputs.platform == 'linux' strategy: fail-fast: false matrix: arch: [x64, arm64] uses: ./.github/workflows/_package-linux.yml with: source-sha: ${{ github.sha }} arch: ${{ matrix.arch }} artifact-purpose: distribution enforce-installer-size: falseRelease 侧(release.yml 第 129–148 行)额外要求enforce-installer-size: true,并把source-sha换成 preflight job 解析出的不可变提交needs.preflight.outputs.sha——这保证了发布产物可以回溯到一个精确的 40 位 SHA。
目标矩阵(摘自同目录 spec.md):
| Target | Runner | 应用包 | CUA | Feishu |
|---|---|---|---|---|
linux/x64 | ubuntu-24.04 | 必需 | 捆绑并验证 | 捆绑并验证 |
linux/arm64 | ubuntu-24.04-arm | 必需 | 跳过 | 捆绑并验证 |
T03:契约测试如何"锁住"行为
T03 的回归覆盖对应仓库中的测试文件:test/main/scripts/packageWorkflow.test.ts 断言了 runner 选择表达式(inputs.arch == 'arm64' && 'ubuntu-24.04-arm' || 'ubuntu-24.04')、三条调用方的arch: ['x64', 'arm64']矩阵,以及deepchat-package-linux-arm64等六个架构专属产物名;test/main/build/electronBuilderConfig.test.ts 校验 unpacked 输出目录映射;test/main/plugin/pluginService.test.ts 则覆盖 CUA 的supportedTargets白名单(['darwin/arm64', 'darwin/x64', 'win32/x64', 'win32/arm64', 'linux/x64'])与在linux/arm64运行时上的业务不可见性。
T04:本地验证命令
计划文档 plan.md 明确了本地验证顺序——先跑聚焦的工作流/插件打包测试,再执行仓库级检查:
pnpm run format pnpm run i18n pnpm run lintT05/T07:远端证据的边界
T05 的证据已经记录:Linux ARM64 打包、原生依赖检查、插件验证与产物上传在 Build Application run 29933595490 中通过,ARM64 job 中 CUA 捆绑与验证按预期被跳过,且已开 Draft PR #2006。
T07 之所以仍是未勾选项,是因为可复用工作流迁移(T06)的远端验证依赖维护者授权:必须等授权推送后,两个 Linux 目标在 distribution 与 verification 两种artifact-purpose模式下都成功,并且确认latest-linux-arm64.yml只引用 ARM64 AppImage,迁移才算远端验证完成。这一"本地已验证、远端待验证"的状态在 spec.md 的 Status 一节中被明确标注。
T06 深度解析:_package-linux.yml可复用工作流
T06 是整个特性的架构核心:把原来散落在 Build/Release 中的 Linux 打包逻辑收敛到一个workflow_call可复用工作流.github/workflows/_package-linux.yml,调用方只需声明式传参。
输入契约
on: workflow_call: inputs: source-sha: # 40 位不可变源提交,必需 required: true arch: # x64 或 arm64,必需 required: true artifact-purpose: # distribution 或 verification,必需 required: true enforce-installer-size: # 是否对照已提交的包体积基线,必需(布尔) required: true其中artifact-purpose决定了产物上传策略:distribution调用方上传完整契约产物deepchat-package-linux-${{ arch }};verification调用方只上传诊断信息(deepchat-package-diagnostics-linux-${{ arch }},保留 7 天)。package-regression.yml 正是以verification+enforce-installer-size: true复用同一工作流做定时回归(cron37 18 * * *)。
架构相关的行为差异全部内聚在此
架构专属逻辑只有三处,且都收敛在工作流内部,调用方完全无感:
runs-on: ${{ inputs.arch == 'arm64' && 'ubuntu-24.04-arm' || 'ubuntu-24.04' }} # job 级环境变量: UNPACKED_DIRECTORY: ${{ inputs.arch == 'arm64' && 'linux-arm64-unpacked' || 'linux-unpacked' }}关键步骤链(均按inputs.arch参数化):
安装目标 runtime:
pnpm run installRuntime:linux:${{ inputs.arch }}(对应 scripts/install-runtime.mjs),其后还有installRuntime:duckdb:vss -- --platform linux --arch <arch>与 DuckDB VSS smoke 检查;构建:
pnpm run build(注入 GitHub OAuth 相关 secret 环境变量);CUA 捆绑与验证——仅 x64:
- name: Bundle CUA plugin if: inputs.arch == 'x64' run: pnpm run plugin:bundle -- --name cua --platform linux --arch ${{ inputs.arch }}验证步骤
Verify bundled CUA plugin同样带if: inputs.arch == 'x64'。这就是 T01"ARM64 上跳过 CUA"的工作流级实现;Feishu 双架构共用:
pnpm run plugin:bundle -- --name feishu ...无条件执行,随后统一plugin:verify;打包:
pnpm exec electron-builder --linux --${{ inputs.arch }} --publish=never;包后验证:在
dist/${UNPACKED_DIRECTORY}下验证 DuckDB VSS 扩展、OpenDAL 原生包,并用unshare --net网络隔离跑 Light OCR 离线 smoke;清单与上传:
scripts/ci/package-manifest.mjs生成目标专属清单;distribution 模式上传deepchat-package-linux-<arch>,verification 模式仅上传诊断。
值得注意的是,package.json 中的本地脚本build:linux:arm64与 CI 保持一致的语义:只捆绑 feishu、不捆绑 cua,即"跳过 CUA"这一契约在本地构建与 CI 两条路径上都被遵守。
Release 组装:latest-linux-arm64.yml独立成文
在 release.yml 的assemblejob 中,deepchat-package-linux-arm64作为六个架构专属产物之一被digest-mismatch: error地下载,随后scripts/ci/assemble-release.mjs在 fail-closed 模式下组装:分别发布各架构的 AppImage 与 tarball,并独立生成latest-linux-arm64.yml与latest-linux-x64.yml。从源码结构看,两个 Linux 架构的 updater 元数据从不合并——这正是 spec 验收标准"Release CI 独立保留latest-linux-arm64.yml"的落地方式,也是 T07 远端确认的检查点之一。
CUA 契约:三层防线
CUA 在linux/arm64上不可用由三层共同保证,且不需要新增业务逻辑分支:
- 清单可见性门控:plugins/cua/plugin.json 的
engines.targets不含linux/arm64,业务层插件呈现逻辑据此隐藏该插件; - 直接打包拒绝:打包校验对
linux/arm64的 CUA 请求返回 unsupported-target 错误,对应 spec 验收标准"Direct CUA packaging forlinux/arm64continues to fail with an unsupported-target error"; - CI 工作流级跳过:
if: inputs.arch == 'x64'确保 ARM64 job 根本不执行 CUA 捆绑/验证,配合 T03 的契约测试,使 CI 无法"意外"把 CUA 打进 ARM64 包。
完成定义与验证证据
Done Definition(原文保留于 tasks.md):
- Build 与 Release 工作流都定义了可用的 Linux x64 与 ARM64 job;
- Linux ARM64 应用产物按契约且按 CI 执行排除 CUA;
- Build、Release、package regression 共享同一份 Linux 打包实现;
- 原始 Build CI 与 Draft PR 证据仍然有效;可复用工作流迁移等待维护者授权的远端运行。
Validation Evidence 同样记录在案:打包、原生依赖检查、插件验证与产物上传在 Build Application run 29933595490 通过;ARM64 job 中 CUA 捆绑与验证按预期跳过;Draft PR #2006 已提交。
小结
这份任务清单展示了一个多架构 Electron 桌面项目新增 CPU 架构支持的完整工程范式:先在调用方铺矩阵(T01/T02),再用契约测试钉死行为(T03),本地全量检查(T04),远端跑通一次拿证据(T05),最后把重复实现收敛为单一workflow_call工作流并区分 distribution/verification 两种用途(T06),把无法本地闭环的远端验证显式留成未勾选项(T07)。对 DeepChat 而言,ARM64 的"支持"同时包含了"精确声明哪些能力不支持"——CUA 的三层排除契约保证了这一边界不会被后续改动悄悄破坏。
【免费下载链接】deepchat🐬DeepChat - A smart assistant that connects powerful AI to your personal world项目地址: https://gitcode.com/GitHub_Trending/dee/deepchat
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考