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=releasescripts/package-mac-app.sh 現在自動預設為通用版(arm64 x86_64)。仍可透過 BUILD_ARCHS=arm64BUILD_ARCHS=x86_64 覆蓋。本機/開發版本(BUILD_CONFIG=debug)預設為目前架構($(uname -m))。
  • 使用 scripts/package-mac-dist.sh 產生發布產出物(zip + DMG + 公證)。使用 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。