fix(macos): size the DMG ourselves, and stop blaming the runner's disk (#477)

The nightly channel has been frozen since 06:32 on 2026-08-10: every run
dies in bundle-macos.sh with "hdiutil: create failed - No space left on
device", on macos-15-intel, after the build, the signing and the
notarization have all succeeded.

The host disk was never full. #476 read that message as the runner running
out of room and freed space for it; the `df -h` it added to prove the point
disproved it instead — 105 GiB available, and the run failed anyway. The
path in the error is under /Volumes/tty7, which is the image being created,
not the runner: the volume ran out, not the disk.

`hdiutil create -srcfolder` sizes the image from the bytes it is about to
copy and does not cover what the filesystem spends carrying them, so a
bundle that fits by measurement still runs the volume dry partway through
the copy. It is a threshold rather than a cliff, which is why this began
without anyone touching packaging: the binaries grew over edfadb7..fafcaa0,
the x86_64 pair is the larger one and crossed it first, and arm64 kept
building fine just underneath.

Ask for the room explicitly — twice the content plus 64 MiB. The image is
compressed on the way out, so the slack is nearly free: on a stage of this
shape, 127 MiB of empty volume cost 672 KiB in the published DMG.

Also drop #476's deletion of the build tree. It was paying for a problem
that did not exist, and the bill was rust-cache finding nothing to save and
every macOS build recompiling the dependency graph. The `mv` from that
commit stays: a second full copy of the bundle is genuinely redundant, and
nothing reads dist/tty7.app after this point.

Verified locally against a staged bundle of the real shape (73 MiB, 101
files): the image is created, mounts with every file present, and detaches
clean. The remaining unknown is only whether CI agrees, which the next
nightly answers.

Co-authored-by: l0ng-ai <24760907+l0ng-ai@users.noreply.github.com>
This commit is contained in:
l0ng-ai
2026-08-10 22:31:23 +08:00
committed by GitHub
co-authored by l0ng-ai
parent 05ed9fa4ff
commit c216b389ae
+16 -17
View File
@@ -210,12 +210,6 @@ if [[ "$PACKAGE_UPDATE_ZIP" != "0" ]]; then
fi
# Package the (now stapled) bundle as a drag-to-Applications DMG.
#
# `hdiutil` needs room for the whole image beside the staged bundle, and the
# hosted Intel runners stopped having it — three nightlies in a row died right
# here on 2026-08-10 with "hdiutil: create failed - No space left on device",
# across two different commits. The arm64 runners have never hit it. So the two
# steps below give the image somewhere to go rather than assuming there is room.
DMG="dist/tty7-${VERSION}-macos-${ARCH}.dmg"
STAGE="dist/dmg-stage"
rm -rf "$STAGE"
@@ -227,17 +221,22 @@ mkdir "$STAGE"
# knows about tty7.app as an intermediate to keep out of the upload globs.
mv "$APP" "$STAGE/"
ln -s /Applications "$STAGE/Applications"
# The build tree is dead weight from here on: every binary it produced is
# already inside the bundle, and no later step in either workflow reads it.
# The cost is that rust-cache finds little left to save, so the next macOS
# build recompiles the dependency graph. That is a slower nightly; the
# alternative is no nightly at all. `df` first so the next person to look at
# this has the number that made it necessary.
df -h . || true
rm -rf "target/${TARGET}/release/deps" \
"target/${TARGET}/release/build" \
"target/${TARGET}/release/incremental"
hdiutil create -volname "tty7" -srcfolder "$STAGE" -ov -format UDZO "$DMG"
# Size the image explicitly. Left to itself, `-srcfolder` measures the bytes it
# is about to copy and asks for about that much, which does not cover what the
# filesystem spends carrying them — so the copy runs the *volume* out of room
# partway through and hdiutil reports "No space left on device". The path in
# that message is under /Volumes/tty7, not on the host: three nightlies died
# here on 2026-08-10 with 105 GiB free on the runner. It is a threshold, not a
# cliff — the x86_64 binaries are the larger pair and crossed it first, while
# arm64 went on building fine just underneath.
#
# Doubling the content and adding 64 MiB is far more slack than the shortfall
# needs, and it is close to free: the image is compressed on the way out, so
# measured against a stage of this shape, 127 MiB of empty volume cost 672 KiB
# in the published DMG.
STAGE_KB="$(du -sk "$STAGE" | awk '{print $1}')"
hdiutil create -volname "tty7" -srcfolder "$STAGE" -ov -format UDZO \
-size "$(( STAGE_KB * 2 + 65536 ))k" "$DMG"
rm -rf "$STAGE"
if [[ -n "$SIGN_ID" && -n "${APPLE_CERTIFICATE:-}" ]]; then
codesign --force --timestamp --sign "$SIGN_ID" "$DMG"