Skip to content

macOS: Sparkle beta update channel and release plumbing#34

Draft
geekflyer wants to merge 1 commit into
mainfrom
feat/sparkle-beta-channel-qzc
Draft

macOS: Sparkle beta update channel and release plumbing#34
geekflyer wants to merge 1 commit into
mainfrom
feat/sparkle-beta-channel-qzc

Conversation

@geekflyer
Copy link
Copy Markdown
Owner

Adds a menu toggle for the beta Sparkle feed, embeds stable/beta appcast URLs in Info.plist, extends release-mac.yml (git_ref, sparkle_channel) and release.sh (--beta) for a long-lived beta branch, and documents hosting appcast-beta.xml.

Made with Cursor

- Resolve appcast URL via SPUUpdaterDelegate and UserDefaults; embed
  stable/beta feed URLs in Info.plist from build-all.sh (env overrides).
- Add menu item Beta Update Channel; reset Sparkle cycle and re-check
  when toggled.
- release-mac: git_ref + sparkle_channel inputs; update appcast.xml or
  appcast-beta.xml; seed beta skeleton on first publish; beta releases
  marked prerelease on GitHub.
- release.sh: --beta and --git-ref/--sparkle-channel for long-lived beta.
- Document feeds and workflow in CI-SETUP.

Made-with: Cursor
Comment thread scripts/build-all.sh
shift 2
;;
--beta-mac)
SPARKLE_INFO_DEFAULT_FEED="$SPARKLE_FEED_BETA"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

--beta-mac is effectively a no-op at runtime.

resolvedFeedURLString() in SparkleUpdateChannel.swift reads ClipRelaySparkleFeedStable first, falling back to SUFeedURL only when that key is absent:

let stable = Bundle.main.object(forInfoDictionaryKey: "ClipRelaySparkleFeedStable") as? String
    ?? Bundle.main.object(forInfoDictionaryKey: "SUFeedURL") as? String

Since build_mac() always writes ClipRelaySparkleFeedStable (line 169), SUFeedURL is never used for the stable URL, so changing SPARKLE_INFO_DEFAULT_FEED here has no effect on which feed the app actually checks at runtime.

To make --beta-mac work as documented, it should also override SPARKLE_FEED_STABLE so the ClipRelaySparkleFeedStable plist key points at the beta feed — or the flag should be removed (the comment already notes "use menu toggle at runtime").

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Apr 6, 2026

Review summary

Overall the approach is clean: using SPUUpdaterDelegate.feedURLString(for:) to supply the runtime feed URL is the correct Sparkle 2.x pattern, and embedding both ClipRelaySparkleFeedStable / ClipRelaySparkleFeedBeta keys in Info.plist gives a nice compile-time-configurable default with a hardcoded fallback.

One bug found (inline): --beta-mac in build-all.sh only mutates SUFeedURL via SPARKLE_INFO_DEFAULT_FEED, but resolvedFeedURLString() reads ClipRelaySparkleFeedStable first and never reaches SUFeedURL in a normal build. The flag is a no-op — either drop it or have it also set SPARKLE_FEED_STABLE to point at the beta feed.

Everything else looks good: the clearFeedURLFromUserDefaults() call correctly evicts any stale URL written by the deprecated API before the delegate takes over, the appcast-update step correctly conditions on !inputs.prerelease (the raw input, not the computed release flag), and the --all --beta guard in release.sh prevents accidentally mixing Android and beta macOS releases.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant