Skip to content

v0.5.6 — In-app update installer

Choose a tag to compare

@ChiFungHillmanChan ChiFungHillmanChan released this 23 Apr 21:45
· 19 commits to main since this release

In-app update installer

Click Update available in the menu, click Install and Restart in the confirmation alert, and Scene downloads the new DMG, swaps itself out for the new bundle, and relaunches automatically. No more "open release page → download → mount → drag → re-grant Accessibility" ritual. Accessibility permission survives the update because TCC's Designated Requirement is stable across any Developer ID-signed release, and ditto --noqtn preserves the com.apple.macl xattr that anchors the grant.

What's new

  • Click → install → relaunch. The "Update available" menu item now opens a confirmation NSAlert with three actions: Install and Restart (default), Release Notes… (opens the GitHub release page in the browser, the pre-V0.5.6 behavior), Later (dismiss). On Install, UpdateInstaller downloads the new DMG to ~/Library/Caches/Scene/, verifies the signature with codesign -dv and confirms TeamIdentifier=22K6G3HH9G, writes a detached helper bash script to /tmp/, launches it via nohup, and quits Scene. The helper waits for Scene's PID to exit, mounts the DMG, replaces the installed bundle (read from Bundle.main.bundleURL so non-/Applications installs are also handled) via ditto --noqtn, strips the destination's com.apple.quarantine xattr, refreshes LaunchServices, unmounts, deletes the cached DMG, and opens the new Scene.
  • Accessibility permission survives across updates. TCC binds the grant to the binary's Designated Requirement (anchor apple generic and identifier "com.hillman.SceneApp" and certificate ... and certificate leaf[subject.OU] = "22K6G3HH9G"), which is stable across any release signed with the same Developer ID. ditto preserves the com.apple.macl xattr — TCC's per-file pointer that anchors the grant to the bundle on disk. The new install launches with AXIsProcessTrusted already true: no re-grant, no tccutil reset, no toggling System Settings.
  • Verification before install. The downloaded DMG is codesign -dv-checked and the embedded TeamIdentifier is matched against 22K6G3HH9G before the helper script runs. A DMG signed by a different Team ID is rejected and surfaced as an error alert — no silent downgrade or impersonation.
  • Rollback on install failure. Helper backs up the old app to /tmp/Scene.app.bak-$$ before ditto. If ditto fails, the backup is restored and the DMG is unmounted; the old Scene is left in place. Logs go to /tmp/scene-update-<pid>.log for post-mortems.

Why this matters

Every previous Scene release nudged you to the GitHub release page and made you do the "mount → drag to Applications → re-launch → re-grant Accessibility" five-step dance by hand. Even with notarization (V0.5.0+), the cdhash-binding cdhash of TCC meant Accessibility re-grants happened more often than they should. V0.5.6 closes the loop: you click once, Scene replaces itself, and your AX grant carries over because the new binary has the same Designated Requirement and inherits the com.apple.macl xattr from the old install.

Under the hood

  • SceneApp/SceneApp/UpdateInstaller.swift (new, ~150 LOC) — download + verify + helper-script launcher.
  • SceneApp/SceneApp/UpdateChecker.swift — adds a dmgURL @Published field, populated from the GitHub release assets[] (first .dmg wins).
  • SceneApp/SceneApp/MenuBarContentView.swift — wires the menu item click to a three-button NSAlert.
  • SceneApp/SceneApp/SceneAppApp.swift + SceneApp/SceneApp/AppDelegate.swift — instantiate and inject UpdateInstaller as an environment object.
  • Localizable.xcstrings — 9 new keys × 3 languages (en, zh-HK, zh-TW).
  • No SceneCore changes. 177/177 unit tests still pass.
  • Hardened runtime, Developer ID signed, Apple notarized + stapled.

Install

Homebrew (recommended):

brew upgrade --cask scene                         # existing users
brew install --cask chifunghillmanchan/tap/scene  # new users

DMG: download Scene-0.5.6.dmg below, double-click, drag into Applications. Universal binary — works on Apple Silicon and Intel.

Upgrade notes

  • One last manual install. V0.5.5's menu item still opens the GitHub release page (the in-app installer ships with this V0.5.6 release). After you install V0.5.6 manually, every future update from V0.5.6 → V0.5.7 → ... will install in-app with no manual download.
  • Accessibility grant survives V0.5.5 → V0.5.6 if you replace /Applications/Scene.app with the new bundle from the DMG via Finder's drag-replace (which preserves the com.apple.macl xattr). Both releases are signed with the same Developer ID + Team ID, so the TCC entry's csreq continues to match.
  • First-time installers: grant Accessibility once in System Settings → Privacy & Security → Accessibility. After that, V0.5.6+ updates preserve the grant automatically.