Skip to content

feat(update): install new versions in place with Sparkle - #3

Merged
megabuild-dev merged 4 commits into
mainfrom
feature/sparkle-auto-update
Oct 29, 2026
Merged

megabuild-dev merged 4 commits into
mainfrom
feature/sparkle-auto-update

Conversation

@megabuild-dev

@megabuild-dev megabuild-dev commented Oct 24, 2026 •

Copy link
Copy Markdown
Owner

Summary

Picnest checks for a new version 1 time a day, asks before it installs, and replaces the app in /Applications. An update skips the Open Anyway prompt that a fresh DMG needs, because Sparkle does not quarantine its download. The sessions in Application Support do not change.

Changes

  • project.yml: add the Sparkle 2 package and the disable-library-validation entitlement, set the SU* Info.plist keys, and regenerate Picnest.xcodeproj.
  • Picnest: start the updater in AppDelegate, except in the test host, and add Picnest > Check for Updates… to the menu.
  • scripts: add make-appcast.sh. It signs each archive, makes the delta updates, and writes docs/appcast.xml for GitHub Pages.
  • Tests: the test host starts no updater. The existing quit guard already stops an install while a sort runs.
  • Docs: README, BUILD.md, and the design spec section 8 and risks 8 and 11.

Test plan

  • Build and run the app; confirm Check for Updates… appears in the Picnest menu.
  • Run the test suite; confirm AppDelegateTests passes and the test host starts no updater.
  • Run scripts/make-appcast.sh against a signed archive and confirm docs/appcast.xml is written.

    Picnest checks for a new version 1 time a day, asks before it installs, and
    replaces the app in /Applications. An update skips the Open Anyway prompt that a
    fresh DMG needs, because Sparkle does not quarantine its download. The sessions
    in Application Support do not change.

    - project.yml: add the Sparkle 2 package and the disable-library-validation
      entitlement, set the SU* Info.plist keys, and regenerate Picnest.xcodeproj.
    - Picnest: start the updater in AppDelegate, except in the test host, and add
      Picnest > Check for Updates… to the menu.
    - scripts: add make-appcast.sh. It signs each archive, makes the delta updates,
      and writes docs/appcast.xml for GitHub Pages.
    - Tests: the test host starts no updater. The existing quit guard already stops
      an install while a sort runs.
    - Docs: README, BUILD.md, and the design spec section 8 and risks 8 and 11.

@thanhnh98 thanhnh98 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The Sparkle integration is generally well structured, and both application tests and all 319 PicnestCore tests pass locally.

I left five follow-up comments covering production signing, MainActor isolation, dependency pinning, automatic-update semantics, and test coverage. Please address these before the production release.

GitHub CI is currently red with two core-test issues, while a clean local rerun passed all 319 tests. Please rerun or investigate the failing job before merging.

At the time of review, both the configured appcast URL and the GitHub updates release return 404, so scheduled and manual checks cannot find an update yet. Suggested release checks:

  1. Enable GitHub Pages for /docs.
  2. Generate and commit docs/appcast.xml.
  3. Create the updates release and upload the signed archives and delta files.
  4. Add a smoke check that fails when the published appcast or its enclosure URLs are unavailable.
  5. Perform one end-to-end update from an older installed build before publishing.

Comment thread Picnest/App/UpdaterCommands.swift Resolved
Comment thread Picnest/Picnest.entitlements Resolved
Comment thread PicnestTests/AppDelegateTests.swift Resolved
Comment thread project.yml Resolved
Comment thread project.yml Resolved
- Keep library validation on in Release; only Debug disables it.
- Read canCheckForUpdates from the KVO change, not off the main actor.
- Put the updater behind an AppUpdater protocol and test the positive path with a fake.
- Commit Package.resolved to pin Sparkle 2.10.0.
- Set SUAllowsAutomaticUpdates to false so every install needs approval.
scripts/check-appcast.sh fails when the appcast or an enclosure URL returns an error.
BUILD.md runs it after the feed is published and adds the end-to-end update test.
startNewSortWaitsUntilTheSortServiceIsIdle slept 50 ms and asserted a wait of at least 150 ms,
which failed on a slow CI runner (52 ms). Poll until the blocking sort runs, then assert the sort
is idle when startNewSort returns.
@megabuild-dev
megabuild-dev merged commit b1a1e09 into main Oct 29, 2026
1 check passed
@megabuild-dev
megabuild-dev deleted the feature/sparkle-auto-update branch October 29, 2026 13:32
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.

3 participants