- 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
97 lines
2.6 KiB
Bash
Executable File
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"
|