Skip to content

feat(release): publish Sparkle payloads to thaw-app/updates - #840

Merged
diazdesandi merged 3 commits into
developmentfrom
feat/sparkle-updates-repo
Jul 28, 2026
Merged

feat(release): publish Sparkle payloads to thaw-app/updates#840
diazdesandi merged 3 commits into
developmentfrom
feat/sparkle-updates-repo

Conversation

@diazdesandi

@diazdesandi diazdesandi commented Jul 28, 2026

Copy link
Copy Markdown
Member

Summary

Split release artifacts so installers stay on Thaw and Sparkle update payloads live on the dedicated thaw-app/updates feed host. Pins sparkle-release to the org-ci SHA that supports updates-repository (thaw-app/org-ci#2) and points SUFeedURL at the new Pages URL.

Scope: Release pipeline + feed URL only. No product UI changes.

Closes: N/A

PR Type

Describe what this change does (not the linked issue’s request kind). Bug reports use bug on issues; bug fixes use fix on PRs.

If you tick Feature or Refactor and touch more than ~20 files, please mention why this can’t be split.

  • Bug fix
  • CI/CD
  • Documentation
  • Feature
  • Enhancement
  • Performance improvement
  • Refactor
  • Test addition or update
  • Other (please describe)

Area

Product surfaces (optional when the change is not about the app UI). Path-based labeling also applies.

  • Use PR Type for what changed (CI/CD, Documentation, Other / chore, etc.).

  • Use ops for where when it is repo operations: CI, release, GitHub hygiene, scripts, lint/sonar config — not a product surface.

  • menubar

  • icebar

  • layout

  • appearance

  • settings

  • onboarding

  • permissions

  • profiles

  • hotkeys

  • updates

  • ops

Does this PR introduce a breaking change?

  • Yes - if yes, please describe the impact and migration path
  • No

New builds poll https://thaw-app.github.io/updates/appcast.xml. Existing installs keep the baked-in legacy SUFeedURL (stonerl.github.io/Thaw) until that host redirects (or users update via the old feed once it is back). Historical enclosure URLs in the seeded appcast are left unchanged.

What is the new behavior?

  • Thaw GitHub Releases: DMG only (human installers)
  • thaw-app/updates releases: Sparkle ZIP + deltas
  • Appcast: published to thaw-app/updates gh-pages
  • SUFeedURL: https://thaw-app.github.io/updates/appcast.xml
  • Release workflow requires secret UPDATES_GITHUB_TOKEN (contents: write on thaw-app/updates)

PR Checklist

  • I've built and run the app locally and verified that it works as expected.
  • I've run swiftformat . to keep the code style consistent.
  • I've run the smallest relevant test commands (list 1–2 below), e.g. xcodebuild test … or swift test --package-path MenuBarModel.
  • I've added tests for new behavior (if applicable).
  • I've documented new public APIs / non-obvious helpers.
  • I've updated documentation as needed.
  • This PR targets the development branch.

Test commands run:

  • N/A (workflow / plist / docs only — verify via draft release below)

Known limitations / follow-ups

  • Merge org-ci#2; re-pin to merge commit if desired
  • Add UPDATES_GITHUB_TOKEN on Thaw (repo or org secret)
  • Enable Pages on thaw-app/updates (gh-pages) and seed current appcast.xml
  • Bring stonerl.github.io/Thaw back with an HTTP redirect to the new feed

Other information

Manual verification:

  • Draft release (publish_release unchecked): DMG draft on Thaw, ZIP/deltas draft on updates, no appcast push
  • Publish release with publish_appcast: enclosure URLs under github.com/thaw-app/updates/releases/download/...
  • Confirm live feed at https://thaw-app.github.io/updates/appcast.xml

Summary by CodeRabbit

  • New Features

    • Release artifacts are now published separately: DMG downloads from the main repo and Sparkle update payloads from the updates repo.
    • Automatic updates use the new appcast feed at https://thaw-app.github.io/updates/appcast.xml.
  • Bug Fixes

    • Improved appcast publishing reliability with serialized runs and retry logic during appcast.xml updates.
  • Documentation

    • Updated release verification guidance to reference the new feed URL and note legacy polling behavior until redirect.

Keep DMGs on Thaw GitHub Releases; host ZIP, deltas, and appcast on the
dedicated updates repo. Point SUFeedURL at the new Pages feed.
@coderabbitai

coderabbitai Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: e6c4bf38-61c6-4b70-bfbf-fda218f917d7

📥 Commits

Reviewing files that changed from the base of the PR and between 2086016 and e8e1783.

📒 Files selected for processing (1)
  • .github/workflows/release.yml

📝 Walkthrough

Walkthrough

The release workflow now separates DMG releases from Sparkle update payloads, publishes payloads and appcast.xml through thaw-app/updates, and updates the application and verification documentation to use the new appcast URL.

Changes

Sparkle release migration

Layer / File(s) Summary
Split release and appcast publishing
.github/workflows/release.yml
The workflow separates DMG and Sparkle payload releases, serializes appcast publishing, and pushes appcast.xml to the updates repository with retry handling.
Update feed configuration
Thaw/Resources/Info.plist, docs/VERIFYING_RELEASES.md
The application and verification documentation reference https://thaw-app.github.io/updates/appcast.xml, with a note for legacy installations.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ReleaseWorkflow
  participant SparkleRelease
  participant ThawRepository
  participant UpdatesRepository
  ReleaseWorkflow->>SparkleRelease: Build ZIP and delta payloads
  SparkleRelease->>ThawRepository: Publish DMG release
  SparkleRelease->>UpdatesRepository: Publish Sparkle payload release
  ReleaseWorkflow->>UpdatesRepository: Push appcast.xml to gh-pages
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately summarizes the main release-pipeline change.
Description check ✅ Passed The description follows the template well and includes summary, type, area, breaking change, behavior, checklist, and follow-ups.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/sparkle-updates-repo

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added the ops CI, release, GitHub hygiene, scripts — repo operations, not a product surface label Jul 28, 2026

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/release.yml:
- Around line 173-200: Reorder the release steps so “Create updates GitHub
Release (ZIP + deltas)” runs before “Create Thaw GitHub Release (DMG)”, ensuring
updates-repository failures occur before the DMG becomes public. Keep each
step’s existing configuration and publication behavior unchanged.
- Around line 140-151: Update the `sparkle-release` action reference in the
release workflow from the temporary commit SHA to a stable merged default-branch
ref or release tag, while preserving all existing inputs including
`updates-repository` and `updates-token`.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 1cc1af0b-0b8c-493a-918f-5d6c100b338b

📥 Commits

Reviewing files that changed from the base of the PR and between 2168eb5 and 0178779.

📒 Files selected for processing (3)
  • .github/workflows/release.yml
  • Thaw/Resources/Info.plist
  • docs/VERIFYING_RELEASES.md

Comment thread .github/workflows/release.yml Outdated
Comment on lines 140 to 151
uses: thaw-app/org-ci/actions/sparkle-release@9944dd9543eeb383493e428f92e262cb299dc1ff
with:
tag: ${{ steps.meta.outputs.tag }}
channel: ${{ steps.meta.outputs.channel }}
app-name: ${{ env.APP_NAME }}
asset-prefix: Thaw
appcast-title: Thaw
sparkle-private-key: ${{ secrets.SPARKLE_ED25519_PRIVATE_KEY }}
updates-repository: ${{ env.UPDATES_REPOSITORY }}
updates-token: ${{ secrets.UPDATES_GITHUB_TOKEN }}
release-html-url: https://github.com/${{ github.repository }}/releases/tag/${{ steps.meta.outputs.tag }}
publish-appcast: "false"

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.

🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Confirm the pinned commit exists and check whether it's reachable from org-ci's default branch.
gh api repos/thaw-app/org-ci/commits/9944dd9543eeb383493e428f92e262cb299dc1ff --jq '.sha, .commit.message' 2>&1 || echo "commit lookup failed (private repo or unreachable)"
gh api repos/thaw-app/org-ci/contents/actions/sparkle-release/action.yml?ref=9944dd9543eeb383493e428f92e262cb299dc1ff --jq '.content' 2>&1 | base64 -d 2>/dev/null | grep -A2 'updates-repository\|updates-token'

Repository: thaw-app/Thaw

Length of output: 1322


Pin sparkle-release to a stable, merged ref.

The pinned commit exists and contains updates-repository/updates-token, but it is a short-lived commit-sha pin. Once the org-ci change is merged, update this workflow to a stable default-branch ref or tag so the action cannot become unreachable if the source branch is rebased/deleted.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/release.yml around lines 140 - 151, Update the
`sparkle-release` action reference in the release workflow from the temporary
commit SHA to a stable merged default-branch ref or release tag, while
preserving all existing inputs including `updates-repository` and
`updates-token`.

Comment thread .github/workflows/release.yml Outdated
Fail closed on updates-repository publish before the Thaw DMG goes public,
and pin sparkle-release to the merged org-ci main SHA.
@github-actions github-actions Bot added breaking-change PR introduces a breaking change cd Related to deployments or release automation ci Related to continuous integration workflows or runners. docs Improvements or additions to documentation updates Sparkle / release channels / appcast labels Jul 28, 2026

@coderabbitai coderabbitai Bot left a comment

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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.github/workflows/release.yml (1)

221-226: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Remove the failed clone directory before the bootstrap clone.

When gh-pages does not yet exist, the failed branch clone can leave $work populated; the fallback git clone then fails because its destination is non-empty. This prevents the workflow from seeding the appcast branch.

Proposed fix
             if git clone --depth 1 --branch gh-pages "$remote" "$work" 2>/dev/null; then
               :
             else
+              rm -rf "$work"
               git clone --depth 1 "$remote" "$work"
               git -C "$work" checkout --orphan gh-pages
               git -C "$work" rm -rf . >/dev/null 2>&1 || true
             fi
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/release.yml around lines 221 - 226, Update the fallback
branch of the release workflow’s gh-pages clone logic to remove the failed clone
destination at $work before running the bootstrap git clone. Preserve the
existing orphan-branch checkout and cleanup steps after the fallback clone.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In @.github/workflows/release.yml:
- Around line 221-226: Update the fallback branch of the release workflow’s
gh-pages clone logic to remove the failed clone destination at $work before
running the bootstrap git clone. Preserve the existing orphan-branch checkout
and cleanup steps after the fallback clone.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 33d31bd5-01e0-45c2-b270-ee4b79df7f94

📥 Commits

Reviewing files that changed from the base of the PR and between 0178779 and 2086016.

📒 Files selected for processing (1)
  • .github/workflows/release.yml

A failed --branch gh-pages clone can leave $work behind; remove it before the
fallback clone so orphan-branch bootstrap can proceed.
@diazdesandi
diazdesandi merged commit 6f326a7 into development Jul 28, 2026
1 of 2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking-change PR introduces a breaking change cd Related to deployments or release automation ci Related to continuous integration workflows or runners. docs Improvements or additions to documentation ops CI, release, GitHub hygiene, scripts — repo operations, not a product surface updates Sparkle / release channels / appcast

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant