Files
nucleic/scripts/build-vm-agent.sh
T

58 lines
2.8 KiB
Bash
Executable File

#!/usr/bin/env bash
#
# Build guest/NucleicVMAgent into a signed NucleicVMAgent.app bundle, ready to be baked into the
# macOS-VM golden base image (docs/MACOS_VM_NATIVE_AGENT.md §11).
#
# ./scripts/build-vm-agent.sh [output-dir] # default output: guest/NucleicVMAgent/dist
#
# Signing: TCC keys its grants to the app's DESIGNATED REQUIREMENT, and an ad-hoc signature changes
# identity every build — so a pre-inserted TCC row would stop matching after a rebuild. Sign with a
# stable identity via $NUCLEIC_VMAGENT_SIGN_IDENTITY (a Developer ID, or a self-signed code-signing
# cert in the login keychain). Falls back to ad-hoc WITH A WARNING so a first local round-trip still
# works (you must re-provision TCC after every ad-hoc rebuild).
#
# Runs on the HOST (needs the Swift toolchain); the produced .app runs inside the GUEST. Stage the
# app next to scripts/provision-macos-guest.sh (or in the shared workspace) when provisioning.
set -euo pipefail
REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
PKG_DIR="$REPO_ROOT/guest/NucleicVMAgent"
OUT_DIR="${1:-$PKG_DIR/dist}"
APP="$OUT_DIR/NucleicVMAgent.app"
IDENTITY="${NUCLEIC_VMAGENT_SIGN_IDENTITY:-}"
# Per-mount scratch dir (keyed on the guest package's own path) so a build off the VM's
# virtiofs share doesn't poison the host's guest/NucleicVMAgent/.build. See scripts/lib/build-scratch.sh.
SCRATCH_ARGS="$(bash "$REPO_ROOT/scripts/lib/build-scratch.sh" "$PKG_DIR")"
echo "▸ Building NucleicVMAgent (release) …"
swift build $SCRATCH_ARGS --package-path "$PKG_DIR" -c release
BIN="$(swift build $SCRATCH_ARGS --package-path "$PKG_DIR" -c release --show-bin-path)/NucleicVMAgent"
[ -x "$BIN" ] || { echo "✗ build produced no binary at $BIN" >&2; exit 1; }
echo "▸ Assembling $APP …"
rm -rf "$APP"
mkdir -p "$APP/Contents/MacOS"
cp "$PKG_DIR/Packaging/Info.plist" "$APP/Contents/Info.plist"
cp "$BIN" "$APP/Contents/MacOS/NucleicVMAgent"
# The LaunchAgent plist rides along so the provisioner can install it from one staged directory.
cp "$PKG_DIR/Packaging/xyz.blakeslee.nucleic.vmagent.plist" "$OUT_DIR/"
echo "▸ Signing …"
if [ -n "$IDENTITY" ]; then
codesign --force --options runtime --sign "$IDENTITY" "$APP"
echo " ✓ signed with '$IDENTITY' (hardened runtime)."
else
codesign --force --sign - "$APP"
echo " ⚠ AD-HOC signed (set NUCLEIC_VMAGENT_SIGN_IDENTITY for a stable identity)." >&2
echo " An ad-hoc identity changes EVERY build, so the guest's pre-granted TCC rows stop" >&2
echo " matching after a rebuild — re-run provisioning Phase 7d after installing this build." >&2
fi
# Never let a quarantine xattr ride into the guest (the app is never downloaded, but be safe).
xattr -dr com.apple.quarantine "$APP" 2>/dev/null || true
codesign --verify --deep "$APP"
echo "✓ $APP"
echo " Stage it for provisioning: copy $OUT_DIR/* next to scripts/provision-macos-guest.sh in the guest."