fix: give the macOS dmg somewhere to drag the app - #145
Merged
Conversation
The dmg was built by pointing -srcfolder at the bundle, so the volume held a single icon with no /Applications symlink beside it. Nothing tells the user where the app is supposed to go, and double-clicking it in the mounted image is the natural reaction. Gatekeeper answers that with App Translocation: the bundle runs from a random read-only path, where the updater cannot create its backup. The helper returns before either of its restore paths, so the app exits on "restart and update" and never comes back, with no message anywhere the user can see (#143). Staging through a directory adds the symlink. A verify step follows, because a dmg that lost it still installs correctly -- nothing downstream would fail, and the regression would only surface as users running the app from the image. Refs #144, #143 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #144. Reduces the trigger for #143.
The problem
Opening
OneAgent-darwin-arm64.dmgshowed a single OneAgent icon and nothing else — no/Applicationssymlink, no arrow, no hint about where the app is supposed to go. The window looked like the app was meant to be run from there.hdiutil createwas pointed straight at the bundle, so the volume contained exactly one entry:hdiutil create -volname OneAgent -srcfolder "bin/OneAgent.app" ...Why this is more than cosmetic
Running the app from the mounted image is what the layout invites, and macOS answers it with App Translocation: the bundle is mounted at a random read-only path.
The updater backs up the bundle before replacing it, and that volume is read-only. From the helper logs on a real machine, four times:
helper.go:122returns 12 there, which is before both of the helper's restore paths (they are conditioned on the swap attempts being exhausted or the launch failing). So the app exits on "restart and update" and never comes back, and the exit code goes nowhere — the helper is a detached process that outlives the UI, and its only record is$TMPDIR/wails-update-<pid>.log.The user sees: click update, app disappears, reopen it manually, still on the old version, no explanation.
So the missing symlink is an upstream cause of #143, not just an aesthetic gap.
The change
Stage into a directory, add the symlink, point
-srcfolderat that:mkdir -p bin/dmg-root cp -R "bin/OneAgent.app" bin/dmg-root/ ln -s /Applications bin/dmg-root/Applications hdiutil create -volname OneAgent -srcfolder bin/dmg-root ...Only built-in tools, no new dependency — which also means no
NOTICEchange.create-dmgwould additionally give icon positions and a background image, but those need a.DS_Storewritten by Finder via AppleScript, which is unreliable on a headless runner, and it would become a third-party attribution obligation underdocs/distribution-compliance-policy.md. The symlink covers most of the benefit at none of that cost; background art can come later as its own change.A verify step follows the packaging. A dmg that lost the symlink still installs correctly, so nothing downstream would fail and the regression would ship silently — surfacing only as users running the app from the image. The check asserts the bundle is present, the symlink exists, and that it is absolute: a relative link resolves against the mounted volume on the user's machine, where it points at nothing.
Verification
Both the layout and the check were run locally on macOS:
And against a deliberately broken dmg built without the symlink, confirming the check is load-bearing rather than decorative:
The workflow YAML parses, and
check-docs.pyis clean.The OTA
.zipstep is untouched: it namesOneAgent.appexplicitly (zip -qry ... OneAgent.app) and asserts a single root entry, andbin/dmg-rootis removed before it runs, so the archive the updater consumes is unchanged.Not covered here
#143 itself. This makes the bad path less likely to be taken; it does not stop a user who has the app somewhere unwritable from being told nothing. That needs the app to detect translocation and decline to offer an update in the first place, which is the more valuable half.
Icon layout and background image are deliberately out of scope, per the reasoning above.
Untested on hardware: whether Finder renders the two icons side by side without an explicit
.DS_Store. It will show both entries; their arrangement is up to Finder's defaults.🤖 Generated with Claude Code