Release: keep prereleases off the auto-update feed and Homebrew cask#468
Closed
FuJacob wants to merge 1 commit into
Closed
Release: keep prereleases off the auto-update feed and Homebrew cask#468FuJacob wants to merge 1 commit into
FuJacob wants to merge 1 commit into
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Review of
release.ymlfound the stable release path solid, but the prerelease path had a material gap: a prerelease tag (v1.2.3-beta) ran the full publish flow, which overwrote the production Sparkle appcast atupdates.cotabby.app/appcast.xmland bumped the Homebrew cask. Because every user sits on Sparkle's default channel (singleSUFeedURL, noallowedChannelsopt-in anywhere) and the appcast carries no<sparkle:channel>, that beta would be force-offered to all auto-update users and become thebrew installtarget. The--prereleaseflag only controls GitHub's "Latest" badge, not Sparkle.This makes prereleases download-only: they still create a GitHub prerelease (and still build + notarize + sign + generate the appcast as an artifact, so signing is validated), but they no longer publish the appcast to Pages or bump the cask. The stable release path is behaviorally unchanged: every new gate is
is_prerelease != 'true', which is always true for a stable tag.Also canonicalizes the appcast enclosure repo name (
Cotabby->cotabby) so the signed download URL no longer depends on GitHub's mixed-case redirect surviving a future rename/transfer.Changes:
release.yml: gate the four Pages steps (Prepare/Configure/Upload/Deploy) and theupdate-homebrew-caskjob to stable releases; make the run summary report the appcast as "not published (prerelease)" instead of printing a feed URL that was not updated.generate_appcast.py:DEFAULT_REPOSITORY->cotabby.Not changed, by decision:
sparkle:minimumSystemVersionis still omitted. The app requires macOS 14, so there is no <14 population to mis-offer; a hardcoded value would only add a drift coupling for ~zero safety.<sparkle:channel>/allowedChannelsbeta channel was added. That is a larger product feature (opt-in beta track); this PR just stops betas from leaking to stable users. If you later want a real beta channel, that is the follow-up.Validation
Confirmed:
Create GitHub ReleaseandGenerate signed appcastremain ungated (run for both channels); the four Pages steps and the Homebrew job are gated to stable; enclosure URL renders ashttps://github.com/FuJacob/cotabby/releases/download/v1.2.3/Cotabby.dmg.A release workflow can only be fully exercised by cutting a tag, so this was validated by YAML/Python parse and gating inspection rather than an end-to-end run.
Linked issues
(none filed)
Risk / rollout notes
-betatag creates a GitHub prerelease but does not move the auto-update feed or the cask. This is the intended fix.Greptile Summary
This PR closes the gap where a prerelease tag (
v1.2.3-beta) ran the full publish flow, overwriting the production Sparkle appcast and bumping the Homebrew cask. Prereleases now create a GitHub release and retain the signed appcast as an artifact for signing validation, but skip the Pages deploy and Homebrew dispatch..github/workflows/release.yml: four GitHub Pages steps and theupdate-homebrew-caskjob are gated withis_prerelease != 'true'; the run summary now reports the appcast as "not published (prerelease)" instead of a URL that was not updated.scripts/generate_appcast.py:DEFAULT_REPOSITORYchanged from"Cotabby"to"cotabby"to canonicalize the enclosure URL in signed appcasts, removing dependence on GitHub's mixed-case redirect.Confidence Score: 5/5
Safe to merge — stable release behavior is unchanged; prereleases correctly skip the Pages deploy and Homebrew dispatch.
The gating logic is straightforward:
is_prereleaseis deterministically set to the string"true"or"false"in the metadata step, and every newif:condition compares against that string using the same expression syntax already used throughout the rest of the workflow. Theupdate-homebrew-caskjob condition correctly extends the pre-existingpublish == 'true'guard. Thegenerate_appcast.pychange is a single-constant rename with no logic impact. No pre-existing paths are altered.No files require special attention.
Important Files Changed
is_prerelease != 'true'; adds a conditional summary line reporting the appcast as unpublished for prereleases. Logic, expression syntax, and job dependency ordering are all correct.DEFAULT_REPOSITORYto lowercasecotabby, eliminating reliance on GitHub's case-redirect for the enclosure URL baked into signed appcasts. No logic changes; the rest of the script is unchanged.Flowchart
%%{init: {'theme': 'neutral'}}%% flowchart TD A[Tag push / workflow_dispatch] --> B[build job] B -->|is_prerelease = version contains '-'| C{is_prerelease?} B --> D[notarize job] D --> E[publish job] E --> F[Create GitHub Release] E --> G[Generate signed appcast artifact] C -->|true / prerelease| H[Summary: appcast not published] C -->|false / stable| I[Prepare Pages artifact] I --> J[Configure GitHub Pages] J --> K[Upload Pages artifact] K --> L[Deploy GitHub Pages\nupdates.cotabby.app/appcast.xml] E --> M{publish == 'true'\nAND is_prerelease != 'true'?} M -->|yes| N[update-homebrew-cask job\ndispatch to FuJacob/homebrew-cotabby] M -->|no - prerelease or dry-run| O[skip cask update] F -.->|both paths| H G -.->|both paths| HReviews (1): Last reviewed commit: "Release: keep prereleases off the auto-u..." | Re-trigger Greptile