Skip to main content

Fased macOS release (Sparkle)

Use this page when you are publishing signed macOS app artifacts. Sparkle updates are a release-maintainer path, not the default public install flow while the repo-backed installer remains primary. Release builds must be Developer ID-signed, zipped, and published with a signed appcast entry.

Prereqs

  • Developer ID Application cert installed. Example: Developer ID Application: <Developer Name> (<TEAMID>).
  • Sparkle private key path set in the environment as SPARKLE_PRIVATE_KEY_FILE. The public key is baked into Info.plist. If it is missing, check ~/.profile.
  • Notary credentials for xcrun notarytool if you want Gatekeeper-safe DMG/zip distribution.
    • We use a Keychain profile named fased-notary, created from App Store Connect API key env vars in your shell profile:
      • APP_STORE_CONNECT_API_KEY_P8
      • APP_STORE_CONNECT_KEY_ID
      • APP_STORE_CONNECT_ISSUER_ID
      • echo "$APP_STORE_CONNECT_API_KEY_P8" | sed 's/\\n/\n/g' > /tmp/fased-notary.p8
      • Store the profile:
  • pnpm deps installed (pnpm install --config.node-linker=hoisted).
  • Sparkle tools are fetched automatically via SwiftPM at apps/macos/.build/artifacts/sparkle/Sparkle/bin/.

Build & package

Notes:
  • APP_BUILD maps to CFBundleVersion/sparkle:version; keep it numeric and monotonic. Avoid -beta here.
  • Defaults to the current architecture ($(uname -m)). For release/universal builds, set BUILD_ARCHS="arm64 x86_64" or BUILD_ARCHS=all.
  • Use scripts/package-mac-dist.sh for release artifacts. Use scripts/package-mac-app.sh for local/dev packaging.

Appcast entry

Use the release note generator so Sparkle renders formatted HTML notes:
Generates HTML release notes from CHANGELOG.md using scripts/changelog-to-html.sh and embeds them in the appcast entry. Commit the updated appcast.xml alongside the release assets when publishing.

Publish & verify

  • Upload FasedAgent-2026.2.27.zip and FasedAgent-2026.2.27.dSYM.zip to the GitHub release for tag v2026.2.27.
  • Ensure the raw appcast URL matches the baked feed: https://raw.githubusercontent.com/fased-ai/fased/main/appcast.xml.
  • Sanity checks:
    • curl -I https://raw.githubusercontent.com/fased-ai/fased/main/appcast.xml returns 200.
    • curl -I <enclosure url> returns 200 after assets upload.
    • On a previous public build, run “Check for Updates…” from the About tab and verify Sparkle installs the new build cleanly.
Definition of done: signed app + appcast are published, update flow works from an older installed version, and release assets are attached to the GitHub release.