xworkmate-app/scripts/install-flutter-mac-dmg.sh
Haitao Pan dc95abbfb0 fix(build): resolve macOS packaging and installation failures
- Include target/release/libcodex_ffi.dylib in FFI framework search paths
- Embed libcodex_ffi.dylib directly into the macOS app bundle during packaging
- Embed xworkmate-go-core for non-App-Store local builds
- Ad-hoc re-sign the app bundle after modifying its contents
- Fix DMG path resolution in the installation script to handle filenames with spaces
2026-04-19 12:45:47 +08:00

97 lines
2.6 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
DIST_DIR="$ROOT_DIR/dist"
APP_NAME="${APP_NAME:-XWorkmate}"
TARGET_APP="${TARGET_APP:-/Applications/$APP_NAME.app}"
STAGING_APP="${STAGING_APP:-${TARGET_APP}.installing}"
DMG_PATH="${1:-}"
APP_NAME_SLUG="$(printf '%s' "$APP_NAME" | tr '[:upper:]' '[:lower:]' | tr ' ' '-')"
MOUNT_POINT="$(mktemp -d "/tmp/${APP_NAME_SLUG}-install.XXXXXX")"
OPEN_AFTER_INSTALL="${OPEN_AFTER_INSTALL:-0}"
cleanup() {
hdiutil detach "$MOUNT_POINT" -quiet 2>/dev/null || true
rm -rf "$STAGING_APP" 2>/dev/null || true
rmdir "$MOUNT_POINT" 2>/dev/null || true
}
trap cleanup EXIT
validate_app_bundle() {
local app_path="$1"
local info_plist="$app_path/Contents/Info.plist"
local executable="$app_path/Contents/MacOS/$APP_NAME"
local frameworks_dir="$app_path/Contents/Frameworks"
[[ -d "$app_path" ]] || {
echo "Installed app bundle missing: $app_path" >&2
return 1
}
[[ -f "$info_plist" ]] || {
echo "Installed app is missing Info.plist: $info_plist" >&2
return 1
}
[[ -x "$executable" ]] || {
echo "Installed app is missing executable: $executable" >&2
return 1
}
[[ -d "$frameworks_dir" ]] || {
echo "Installed app is missing Frameworks directory: $frameworks_dir" >&2
return 1
}
bash "$ROOT_DIR/scripts/validate-macos-app-bundle.sh" "$app_path"
codesign --verify --deep --verbose=2 "$app_path"
}
if [[ -z "$DMG_PATH" ]]; then
shopt -s nullglob
dmgs=("$DIST_DIR"/"$APP_NAME"-*.dmg)
shopt -u nullglob
if [[ "${#dmgs[@]}" -eq 0 ]]; then
echo "No DMG found under $DIST_DIR for $APP_NAME" >&2
exit 1
fi
# Sort by modification time and pick the newest
DMG_PATH="$(ls -t "${dmgs[@]}" | head -n 1)"
fi
if [[ ! -f "$DMG_PATH" ]]; then
echo "DMG not found: $DMG_PATH" >&2
exit 1
fi
echo "Mounting $DMG_PATH..."
hdiutil attach "$DMG_PATH" -mountpoint "$MOUNT_POINT" -nobrowse -readonly -quiet
SOURCE_APP="$MOUNT_POINT/$APP_NAME.app"
if [[ ! -d "$SOURCE_APP" ]]; then
echo "Expected app bundle missing from DMG: $SOURCE_APP" >&2
exit 1
fi
validate_app_bundle "$SOURCE_APP"
if [[ -d "$TARGET_APP" ]]; then
echo "Replacing existing app at $TARGET_APP"
rm -rf "$TARGET_APP"
fi
rm -rf "$STAGING_APP"
echo "Installing to staging app $STAGING_APP..."
ditto "$SOURCE_APP" "$STAGING_APP"
validate_app_bundle "$STAGING_APP"
echo "Promoting staging app to $TARGET_APP..."
mv "$STAGING_APP" "$TARGET_APP"
validate_app_bundle "$TARGET_APP"
xattr -dr com.apple.quarantine "$TARGET_APP" 2>/dev/null || true
if [[ "$OPEN_AFTER_INSTALL" == "1" ]]; then
open "$TARGET_APP"
fi
echo "Installed: $TARGET_APP"