Fix update-channel regressions: nightly exit + older nightly filtering

Closed
LA
1mo ago
+229-0

Summary

  • fix the nightly -> stable escape hatch by allowing stable appcast selection when the app is on a nightly build and nightly updates are disabled
  • prevent nightly channel from suggesting older semantic versions (example: being on 0.58.x and getting offered 0.56.x-nightly)
  • add regression coverage for both behaviors

Why

Two bad update-channel edge cases were possible:

  1. After installing nightly, disabling nightly could trap the user because Sparkle treated stable as older (onNewerThanLatestVersion).
  2. Enabling nightly could offer a numerically older release series due nightly build-number ordering.

What changed

Sources/Update/UpdateDelegate.swift

  • added semantic version parsing in UpdateChannelSettings
  • added shouldOfferNightlyCandidate(...) guard
  • expanded bestValidUpdate(in:for:) logic:
    • when nightly is OFF and current build is nightly: select latest stable item (enables leaving nightly)
    • when nightly is ON: only select appcast items whose semantic version is >= current semantic version
    • if nightly is ON and no eligible semantic candidate exists: return SUAppcastItem.empty() to avoid falling back to an older nightly suggestion

cmuxTests/CmuxWebViewKeyEquivalentTests.swift

  • added regression tests for:
    • toggling nightly off returns to stable feed
    • stable downgrade offer logic for nightly-installed builds
    • nightly candidate selection when semantic version is equal/newer
    • nightly candidate rejection when semantic version is older (0.58 current vs 0.56-nightly candidate)

Verification

  • xcodebuild -project GhosttyTabs.xcodeproj -scheme cmux-unit -configuration Debug -destination 'platform=macOS' -only-testing:cmuxTests/UpdateChannelSettingsTests test
  • ./scripts/reload.sh --tag fix-nightly-exit
  • xcodebuild -project GhosttyTabs.xcodeproj -scheme cmux -configuration Debug -destination 'platform=macOS' build