27 KiB
CTMS Desktop Release Stabilization Checklist
状态: active
适用范围: Web、macOS Desktop 与 Windows x64 Desktop 统一客户端发布
最后更新: 2026-07-17
本清单用于第一、二阶段桌面端能力完成后的准发布稳定化。当前允许按 docs/desktop-local-cache-plan.md 引入在线辅助本地缓存,但不引入离线登录、离线写入、本地业务权威数据、内嵌后端服务或离线同步。
1. 发布链路门禁
发布候选提交必须从同一 Git 提交构建 Web 与 Desktop 制品,并完成以下检查:
cd frontend
npm ci
npm run version:check
npm run release:env:check
npm run runtime:check
npm run desktop:release:check
npm run ui:contract
npm run type-check
npm run test:unit
npm run build
npm run desktop:build:app
正式发布还必须确认:
frontend/package.json、package-lock.json、Tauri 配置、Cargo manifest/lock 版本一致。VITE_BUILD_CHANNEL=release和VITE_BUILD_COMMIT=<release tag commit>由 CI 注入,且npm run release:env:check通过。- 在正式 release tag 环境中执行
npm run desktop:release-readiness:check,确认 tag、构建元数据、当前精确版本的平台签名策略、updater 私钥和生产 artifact HTTPS 基址齐备。 - macOS app 已完成 Apple 签名/公证;若当前精确版本获批平台签名例外,则已验证
Signature=adhoc、确认未公证并附带 Gatekeeper 风险说明。 - Windows 应用和 NSIS 安装器已使用组织证书签名并带有效 RFC 3161 时间戳,
Get-AuthenticodeSignature返回Valid;若当前精确版本获批例外,则应用和安装器必须返回NotSigned并附带 SmartScreen 风险说明。 - updater
.sig使用组织 CI secret 或密钥库中的私钥生成,私钥未进入仓库。 - 始终设置
TAURI_SIGNING_PRIVATE_KEY、TAURI_SIGNING_PRIVATE_KEY_PASSWORD和REQUIRE_UPDATER_SIGNING=true;默认 macOS 路径再设置 Apple 变量和REQUIRE_DESKTOP_SIGNING=true,例外路径则设置DESKTOP_PLATFORM_SIGNING_MODE=unsigned-exception、ALLOW_UNSIGNED_PLATFORM_RELEASE=true并执行npm run desktop:build:macos-unsigned-release -- --ci。 - 默认 Windows 路径设置 PFX、密码、
WINDOWS_TIMESTAMP_URL和REQUIRE_WINDOWS_SIGNING=true;例外路径不得伪装签名状态,构建后必须对应用和安装器验证NotSigned。 - 正式 updater feed 使用
--artifact <CTMS.app.tar.gz>和--platform-artifact windows-x86_64=<CTMS.nsis.zip>汇总生成同一个latest.json与SHA256SUMS.txt。 - 正式 updater feed 执行
npm run desktop:update-feed:check -- --feed <release-dir>/latest.json --artifacts-dir <release-dir> --require-platform windows-x86_64 --require-provenance,并确认两个平台的 updater artifact、.sig、安装包、provenance、checksum manifest 和latest.json均通过校验。 - 不可变制品先上传,
latest.json最后原子替换;若 feed 校验未通过,不替换线上latest.json。 - Web 与 Desktop 制品记录同一产品版本、Git 标签和完整提交 SHA。
2. 安全边界复审
自动门禁 npm run desktop:release:check 覆盖以下静态约束:
- Tauri bundle 启用
app、dmg和 updater artifacts。 - updater public key 已配置。
- CSP 禁止 wildcard source、
unsafe-eval、宽泛 HTTP API 访问和object-src。 script-src保持仅允许自身;ONLYOFFICE 仅在frame-src增加 HTTPS 和 localhost/127.0.0.1 开发来源。- ONLYOFFICE frame 地址只由
frontend/src/runtime/onlyoffice.ts使用已校验服务器 origin 与固定/onlyoffice-host.html生成。 - ONLYOFFICE 宿主消息同时校验
origin、source和一次性内存 nonce,配置不进入本地缓存或请求去重。 - Tauri capability 不包含 shell 权限、持久文件系统 scope 或宽泛目录读写。
- Tauri capability 不包含
remote授权,远程 ONLYOFFICE frame 无文件、通知、对话框或 opener 权限。 - 文件系统仅开放临时文件所需的 read/write/mkdir/remove 命令,且文件系统与 opener scope 只允许
$TEMP/ctms-desktop/**。 - 单实例插件先于其他桌面插件注册。
- macOS 首个顶层 submenu 为应用菜单,包含关于、设置、服务、隐藏和退出;文件菜单保持独立。
- macOS 红色按钮保持真正关闭窗口的系统语义,Dock/Finder reopen 事件在需要时重建、显示并聚焦主窗口。
- 桌面快捷键只通过受控 command 同步到原生菜单,不向 WebView 开放原始窗口或菜单控制权限。
- 桌面主题支持跟随系统、明亮和暗黑,并通过受控 command 同步窗口外观。
- Tauri command 白名单仅包含凭据、更新和已审计的桌面 UI 窄命令。
- 前端源码不通过 query string 传递 token。
ctms_token只允许由secureSessionStorage处理。- 登录表单密码不写入
localStorage或sessionStorage;Web 端只使用浏览器凭据管理能力,Desktop 端只使用系统凭据库。 - 本地缓存能力只通过
frontend/src/runtime/desktopDataCache.ts或后续同名 runtime 入口暴露,业务模块不直接调用 Tauri 存储 API、SQLite、IndexedDB、Cache Storage 或文件系统。 - 本地缓存命名空间包含 server origin、user id 和 cache schema version。
- 本地缓存不保存 token、密码、Authorization/Bearer 文本、下载凭据、临时授权 URL 或系统通知正文。
- 系统通知只能通过
frontend/src/runtime/notifications.ts发送,标题和正文保持通用。 - 通知 capability 只暴露权限查询、权限请求和发送通知,不使用
notification:default。 - opener capability 只允许打开
$TEMP/ctms-desktop/**下的临时文件,不开放 URL 或 reveal 权限。 - updater capability 不直接暴露给 WebView,自动更新只走受控 Tauri command。
- 更新弹窗 release notes 过滤 URL、token 查询参数和 Authorization/Bearer 形态文本。
- CI release 候选 workflow 包含 version/runtime/desktop/ui/type/unit/build/desktop app smoke 门禁。
- Desktop release candidate workflow 只允许从
vX.Y.Ztag 运行;先按精确版本解析平台签名策略,macOS 和 Windows 原生 job 分别验证实际签名状态,再由聚合 job 生成包含darwin-aarch64、darwin-x86_64和windows-x86_64的 feed、provenance、checksum 清单和 verified release directory。
人工复审还必须确认:
- token 不出现在 URL、日志、系统通知正文、下载链接或持久化业务缓存中。
- 密码不出现在 URL、日志、系统通知正文、诊断信息或明文浏览器存储中。
- 桌面端通知正文只显示通用内容,不包含项目、文件或版本详情。
- 服务端权限、审计和业务数据持久化仍由 FastAPI 后端裁决。
- 本地缓存只作为服务端响应副本,mutation、审批、权限判断和审计判断仍以后端结果为准。
- Web 运行时不直接导入 Tauri API。
3. 端到端回归矩阵
| 场景 | Web | macOS Desktop | 预期 |
|---|---|---|---|
| 登录与项目恢复 | 必测 | 必测 | 登录成功后恢复可访问项目;401 后重新登录 |
| 记住密码 | 必测 | 必测 | Web 使用浏览器凭据管理/自动填充;Desktop 使用系统凭据库;未勾选时不继续写入保存密码 |
| 30 天免登录 | 不适用 | 必测 | 关闭并重启 App 后复用系统凭据库中的后端在线会话;超过 30 天或 /me 校验失败后重新登录 |
| 构建默认服务器地址已注入 | 不适用 | 必测 | 首次启动使用 VITE_DESKTOP_SERVER_URL,不要求重复输入;运行时代码不含生产域名 |
| 构建默认地址和本地配置均缺失 | 不适用 | 必测 | 自动进入服务器设置,不进入业务页 |
| 服务器地址切换 | 不适用 | 必测 | 清除当前会话和项目上下文,要求重新登录 |
| 服务端不可达 | 必测 | 必测 | 显示可恢复错误,不进入离线模式 |
| 本地缓存命中 | 必测 | 必测 | /me 校验通过后可先展示缓存再后台刷新 |
| 本地缓存清理 | 必测 | 必测 | 登出、切换服务器、切换用户、401/403 后旧命名空间不可读取 |
| mutation 缓存失效 | 必测 | 必测 | 新增、编辑、删除或审批成功后相关列表、详情、统计和图表缓存失效 |
| 附件上传 | 必测 | 必测 | Web 使用浏览器文件选择,Desktop 使用原生选择 |
| 附件下载/保存/打开 | 必测 | 必测 | 使用 Authorization header;无 ?token= |
| Office 附件/版本只读预览 | 必测 | 必测 | 独立全幅页面;不下载到本地;无编辑、复制、打印、下载入口;标签失活和服务器切换立即销毁 |
| ONLYOFFICE 服务不可用 | 必测 | 必测 | 显示可重试错误,不回退 iframe 或自动下载;原保存/打开功能不受影响 |
| 临时文件清理 | 不适用 | 必测 | 启动时清理 $TEMP/ctms-desktop/** |
| 系统通知开启 | 不适用 | 必测 | 用户主动开启后请求 OS 权限并创建订阅 |
| 系统通知拒绝 | 不适用 | 必测 | 开关回退,提示系统权限未开启 |
| 通知领取与 ack | 不适用 | 必测 | 显示成功后 ack;失败等待租约重试 |
| 单实例重复启动 | 不适用 | 必测 | 恢复、显示并聚焦主窗口 |
| 关闭窗口后 Dock 重开 | 不适用 | 必测 | 红色关闭按钮真正关闭主窗口;点击 Dock 后重建、显示并聚焦 |
| 原生应用菜单 | 不适用 | 必测 | CTMS、文件、编辑、显示、导航、窗口和帮助菜单顺序及职责符合 macOS 习惯 |
| 自定义快捷键同步 | 不适用 | 必测 | 设置修改后原生菜单立即显示并响应新的后退、前进和刷新快捷键 |
| 跟随系统主题 | 不适用 | 必测 | 系统明暗模式变化时 WebView、标题栏和系统控件同步更新 |
| 自动更新检查 | 不适用 | 必测 | release 通道按当前 CTMS origin 派生清单 |
| 更新稍后提醒 | 不适用 | 必测 | 同版本 24 小时内不重复提示 |
| 更新安装失败 | 不适用 | 必测 | 不打断业务录入,显示可排障错误 |
4. 桌面体验验收
- 登录页显示当前桌面服务器地址,长 URL 不撑破登录面板。
- 30 天免登录仍只保存系统凭据库会话记录,不把 token 写入 URL、日志、通知正文或业务缓存。
- 记住密码与 30 天免登录使用独立凭据记录;服务器切换后不复用旧服务器保存的密码。
- 服务器设置页显示当前服务器、连接检查状态、HTTP 错误、超时和网络失败原因。
- 个人中心显示客户端类型、版本、平台、构建通道、提交、服务器和能力状态。
- 个人中心可复制诊断信息,内容不包含 token 或业务敏感数据。
- 系统偏好或个人中心提供本地缓存记录数、容量和最近清理时间,且支持手动清理。
- 通知开关显示 OS 权限状态。
- 手动检查更新能反馈“已是最新版本”、未启用更新或检查失败。
- 关键弹窗、表单、按钮在最小窗口尺寸
1180x760下不重叠、不溢出。 - “设置…”位于 macOS CTMS 应用菜单并使用
⌘,;退出位于应用菜单而不是文件菜单。 - “显示”和“导航”菜单中的快捷键与桌面偏好保存值一致。
- 更新弹窗只显示版本、发布日期和通用 release notes,不展示 token、下载链接或业务详情。
5. 不允许项
- 不实现离线登录、离线写入、离线队列或离线同步。
- 不在
/me校验通过前展示业务缓存。 - 不把本地缓存作为 CTMS 业务权威数据或本地优先数据源。
- 不内嵌 FastAPI、PostgreSQL 或本地业务 API 镜像。
- 不绕过后端做本地权限裁决、本地审计判定或审计回放。
6. 2026-07-01 收尾验证记录
本轮收尾验证在 /Users/zcc/MyCTMS/ctms-dev/worktrees/ctms-desktop 的 detached HEAD c923f887 上执行,包含当前工作区文档与 CI 门禁调整。
已通过的自动门禁:
cd frontend && npm run version:checkcd frontend && npm run release:env:checkcd frontend && npm run runtime:checkcd frontend && npm run desktop:release:checkcd frontend && npm run ui:contractcd frontend && npm run type-checkcd frontend && npm run test:unitcd frontend && npm run buildcd frontend && npm run desktop:build:appcd frontend && node --check scripts/verify-desktop-update-feed.mjs
验证结论:
- Tauri 运行时边界、release 静态安全门禁、构建元数据预检、版本一致性和 UI 合约均通过。
- Web 生产构建和未签名 macOS
.appsmoke 构建均可重复执行。 - 当前 CI 已补齐
npm run release:env:check和npm run ui:contract,tag 构建会将VITE_BUILD_CHANNEL规范为release并校验 tag 与版本号一致。 - updater feed 校验脚本已完成语法检查;正式
latest.json需要在签名 updater artifacts 生成后执行实物校验。
仍需正式发布前人工确认:
- macOS 签名、公证、Apple Developer 凭据和组织 updater 私钥。
- 签名后的 updater artifacts、
.sig、checksum manifest 和latest.json在真实发布目录内通过npm run desktop:update-feed:check。 - 不可变制品上传完成后,再原子替换线上
latest.json。 - Desktop 端到端人工回归矩阵、最小窗口体验验收和系统通知/自动更新真实环境验证。
7. 2026-07-02 发布稳定化推进记录
本次推进补齐了发布链路自动化,不改变桌面端产品边界:
- 新增
npm run desktop:build:macos-release,封装 Universal macOSapp/dmgrelease candidate 构建命令。 - 新增
npm run desktop:update-feed:create,从签名 updater artifact 和.sig生成latest.json、复制发布目录文件并生成SHA256SUMS.txt。 npm run desktop:update-feed:check在传入--artifacts-dir时要求并校验SHA256SUMS.txt。- 新增
npm run desktop:release-readiness:check,在正式签名候选构建前检查 release tag、构建元数据、签名/公证变量、updater 私钥和生产 artifact HTTPS 基址。 - 新增
.github/workflows/desktop-release-candidate.yml,在 release tag 上执行签名候选构建、feed 生成、feed 校验并上传 verified release directory。 npm run desktop:release:check已检查上述脚本和 workflow,避免发布链路回退。
仍未自动完成、正式发布前必须人工确认:
- Apple Developer 凭据、证书、签名身份、公证结果和组织 updater 私钥。
- 生产下载源的不可变制品上传和线上
latest.json原子替换。 - 真实环境下的自动更新安装、系统通知、单实例和完整人工回归。
8. 2026-07-02 端到端回归优化记录
本轮端到端优化仍保持在线桌面客户端边界,不引入离线、本地业务存储或本地权限裁决。
已完成的自动化收口:
- 服务器地址切换时,桌面设置页调用
auth.logout({ rememberCurrentStudy: false }),避免退出时把旧服务器项目记入当前用户的最近项目;随后继续清除当前项目上下文。 - 系统偏好连接页与独立服务器设置页保持同一切换服务器语义,切换时不记忆旧服务器项目并清除当前项目上下文。
- 系统通知轮询在部分通知显示失败或系统通知未实际发起时,先 ack 已成功发起系统通知的通知,再让失败项通过租约重试,贴合“显示成功后 ack;失败等待重试”的回归预期。
- 自动更新管理器新增稍后提醒 24 小时抑制、安装失败可重试、检查失败不打断业务和未启用更新状态的单元覆盖。
- 附件 API 新增 blob 下载、multipart 上传和删除端点单元覆盖,确保下载凭据继续由 axios Authorization header 承载而不是进入 URL。
- 文件任务反馈 helper 新增选择、保存、取消保存和打开的单元覆盖,约束桌面保存/打开继续走
frontend/src/runtime/适配层。 - Keychain/凭据库会话新增旧浏览器 token 迁移、未配置服务器不读取凭据、本地 30 天上限、服务器切换删除旧服务器凭据,以及恢复 token 必须先经
/me校验的单元覆盖。 - 桌面发布门禁新增单实例重复启动处理校验,要求重复启动时恢复、显示并聚焦
main窗口。 - 会话刷新后的跨窗口 token 更新不再写入
localStoragefallback,只通过内存态 BroadcastChannel 通知,避免 token 进入明文广播缓存。 desktop:release:check新增 session broadcast 静态门禁,防止TOKEN_UPDATEDpayload 回退写入localStorage。- 新增相关单元测试覆盖服务器切换不记忆旧项目、通知权限未授权不领取、部分通知失败时只 ack 成功项、系统通知未发起时不 ack、自动更新失败恢复路径、附件文件流契约、30 天在线会话恢复边界、单实例恢复行为和 token 广播存储边界。
仍需人工或真实环境验证:
- Keychain/凭据库 30 天在线会话恢复。
- 原生附件上传、下载、保存和打开。
- 系统通知拒绝路径的 OS 级交互。
- 单实例重复启动聚焦主窗口。
- 签名 release 构建下的自动更新 feed、验签、安装和重启实物流。
9. 2026-07-02 安全边界复审记录
本轮安全复审在端到端自动化收口之后推进,不改变桌面端在线客户端边界。
已完成的安全边界收口:
- Tauri notification capability 从
notification:default收敛为notification:allow-is-permission-granted、notification:allow-request-permission和notification:allow-notify。 desktop:release:check新增 capability 最小化约束,拒绝notification:default、opener URL/reveal 权限和 WebView 直连 updater 权限。desktop:release:check将 token URL 检查扩展到token与access_token查询参数,并扩大日志敏感词检查到token、access_token、authorization和bearer。- 更新弹窗 release notes 增加清理逻辑,过滤 URL、token 查询参数、
access_token、Authorization和Bearer形态文本,避免 feed 内容把下载链接或凭据样式文本带入 UI。 - 凭据库 Rust 单测新增带凭据 server origin 拒绝,以及 Keychain/Credential Manager account 不暴露原始服务器 origin 的覆盖。
仍需人工复审确认:
- 真实生产 release notes 内容保持通用,不写入项目、文件、下载链接或敏感业务详情。
- 正式签名、公证和 updater feed 环境继续使用组织 secret,不在日志、artifact 或配置中泄露私钥材料。
10. 2026-07-02 桌面体验收口记录
本轮体验收口聚焦登录、服务器设置、个人中心诊断、系统偏好和最小窗口布局稳定性,不改变业务能力边界。
已完成的体验收口:
- 个人中心新增只读客户端诊断信息,展示客户端类型、版本、平台、构建通道、提交、服务器和能力状态,并支持复制诊断信息。
- 登录页在桌面最小窗口附近收紧左右分栏 padding 和卡片宽度,长服务器地址继续在登录面板内换行,不撑破布局。
- 服务器设置页增加面板内滚动和健康检查 URL 换行约束,避免
1180x760下长 URL 或错误信息溢出。 - 系统偏好通知/更新控制区允许换行,长状态说明使用
overflow-wrap,避免按钮和权限状态标签在窄视口重叠。 - 个人中心对话框内容区改为内部滚动,诊断值使用强制换行,避免新增诊断信息后超过最小窗口高度。
- 通知权限运行时改为优先读取 WebView
Notification.permission的granted/denied状态;请求权限返回default时保持“待授权”,不再误标为“已拒绝”。 - 系统偏好通知页已移除授权成功态的固定标签文案,开启状态只由开关表达;待授权、已拒绝和不可用状态继续显示提示标签。
- 系统偏好通知页新增“测试通知”命令,完整走
frontend/src/runtime/notifications.ts->@tauri-apps/plugin-notification的系统通知发送链路;测试通知文案为固定通用内容,不包含项目、文件、token 或其他敏感业务信息。 showSystemNotification和测试通知调用会在发送前确认系统通知权限,只有真正发起系统通知时才返回成功;桌面通知轮询据此只 ack 已实际发起系统通知的后端通知。- 真实 macOS
.app已验证系统偏好通知开关可调用系统通知权限并生效。验证截图见/Users/zcc/Library/Application Support/CleanShot/media/media_boKznpjOwt/CleanShot 2026-07-02 at 11.07.52@2x.png。 Layout.desktop.test.ts新增静态契约覆盖个人中心诊断、登录页最小窗口断点、服务器设置滚动和偏好页控制区换行约束。notifications.test.ts新增授权、拒绝、待授权、取消授权请求和测试通知发送链路的单元覆盖。
仍需人工体验验收:
- 在真实 macOS
.app中以1180x760检查登录页、服务器设置、个人中心、系统偏好和更新弹窗无重叠、无横向溢出。 - 在真实系统通知权限拒绝流程中确认权限状态提示、开关回退和错误提示与 OS 状态一致。
11. 2026-07-13 macOS 原生体验适配记录
本轮继续保留 Tauri 和共享 Vue 前端,不引入 Swift 业务 UI,也不改变 Windows 内测边界:
- macOS 新增标准 CTMS 应用菜单,将关于、设置、服务、隐藏和退出等项目收敛到首个应用 submenu;文件、编辑、显示、导航、窗口和帮助菜单保持独立。
- macOS 红色关闭按钮保持真正关闭主窗口的系统语义;Tauri
RunEvent::Reopen在 Dock/Finder 再激活时从受控配置重建、显示并聚焦主窗口,重复启动继续复用同一恢复 helper。 - 新增受控
desktop_menu_set_shortcutscommand,只接受后退、前进和刷新三项经过双层校验的快捷键,并同步原生菜单 accelerator。 - 桌面主题新增“跟随系统”,WebView 监听
prefers-color-scheme,受控desktop_window_set_themecommand 同步 Tauri 窗口外观;未向 WebView 增加原始窗口权限。 desktop:release:check已增加应用菜单、Dock reopen、关闭后重建、快捷键同步、系统主题和新增 command 白名单约束。
真实 .app 仍需人工验证:红色按钮真正关闭主窗口后 Dock 重建、菜单顺序、个人中心自身关闭按钮、编辑菜单文本输入行为、自定义快捷键即时同步,以及系统明暗模式切换时的标题栏一致性。
本轮未引入以下条件性 Swift 能力:Quick Look 需先确认附件审阅频率和 Windows 降级语义;Touch ID 会改变现有 30 天会话恢复体验,需先确定凭据访问控制策略;通知点击回跳需先定义固定、无敏感信息的动作和目标页面。三项均不是当前发布前置条件。
12. 2026-07-17 Windows 正式发布链路记录
经发布负责人明确批准,Windows x64 NSIS 从内部兼容性验证目标提升为正式桌面发布目标。本轮完成:
- 正式 Desktop candidate workflow 拆分为 macOS 签名/公证、Windows 代码签名和跨平台聚合三个 job;两端都只接受与客户端版本一致的
vX.Y.Ztag。 - Windows job 从组织 secret 导入 Base64 PFX,动态配置证书指纹、SHA-256、RFC 3161 时间戳,构建 NSIS installer/updater,并校验应用与安装器的 Authenticode signer 和 timestamp certificate。
- 聚合 job 只在两个原生 job 均通过后生成统一
latest.json,同时包含 Universal macOS 的两个平台键和windows-x86_64,并校验所有制品、.sig与 checksum。 - 无签名
.github/workflows/desktop-windows-internal.yml继续保持 branch-only 内部验证语义,不生成正式 updater feed。 - npm 依赖锁文件已升级至当前安全修复版本,生产和完整依赖审计均为 0 个已知漏洞;Axios 新 header 类型通过受控字符串归一化适配并新增单元测试。
创建正式 tag 前仍必须由发布负责人确认:
- GitHub Actions 已配置 updater secrets 和 versioned artifact base URL;默认平台签名路径还必须配置 Apple 与 Windows secrets 和 Windows timestamp URL。
- 若使用默认 Windows 签名路径,组织证书允许 PFX 导入 CI;若为硬件或云托管密钥,先将 workflow 切换为经审计的 Tauri
signCommandprovider。 - macOS/Windows 原生 candidate job、联合 feed 校验、真实安装/升级和生产下载源上传全部通过。
13. 2026-07-17 v0.1.0 平台签名例外记录
经发布负责人明确批准,v0.1.0 可在无法提供 Apple Developer 和 Windows 组织代码签名凭据时受控分发。该批准仅覆盖精确版本 0.1.0:
frontend/desktop-release-policy.json默认仍为signed,仅将 v0.1.0 列入unsignedPlatformExceptions;后续版本不会继承本例外。- macOS 使用 Tauri
signingIdentity: "-"生成 ad-hoc 签名 Universal app/DMG,必须通过codesign --verify并确认Signature=adhoc,不执行或声称 Apple 公证。 - Windows 应用和 NSIS 安装器不做 Authenticode 签名,必须通过
Get-AuthenticodeSignature确认NotSigned,不执行或声称 RFC 3161 时间戳。 - 两端仍必须从同一
v0.1.0tag 和 SHA 构建,使用同一 updater 私钥生成.sig,并通过联合 feed、checksum 和 provenance 校验。 - GitHub Actions 额度不可用期间,发布负责人额外批准从最终
v0.1.0tag/SHA 在受控 macOS 主机本地构建并先行上传 macOS 制品;Windows 必须在恢复后从同一 tag/SHA 后补。 - macOS 先行的用户可见 GitHub Release 只包含 DMG、仅覆盖该 DMG 的 checksum 和 GitHub 自动源码归档;Release Notes 必须明确 macOS ad-hoc/未公证风险和 Windows pending,且不得包含或替换生产
latest.json。updater 包及.sig、完整 checksum、provenance、UNSIGNED-PLATFORM和 Windows pending 证据必须先复制到权限受限且被 Git 忽略的私有发布目录。 - Windows
NotSigned实物和联合 feed 全部验证通过后,才允许激活生产 updater feed;tag 不得为补充 Windows 制品而移动。 - 制品与 Actions artifact 名称必须含
_UNSIGNED或UNSIGNED-PLATFORM,私有证据/完整 updater 发布目录必须携带UNSIGNED-PLATFORM-RELEASE.txt和DESKTOP-RELEASE-PROVENANCE.json;installer-only GitHub Release 通过_UNSIGNED安装包名和 Release Notes 呈现风险,不要求公开展示内部证据文件。 - 受控分发说明必须明确提示 macOS Gatekeeper 与 Windows SmartScreen 警告;平台未签名制品不得描述为 Apple/Microsoft 信任或已公证/已 Authenticode 签名。
本地实物验证已完成:使用当前 updater 私钥成功构建 Universal x86_64 arm64 macOS app、DMG、.app.tar.gz 和 .sig;codesign --verify --deep --strict 通过,签名详情为 Signature=adhoc、TeamIdentifier=not set,Gatekeeper 拒绝符合预期。Windows NotSigned、NSIS 和 updater .sig 仍须由 windows-latest 原生 job 在正式 tag 上验证。