Skip to content

Commit 9d7d1c2

Browse files
eriknielsenclaude
andcommitted
Fix DMG build: volume icon, single-conversion pipeline
Root cause: AppleScript's "update without registering applications" deletes .VolumeIcon.icns. Fix: copy icon AFTER AppleScript runs. Replaced the lossy create-dmg → R/W → modify → UDZO pipeline with a single R/W DMG built from scratch, styled via AppleScript, then converted once to UDZO. No metadata loss. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 702e562 commit 9d7d1c2

File tree

1 file changed

+23
-35
lines changed

1 file changed

+23
-35
lines changed

scripts/build-release.sh

Lines changed: 23 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -59,49 +59,33 @@ spctl --assess --type exec "${APP_PATH}" && echo " Gatekeeper: ACCEPTED" || ec
5959
echo "==> Creating DMG..."
6060
DMG_DIR="build/dmg"
6161
DMG_PATH="build/${APP_NAME}.dmg"
62-
rm -rf "${DMG_DIR}" "${DMG_PATH}"
62+
RW_DMG="build/${APP_NAME}-rw.dmg"
63+
rm -rf "${DMG_DIR}" "${DMG_PATH}" "${RW_DMG}"
6364
mkdir -p "${DMG_DIR}"
6465
cp -R "${APP_PATH}" "${DMG_DIR}/"
6566
rm -rf "${SIGN_DIR}"
6667

67-
# Create a Finder alias to /Applications instead of a symlink.
68-
# Symlinks show a broken/generic icon on macOS Sonoma+ when mounted as read-only DMG.
69-
# Finder aliases always resolve the proper Applications folder icon.
70-
# Step 1: Let create-dmg build with symlink (it handles positioning)
71-
create-dmg \
72-
--volname "${APP_NAME}" \
73-
--volicon "scripts/dmg-volume-icon.icns" \
74-
--background "scripts/dmg-background@2x.png" \
75-
--window-pos 200 120 \
76-
--window-size 660 480 \
77-
--icon-size 96 \
78-
--text-size 14 \
79-
--icon "${APP_NAME}.app" 170 170 \
80-
--hide-extension "${APP_NAME}.app" \
81-
--app-drop-link 490 170 \
82-
--no-internet-enable \
83-
"${DMG_PATH}" \
84-
"${DMG_DIR}"
85-
86-
# Step 2: Replace symlink with Finder alias (fixes broken icon on Sonoma+)
87-
# Mount the DMG as read-write, swap the symlink, then convert back
88-
RW_DMG="${DMG_PATH%.dmg}-rw.dmg"
89-
hdiutil convert "${DMG_PATH}" -format UDRW -o "${RW_DMG}"
90-
rm "${DMG_PATH}"
91-
68+
# Build R/W DMG directly — no intermediate conversions that lose metadata
69+
DMG_SIZE_MB=$(( $(du -sm "${DMG_DIR}" | awk '{print $1}') + 20 ))
70+
hdiutil create -size ${DMG_SIZE_MB}m -fs HFS+ -volname "${APP_NAME}" -o "${RW_DMG}"
9271
MOUNT_DIR=$(hdiutil attach "${RW_DMG}" -readwrite -noverify | grep Apple_HFS | awk '{print $3}')
9372
echo " Mounted R/W at: ${MOUNT_DIR}"
9473

95-
# Remove symlink, create Finder alias
96-
rm "${MOUNT_DIR}/Applications"
74+
# Copy app
75+
cp -R "${DMG_DIR}/${APP_NAME}.app" "${MOUNT_DIR}/"
76+
77+
# Create Finder alias to /Applications (not a symlink — symlinks show broken icon on Sonoma+)
9778
osascript -e "tell application \"Finder\" to make new alias file at POSIX file \"${MOUNT_DIR}\" to POSIX file \"/Applications\""
9879
mv "${MOUNT_DIR}/Applications alias" "${MOUNT_DIR}/Applications" 2>/dev/null || true
9980

100-
# Re-apply Finder window styling after alias creation.
101-
# The Finder alias step regenerates .DS_Store, resetting all icon positions.
102-
# This AppleScript re-positions everything: app + Applications in view,
103-
# all other items pushed far off-screen.
104-
echo " Re-applying Finder window layout..."
81+
# Set up background image
82+
mkdir -p "${MOUNT_DIR}/.background"
83+
cp "scripts/dmg-background@2x.png" "${MOUNT_DIR}/.background/"
84+
85+
# Set volume icon
86+
# Apply Finder window styling via AppleScript
87+
# NOTE: volume icon is set AFTER this step — AppleScript's "update" deletes it
88+
echo " Applying Finder window layout..."
10589
VOLNAME=$(basename "${MOUNT_DIR}")
10690
osascript << APPLESCRIPT
10791
tell application "Finder"
@@ -126,7 +110,6 @@ tell application "Finder"
126110
try
127111
set position of item ".fseventsd" to {900, 900}
128112
end try
129-
-- .VolumeIcon.icns must stay — it provides the title bar icon
130113
try
131114
set position of item ".DS_Store" to {900, 900}
132115
end try
@@ -139,11 +122,16 @@ tell application "Finder"
139122
end tell
140123
APPLESCRIPT
141124

142-
# Unmount and convert to compressed read-only
125+
# Set volume icon AFTER AppleScript (the "update" command deletes .VolumeIcon.icns)
126+
cp "scripts/dmg-volume-icon.icns" "${MOUNT_DIR}/.VolumeIcon.icns"
127+
SetFile -a C "${MOUNT_DIR}"
128+
129+
# Convert to compressed read-only (single conversion, no metadata loss)
143130
sync
144131
hdiutil detach "${MOUNT_DIR}"
145132
hdiutil convert "${RW_DMG}" -format UDZO -o "${DMG_PATH}"
146133
rm "${RW_DMG}"
134+
rm -rf "${DMG_DIR}"
147135

148136
echo "==> Notarizing..."
149137
xcrun notarytool submit "${DMG_PATH}" \

0 commit comments

Comments
 (0)