#!/usr/bin/env bash # post-build-mac.sh # Re-sign and package a release .app into a .dmg for RustDesk (macOS). # # Must be run AFTER `flutter build macos --release` finishes. # The .app will NOT launch on macOS 26.5 without re-signing — see BUILD.md. # # Usage: # ./res/post-build-mac.sh # signs build output, installs to /Applications, creates dmg # ./res/post-build-mac.sh --no-dmg # just re-sign and install, skip dmg # ./res/post-build-mac.sh --no-install # just re-sign and create dmg in build dir # VERSION=1.4.7 ./res/post-build-mac.sh # custom version label in dmg filename set -euo pipefail # ---------- Config ---------- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" VERSION="${VERSION:-1.4.7}" ARCH="${ARCH:-arm64}" APP_REL="flutter/build/macos/Build/Products/Release/RustDesk.app" APP_PATH="$PROJECT_ROOT/$APP_REL" DMG_NAME="rustdesk-${VERSION}-${ARCH}.dmg" STAGING="/tmp/dmg_staging_postbuild" INSTALL_TARGET="${INSTALL_TARGET:-/Applications/RustDesk.app}" SKIP_DMG=0 SKIP_INSTALL=0 for arg in "$@"; do case "$arg" in --no-dmg) SKIP_DMG=1 ;; --no-install) SKIP_INSTALL=1 ;; -h|--help) grep -E '^#( |!)' "$0" | sed 's/^# \{0,1\}//' exit 0 ;; esac done # ---------- Sanity checks ---------- if [ ! -d "$APP_PATH" ]; then echo "ERROR: $APP_PATH does not exist." >&2 echo "Run 'flutter build macos --release' first." >&2 exit 1 fi # ---------- Step 1: Re-sign the .app ---------- echo "==> Re-signing $APP_PATH" codesign --force --deep -s - "$APP_PATH" codesign --verify --strict --verbose=2 "$APP_PATH" 2>&1 | head -3 || true echo " Signature: $(codesign -dvv "$APP_PATH" 2>&1 | grep -E '^Signature=' | head -1)" # ---------- Step 2: Install to /Applications ---------- if [ "$SKIP_INSTALL" -eq 0 ]; then echo "==> Installing to $INSTALL_TARGET" pkill -9 -f "RustDesk.app/Contents/MacOS/RustDesk" 2>/dev/null || true sleep 1 rm -rf "$INSTALL_TARGET" 2>/dev/null || true cp -R "$APP_PATH" "$INSTALL_TARGET" # Re-sign the installed copy (path is now different, so signatures may differ) codesign --force --deep -s - "$INSTALL_TARGET" echo " Installed: $INSTALL_TARGET" fi # ---------- Step 3: Build the .dmg ---------- if [ "$SKIP_DMG" -eq 0 ]; then echo "==> Building $DMG_NAME" rm -rf "$STAGING" mkdir -p "$STAGING" cp -R "$APP_PATH" "$STAGING/RustDesk.app" ln -sf /Applications "$STAGING/Applications" # CRITICAL: re-sign the staging copy too — hdiutil snapshots whatever's there codesign --force --deep -s - "$STAGING/RustDesk.app" DMG_OUT="$PROJECT_ROOT/$DMG_NAME" rm -f "$DMG_OUT" hdiutil create -volname "RustDesk Installer" \ -srcfolder "$STAGING" \ -ov -format UDZO \ "$DMG_OUT" echo " DMG: $DMG_OUT ($(du -h "$DMG_OUT" | awk '{print $1}'))" fi # ---------- Step 4: Cleanup ---------- rm -rf "$STAGING" echo "" echo "Done. To launch:" echo " open $INSTALL_TARGET" if [ "$SKIP_DMG" -eq 0 ]; then echo "To distribute:" echo " open $PROJECT_ROOT/$DMG_NAME" fi