Skip to content

fix(desktop): make locally-built macOS app relaunchable after in-place self-update - #36198

Merged
OutThisLife merged 1 commit into
mainfrom
bb/mac-desktop-update-relaunch
Jun 1, 2026
Merged

fix(desktop): make locally-built macOS app relaunchable after in-place self-update#36198
OutThisLife merged 1 commit into
mainfrom
bb/mac-desktop-update-relaunch

Conversation

@OutThisLife

Copy link
Copy Markdown
Collaborator

Summary

On macOS the desktop app is built locally and ad-hoc signed (users have no Developer ID). An ad-hoc bundle has no stable Designated Requirement (no Team ID), so when the self-updater rebuilds it in place with a fresh build (new cdhash) — plus the com.apple.quarantine flag inherited from the downloaded installer's process chain — Gatekeeper/LaunchServices treats the changed code as tampering and macOS reports "Hermes is damaged and can't be opened," then fails to relaunch.

Repro (fresh Mac, happy path): download the signed/notarized thin installer → install (builds Hermes.app locally) → first launch works → click Update in-app → "Hermes is damaged," app does not reopen. First launch works because it's a fresh registration; the in-place relaunch is what breaks.

Fix

After building the desktop app locally, strip quarantine xattrs and re-apply a clean deep ad-hoc signature (omitting the hardened-runtime flag an ad-hoc build can't satisfy), so the rebuilt bundle relaunches.

Applied in both build entry points so it ships via hermes update (git) with no installer re-download:

  • hermes_cli/main.py cmd_gui — the hermes desktop --build-only path the updater drives.
  • scripts/install.sh install_desktop — first install, for parity.

Both are no-ops on non-macOS and when a real signing identity (CSC_LINK / APPLE_SIGNING_IDENTITY) is configured, so signed/notarized builds are never clobbered.

Why this is the right layer

The signed+notarized thin installer (Hermes Setup) is the downloaded artifact and is unaffected. The big Electron Hermes.app is always built on the user's machine (ad-hoc), so making the locally built app relaunch-safe is the correct fix — and putting it in the build path means existing installs self-heal on their next hermes update.

Test plan

  • python -c "import ast; ast.parse(...)" on main.py, bash -n scripts/install.sh pass.
  • Confirmed the built app is flags=0x10002(adhoc,runtime) and that an in-place ad-hoc rebuild is what trips the "damaged" check.
  • On a fresh Mac: install via the notarized thin installer → click Update in-app → verify it rebuilds, relaunches, and shows no "damaged" dialog.

Loading
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.

1 participant