#!/bin/bash # Build a REAL .dmg for macOS users ON LINUX (no Mac needed). # # One-time toolchain setup (all on the Linux build host): # apt-get install -y hfsprogs libguestfs-tools linux-modules-extra-$(uname -r) # hfsprogs = the HFS+ volume formatter; libguestfs runs it INSIDE its # sandboxed appliance VM, where it only ever formats disk-image FILES — # never real block devices/drives. # modprobe hfsplus && echo hfsplus >> /etc/modules (kernel support) # git clone https://github.com/planetbeing/libdmg-hfsplus.git /opt/libdmg-hfsplus # cd /opt/libdmg-hfsplus # sed -i 's/IF(OPENSSL_FOUND)/IF(FALSE)/' dmg/CMakeLists.txt # OpenSSL 3 breaks FileVault; not needed for plain UDZO # mkdir build && cd build && cmake .. && make # # Usage: scripts/build-dmg-linux.sh (run from dashcaddy-installer/, after npm run build:mac) set -euo pipefail cd "$(dirname "$0")/.." LIBDMG=/opt/libdmg-hfsplus/build STAGE="$(mktemp -d)" trap 'rm -rf "$STAGE"' EXIT APP="build-output/mac/DashCaddy Installer.app" VERSION=$(node -p "require('./package.json').version") OUT="build-output/DashCaddy Installer-$VERSION.dmg" [ -d "$APP" ] || { echo "ERROR: $APP missing — run: npm run build:mac"; exit 1; } [ -x "$LIBDMG/hdutil/hdutil" ] || { echo "ERROR: libdmg-hfsplus not built at $LIBDMG"; exit 1; } modprobe hfsplus 2>/dev/null || { echo "ERROR: hfsplus kernel module missing"; exit 1; } echo ">>> staging app + /Applications drag-install link" cp -a "$APP" "$STAGE/DashCaddy Installer.app" ln -s /Applications "$STAGE/Applications" echo ">>> creating HFS+ volume inside a 400M image file (no drives touched)" # LIBGUESTFS_BACKEND=direct is deliberate: the appliance must run the host # kernel so the hfsplus module is available; direct backend on a dedicated # build host is accepted (appliance only ever touches image files here). export LIBGUESTFS_BACKEND=direct virt-make-fs --type=hfsplus --size=400M "$STAGE" "$STAGE/vol.hfs" echo ">>> verifying volume contents (app + symlink present)" "$LIBDMG/hdutil/hdutil" "$STAGE/vol.hfs" ls / echo ">>> compressing to UDIF .dmg" "$LIBDMG/dmg/dmg" dmg "$STAGE/vol.hfs" "$OUT" echo ">>> secret-scanning the DMG contents" VERIFY="$STAGE/verify" mkdir -p "$VERIFY" "$LIBDMG/hdutil/hdutil" "$STAGE/vol.hfs" extractall / "$VERIFY" bash scripts/check-artifact-secrets.sh "$VERIFY" echo ">>> DONE: $OUT ($(du -h "$OUT" | cut -f1))" file "$OUT"