Files
Meldwork/docs/macos-signing.md
T
Ryder Sun dcbec859d1 docs(release): translate macOS signing guide
Translate the Developer ID signing and Apple notarization instructions into Chinese while preserving official certificate names, commands, environment variables, and fail-closed release requirements.

Checks: git diff --check; documentation-only change.
2026-08-06 11:35:08 +08:00

7.2 KiB
Raw Blame History

macOS Developer ID 签名与 Apple 公证

当前内测版本采用临时签名(ad-hoc signing)。面向公众分发 DMG 和 ZIP 时,必须使用 Developer ID Application 证书完成签名,并提交 Apple 公证,确保应用能够在全新 Mac 上通过 Gatekeeper 检查。

1. 加入 Apple Developer Program

  1. 使用将来负责发布 Meldwork 的 Apple ID 登录 Apple Developer Program。
  2. 为 Apple ID 开启双重认证,然后加入 Apple Developer Program。Apple 会收取年度会员费,具体人民币价格和身份验证要求以申请页面为准。
  3. 如果未来由公司或机构发布,建议使用法人主体加入,而不是个人账号。Apple 可能要求提供 D-U-N-S 编号,并验证申请人是否有权代表该组织签署协议。
  4. 申请通过后,在 Membership 页面记录十位字符的 Apple Team ID。

审核时间可能从几小时到数个工作日不等,取决于个人身份或组织资质验证。这个申请过程无法通过本仓库自动完成。

2. 注册固定的应用标识

Meldwork 的正式 Bundle ID 是 com.rydersun.meldwork。必须在第一次签名并公证发布前注册这个标识,之后保持不变。后续修改 Bundle ID 可能影响 macOS 应用身份、系统权限、钥匙串数据访问和升级连续性。

进入 Apple Developer 网站的 Certificates, Identifiers & Profiles,在 Identifiers 中注册 com.rydersun.meldwork。首次公开发布后不要更换这个标识。

3. 创建签名证书

推荐在发布用 Mac 上通过 Xcode 创建证书:

  1. 安装发布 Mac 所支持的最新稳定版 Xcode。
  2. 打开 Xcode 设置,进入 Accounts,添加已经加入 Apple Developer Program 的 Apple ID,并选择正确的 Team。
  3. 打开 Manage Certificates,创建 Developer ID Application 证书。
  4. 确认登录钥匙串中同时存在证书和对应私钥:
security find-identity -v -p codesigning

分发 DMG 和 ZIP 需要的是 Developer ID Application。只有分发签名 .pkg 安装包时才需要 Developer ID Installer。

将证书和私钥导出为加密的 .p12 文件,并保存在仓库之外的安全位置。不要把证书、私钥、密码、API Key 或公证配置提交到 Git。

4. 创建 Apple 公证凭据

CI/CD 推荐使用 App Store Connect API Key:

  1. 打开 App Store Connect,依次进入 Users and Access、Integrations、App Store Connect API。
  2. 创建一个能够代表当前 Team 提交公证任务、但权限尽可能小的 API Key。
  3. 下载只能获取一次的 .p8 私钥文件,同时记录 Key ID 和 Issuer ID。

如果只在本机发布,可以让 notarytool 把 Apple ID 凭据保存到钥匙串:

xcrun notarytool store-credentials "meldwork-notary" \
  --apple-id "YOUR_APPLE_ID" \
  --team-id "YOUR_TEAM_ID" \
  --password "YOUR_APP_SPECIFIC_PASSWORD"

需要在 Apple ID 账户页面 创建 App 专用密码。这里不能使用 Apple ID 的普通登录密码。

5. 配置 electron-builder

当前仓库已经使用 Bundle ID com.rydersun.meldwork,社区版许可证为 AGPL-3.0-only。公开发布配置必须保持 Hardened Runtime 开启,并在现有 afterPack Electron Fuses 加固完成后,由 electron-builder 执行签名和公证。

使用本机钥匙串证书时,electron-builder 可以自动发现有效的 Developer ID Application 身份。在 CI 中,需要把证书导出为加密的 .p12,并配置以下 Secrets:

CSC_LINK
CSC_KEY_PASSWORD
APPLE_API_KEY
APPLE_API_KEY_ID
APPLE_API_ISSUER

CSC_LINK 指向 .p12 证书或其安全编码内容,CSC_KEY_PASSWORD 是 .p12 密码。APPLE_API_KEY 必须指向 CI 运行环境中的 .p8 私钥文件。

如果不使用 App Store Connect API Key,也可以配置 Apple ID 方案:

APPLE_ID
APPLE_APP_SPECIFIC_PASSWORD
APPLE_TEAM_ID

如果使用本机钥匙串中的 notarytool Profile,设置 APPLE_KEYCHAIN_PROFILE=meldwork-notary。Profile 位于默认钥匙串时,通常不需要设置 APPLE_KEYCHAIN。

公开发布命令 dist:public 会依次执行以下保护:

  1. scripts/public-release-preflight.cjs 检查签名身份和完整的公证凭据。
  2. electron-builder.public.cjs 强制启用 forceCodeSigning: true 和 mac.notarize: true。
  3. scripts/after-sign.cjs 拒绝临时签名、缺失 Team ID、未开启 Hardened Runtime,或者 Bundle ID 不是 com.rydersun.meldwork 的产物。

不要增加任何明文凭据降级方案。缺少签名或公证凭据时,公开发布必须在打包前失败,不能生成可能被误发布的临时签名产物。

6. 构建并验证正式产物

安装锁定依赖并构建公开分发包:

npm --prefix frontend ci
npm --prefix desktop ci
npm --prefix desktop run dist:public

npm --prefix desktop run dist 只用于本地打包验证,不是正式公开发布命令。

发布前检查实际生成的应用和 DMG:

codesign --verify --deep --strict --verbose=2 \
  desktop/dist/mac-arm64/Meldwork.app

spctl --assess --type execute --verbose=4 \
  desktop/dist/mac-arm64/Meldwork.app

xcrun stapler validate desktop/dist/mac-arm64/Meldwork.app
xcrun stapler validate desktop/dist/Meldwork-0.1.0-arm64.dmg

必须在没有安装过 Meldwork、没有历史应用数据的全新 Apple 芯片 Mac 用户账户中安装 DMG,并通过正常双击启动。不能使用右键绕过、删除隔离属性或执行 xattr 的方式通过测试。只有 Gatekeeper 正常接受应用,才算满足公开发布门槛。

签名、公证和 Stapling 全部完成后,再生成最终校验值:

shasum -a 256 \
  desktop/dist/Meldwork-0.1.0-arm64.dmg \
  desktop/dist/Meldwork-0.1.0-arm64.zip

发布到 GitHub Release 的 DMG、ZIP 和 SHA256SUMS.txt 必须来自同一个干净的 Git 标签和同一次正式构建。

7. 常见错误

  • CSSMERR_TP_NOT_TRUSTED:证书链无效、证书已过期、缺少对应私钥,或者证书在当前钥匙串中不受信任。
  • no identity found:没有安装有效的 Developer ID 证书,或者 electron-builder 无法访问证书所在的钥匙串。
  • 公证拒绝二进制文件:使用 notarytool 查看详细日志,重点检查未签名的嵌套可执行文件、缺失 Hardened Runtime、无效 Entitlements 或额外打包的可执行内容。
  • spctl 拒绝已经签名的应用:通常是没有完成公证或 Stapling、公证票据无效,或者本地验证的应用并不是提交给 Apple 的同一份产物。
  • 签名版本启动后出现全新数据目录:Bundle ID 或产品身份可能在内测后发生了变化。应停止发布并先设计明确的数据迁移方案。

8. 当前项目状态

  • Bundle ID 已固定为 com.rydersun.meldwork。
  • dist:public 已配置为缺少正式签名或公证凭据时安全失败。
  • 当前 Mac 上没有有效的 Developer ID Application 证书。
  • 当前检测到的 www.dingtalkcs.com 身份无效且与 Meldwork 无关,不能用于发布,也不应由项目脚本自动删除。
  • 在完成 Apple Developer Program 申请、证书安装和公证凭据配置之前,只能生成供本地验证使用的临时签名包。