OpenClaw macOS 发布(Sparkle)

本应用通过 Sparkle 提供自动更新。发布构建必须经 Developer ID 签名、打包为 zip,并发布带签名的 appcast 条目。

前置准备

  • 已安装 Developer ID Application 证书(例如 Developer ID Application: <Developer Name> (<TEAMID>))。
  • Sparkle 私钥路径已通过环境变量 SPARKLE_PRIVATE_KEY_FILE 设置(路径指向 Sparkle ed25519 私钥;公钥已内置于 Info.plist)。如果没设,检查 ~/.profile
  • 用于 xcrun notarytool 的公证凭证(Keychain profile 或 API key),如果需要 Gatekeeper 安全的 DMG/zip 分发。
    • 使用名为 openclaw-notary 的 Keychain profile,通过 shell profile 中的 App Store Connect API key 环境变量创建:
      • APP_STORE_CONNECT_API_KEY_P8APP_STORE_CONNECT_KEY_IDAPP_STORE_CONNECT_ISSUER_ID
      • echo "$APP_STORE_CONNECT_API_KEY_P8" | sed 's/\\n/\n/g' > /tmp/openclaw-notary.p8
      • xcrun notarytool store-credentials "openclaw-notary" --key /tmp/openclaw-notary.p8 --key-id "$APP_STORE_CONNECT_KEY_ID" --issuer "$APP_STORE_CONNECT_ISSUER_ID"
  • pnpm 依赖已安装(pnpm install --config.node-linker=hoisted)。
  • Sparkle 工具通过 SwiftPM 自动获取,位于 apps/macos/.build/artifacts/sparkle/Sparkle/bin/sign_updategenerate_appcast 等)。

构建与打包

说明:

  • APP_BUILD 映射到 CFBundleVersion/sparkle:version;保持数字且单调递增(不要带 -beta),否则 Sparkle 会当作相等版本来比较。
  • 如果省略 APP_BUILDscripts/package-mac-app.sh 会从 APP_VERSION 自动推导一个 Sparkle 兼容的默认值(YYYYMMDDNN:稳定版默认为 90,预发布版使用后缀推导的通道号),并取该值与 git commit 数量中的较大者。
  • 你仍然可以在需要特定单调值时显式指定 APP_BUILD
  • BUILD_CONFIG=release 时,scripts/package-mac-app.sh 默认构建通用版(arm64 x86_64)。你仍可用 BUILD_ARCHS=arm64BUILD_ARCHS=x86_64 覆盖。本地/开发构建(BUILD_CONFIG=debug)默认为当前架构($(uname -m))。
  • 发布产物用 scripts/package-mac-dist.sh。本地/开发打包用 scripts/package-mac-app.sh
# 从仓库根目录运行;设置发布 ID 以启用 Sparkle feed。
# 此命令构建发布产物但不做公证。
# APP_BUILD 必须为数字且单调递增以供 Sparkle 比较。
# 省略时自动从 APP_VERSION 推导。
SKIP_NOTARIZE=1 \
BUNDLE_ID=ai.openclaw.mac \
APP_VERSION=2026.3.13 \
BUILD_CONFIG=release \
SIGN_IDENTITY="Developer ID Application: <Developer Name> (<TEAMID>)" \
scripts/package-mac-dist.sh

# `package-mac-dist.sh` 已创建 zip + DMG。
# 如果直接使用了 `package-mac-app.sh`,需手动创建:
# 如需在此步骤进行公证/钉合,使用下方的 NOTARIZE 命令。
ditto -c -k --sequesterRsrc --keepParent dist/OpenClaw.app dist/OpenClaw-2026.3.13.zip

# 可选:构建有样式的 DMG 供用户拖拽到 /Applications
scripts/create-dmg.sh dist/OpenClaw.app dist/OpenClaw-2026.3.13.dmg

# 推荐:构建 + 公证/钉合 zip + DMG
# 先创建一次 Keychain profile:
#   xcrun notarytool store-credentials "openclaw-notary" \
#     --apple-id "<apple-id>" --team-id "<team-id>" --password "<app-specific-password>"
NOTARIZE=1 NOTARYTOOL_PROFILE=openclaw-notary \
BUNDLE_ID=ai.openclaw.mac \
APP_VERSION=2026.3.13 \
BUILD_CONFIG=release \
SIGN_IDENTITY="Developer ID Application: <Developer Name> (<TEAMID>)" \
scripts/package-mac-dist.sh

# 可选:随发布附带 dSYM
ditto -c -k --keepParent apps/macos/.build/release/OpenClaw.app.dSYM dist/OpenClaw-2026.3.13.dSYM.zip

Appcast 条目

使用发布说明生成器,让 Sparkle 渲染格式化的 HTML 说明:

SPARKLE_PRIVATE_KEY_FILE=/path/to/ed25519-private-key scripts/make_appcast.sh dist/OpenClaw-2026.3.13.zip https://raw.githubusercontent.com/openclaw/openclaw/main/appcast.xml

CHANGELOG.md 生成 HTML 发布说明(通过 scripts/changelog-to-html.sh)并嵌入 appcast 条目。 发布时将更新后的 appcast.xml 与发布产物(zip + dSYM)一起提交。

发布与验证

  • OpenClaw-2026.3.13.zip(和 OpenClaw-2026.3.13.dSYM.zip)上传到标签 v2026.3.13 的 GitHub release。
  • 确保原始 appcast URL 与内置的 feed 匹配:https://raw.githubusercontent.com/openclaw/openclaw/main/appcast.xml
  • 健全性检查:
    • curl -I https://raw.githubusercontent.com/openclaw/openclaw/main/appcast.xml 返回 200。
    • curl -I <enclosure url> 在资产上传后返回 200。
    • 在之前的公开构建上运行 About 标签中的 “Check for Updates…”,验证 Sparkle 能干净地安装新构建。

完成标准:签名的应用 + appcast 已发布,从旧版本的更新流程能正常工作,发布产物已附加到 GitHub release。