Skip to content

fix: give the macOS dmg somewhere to drag the app - #145

Merged
yujiezhang-ops merged 1 commit into
mainfrom
fix/dmg-drag-install
Aug 10, 2026
Merged

fix: give the macOS dmg somewhere to drag the app#145
yujiezhang-ops merged 1 commit into
mainfrom
fix/dmg-drag-install

Conversation

@yujiezhang-ops

Copy link
Copy Markdown
Collaborator

Fixes #144. Reduces the trigger for #143.

The problem

Opening OneAgent-darwin-arm64.dmg showed a single OneAgent icon and nothing else — no /Applications symlink, 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 create was 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.

/private/var/folders/.../AppTranslocation/79C329CB-.../d/OneAgent.app

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:

backing up /private/var/folders/.../d/OneAgent.app → ....app.bak
backup failed: mkdir ....app.bak: read-only file system

helper.go:122 returns 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 -srcfolder at 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 NOTICE change. create-dmg would additionally give icon positions and a background image, but those need a .DS_Store written by Finder via AppleScript, which is unreliable on a headless runner, and it would become a third-party attribution obligation under docs/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:

lrwxr-xr-x  Applications -> /Applications
drwxr-xr-x  OneAgent.app
verify exit: 0

And against a deliberately broken dmg built without the symlink, confirming the check is load-bearing rather than decorative:

Applications symlink missing from dmg
links to "", want /Applications
verify exit on a bad dmg: 1 (want 1)

The workflow YAML parses, and check-docs.py is clean.

The OTA .zip step is untouched: it names OneAgent.app explicitly (zip -qry ... OneAgent.app) and asserts a single root entry, and bin/dmg-root is 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

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>
@yujiezhang-ops
yujiezhang-ops requested a review from a team August 10, 2026 07:39
@yujiezhang-ops
yujiezhang-ops merged commit bfb2dba into main Aug 10, 2026
4 checks passed
@yujiezhang-ops
yujiezhang-ops deleted the fix/dmg-drag-install branch August 10, 2026 07:41
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.

dmg 没有拖拽引导,用户不知道要放进应用程序文件夹

1 participant