PromtGarageMac / scripts /build-app.sh
smlflg's picture
Initial public upload from Projekte/PromtGarageMac
4977db2 verified
Raw History Blame Contribute Delete
3.38 kB
#!/usr/bin/env bash
set -euo pipefail
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
DIST="$ROOT/dist"
APP="$DIST/PromptGarage.app"
INFO_PLIST="$ROOT/AppBundle/Info.plist"
fail() {
printf 'build-app: %s\n' "$*" >&2
exit 1
}
require_command() {
command -v "$1" >/dev/null 2>&1 || fail "required command not found: $1"
}
assert_supported_host() {
[[ "$(uname -s)" == "Darwin" ]] || fail "this release build must run on macOS"
[[ "$(uname -m)" == "arm64" ]] || fail "this release build requires an Apple Silicon (arm64) Mac"
local macos_version macos_major xcode_version xcode_major swift_version
macos_version="$(sw_vers -productVersion)"
macos_major="${macos_version%%.*}"
[[ "$macos_major" =~ ^[0-9]+$ ]] || fail "could not parse macOS version: $macos_version"
(( macos_major >= 26 )) || fail "macOS 26 or newer is required; found $macos_version"
xcode_version="$(xcodebuild -version | awk 'NR == 1 { print $2 }')"
xcode_major="${xcode_version%%.*}"
[[ "$xcode_major" =~ ^[0-9]+$ ]] || fail "could not parse Xcode version: $xcode_version"
(( xcode_major >= 26 )) || fail "Xcode 26 or newer is required; found $xcode_version"
swift_version="$(swift --version | sed -n '1s/.*Swift version \([0-9][0-9.]*\).*/\1/p')"
[[ "$swift_version" == 6.2* ]] || fail "Swift 6.2 is required; found ${swift_version:-unknown}"
}
assert_exact_arm64() {
local binary="$1"
local architectures
architectures="$(lipo -archs "$binary" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
[[ "$architectures" == "arm64" ]] || fail "expected exactly arm64, found: ${architectures:-no architecture}"
}
for command_name in uname sw_vers xcodebuild swift awk sed lipo codesign plutil install mktemp; do
require_command "$command_name"
done
assert_supported_host
[[ -f "$INFO_PLIST" ]] || fail "missing bundle metadata: $INFO_PLIST"
plutil -lint "$INFO_PLIST" >/dev/null || fail "invalid Info.plist"
cd "$ROOT"
swift build --configuration release --arch arm64
BIN_DIR="$(swift build --configuration release --arch arm64 --show-bin-path)"
BINARY="$BIN_DIR/PromptGarage"
[[ -x "$BINARY" ]] || fail "release executable not found: $BINARY"
assert_exact_arm64 "$BINARY"
mkdir -p "$DIST"
STAGING_ROOT="$(mktemp -d "$DIST/.PromptGarage-build.XXXXXX")"
STAGING_APP="$STAGING_ROOT/PromptGarage.app"
cleanup() {
local status=$?
trap - EXIT
if [[ -n "${STAGING_ROOT:-}" && -d "$STAGING_ROOT" ]]; then
rm -rf "$STAGING_ROOT"
fi
exit "$status"
}
trap cleanup EXIT
mkdir -p "$STAGING_APP/Contents/MacOS" "$STAGING_APP/Contents/Resources"
install -m 0755 "$BINARY" "$STAGING_APP/Contents/MacOS/PromptGarage"
install -m 0644 "$INFO_PLIST" "$STAGING_APP/Contents/Info.plist"
assert_exact_arm64 "$STAGING_APP/Contents/MacOS/PromptGarage"
codesign --force --sign - --timestamp=none "$STAGING_APP"
codesign --verify --deep --strict --verbose=2 "$STAGING_APP"
# dist/ contains generated release output only. Replace that one known bundle
# after the complete staging bundle has passed architecture and signature checks.
if [[ -e "$APP" ]]; then
rm -rf "$APP"
fi
mv "$STAGING_APP" "$APP"
rmdir "$STAGING_ROOT"
STAGING_ROOT=""
trap - EXIT
assert_exact_arm64 "$APP/Contents/MacOS/PromptGarage"
codesign --verify --deep --strict --verbose=2 "$APP"
printf 'Built and ad-hoc signed: %s\n' "$APP"