#!/bin/bash
|
# Round0 smoke QA entrypoint.
|
|
set -euo pipefail
|
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
OUTPUT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
# shellcheck source=build-output-paths.sh
|
source "$SCRIPT_DIR/build-output-paths.sh"
|
SOURCE_ROOT="$OUTPUT_ROOT/C1.source"
|
BUILD_ROOT="$OUTPUT_ROOT/C2.builds"
|
ARCHIVE_ROOT="$BUILD_OLD_RELEASE_ROOT"
|
APP="$BUILD_CURRENT_APP"
|
|
fail() {
|
echo "QA failed: $*" >&2
|
exit 1
|
}
|
|
aligner_pids_for_current_app() {
|
ps -axo pid=,args= | while read -r pid command; do
|
case "$command" in
|
"$APP/Contents/MacOS/Aligner"*) echo "$pid" ;;
|
esac
|
done
|
}
|
|
stop_current_aligner() {
|
for pid in $(aligner_pids_for_current_app); do
|
kill "$pid" 2>/dev/null || true
|
done
|
|
for _ in {1..20}; do
|
[ -z "$(aligner_pids_for_current_app)" ] && return
|
sleep 0.1
|
done
|
|
fail "current Aligner app did not exit"
|
}
|
|
cd "$SOURCE_ROOT"
|
swift build
|
swift test
|
|
"$SCRIPT_DIR/check-signing.sh"
|
|
stop_current_aligner
|
"$SCRIPT_DIR/package-app.sh"
|
|
[ -d "$APP" ] || fail "missing $APP"
|
codesign --verify --deep --strict "$APP"
|
|
APP_REQUIREMENT="$(codesign -d -r- "$APP" 2>&1)"
|
echo "$APP_REQUIREMENT"
|
if echo "$APP_REQUIREMENT" | grep -Fq 'cdhash H"'; then
|
fail "app is signed with a cdhash-only ad-hoc requirement"
|
fi
|
|
ROOT_DMG_COUNT="$(find "$BUILD_ROOT" -maxdepth 1 -type f \( -name 'Aligner_*.dmg' -o -name 'Aligner-*.dmg' \) | wc -l | tr -d ' ')"
|
[ "$ROOT_DMG_COUNT" = "0" ] || fail "expected no root DMG, found $ROOT_DMG_COUNT"
|
|
LATEST_RELEASE_DIR="$(find "$BUILD_ROOT" -maxdepth 1 -type d -name 'Aligner-*-build*' | sort | tail -n 1)"
|
[ -n "$LATEST_RELEASE_DIR" ] || fail "missing latest release directory"
|
|
LATEST_DMG="$(find "$LATEST_RELEASE_DIR" -maxdepth 1 -type f -name 'Aligner-*-build*.dmg' | sort | tail -n 1)"
|
[ -n "$LATEST_DMG" ] || fail "missing latest DMG"
|
hdiutil verify "$LATEST_DMG"
|
|
if [ ! -f "$LATEST_RELEASE_DIR/SHA256SUMS.txt" ]; then
|
fail "missing SHA256SUMS.txt in $LATEST_RELEASE_DIR"
|
fi
|
|
if find "$BUILD_ROOT" "$BUILD_TMP_ROOT" -maxdepth 1 -type f -name '.*tmp*.dmg' | grep -q .; then
|
fail "temporary DMG left in $BUILD_ROOT"
|
fi
|
|
if find "$ARCHIVE_ROOT" -maxdepth 2 -name '*.app' | grep -q .; then
|
fail "old build archives must not contain .app bundles"
|
fi
|
|
if [ -n "$(aligner_pids_for_current_app)" ]; then
|
fail "package-app.sh must not open Aligner by default"
|
fi
|
|
swift "$SCRIPT_DIR/window-logic-qa.swift"
|
|
frontmost_app() {
|
swift -e 'import AppKit; print(NSWorkspace.shared.frontmostApplication?.localizedName ?? "")' 2>/dev/null || true
|
}
|
|
FRONTMOST_BEFORE="$(frontmost_app)"
|
"$APP/Contents/MacOS/Aligner" \
|
--round0-skip-permissions \
|
--round0-debug-overlay \
|
--round0-debug-settings-child \
|
--round0-debug-auto-hide-after=1.0 \
|
--round0-debug-quit-after=3.0 &
|
DEBUG_PID="$!"
|
|
cleanup_debug_app() {
|
kill "$DEBUG_PID" 2>/dev/null || true
|
}
|
trap cleanup_debug_app EXIT
|
|
sleep 0.8
|
swift "$SCRIPT_DIR/window-logic-qa.swift" --expect-debug-overlay --expect-debug-settings-child
|
|
FRONTMOST_AFTER="$(frontmost_app)"
|
if [ -n "$FRONTMOST_BEFORE" ] && [ -n "$FRONTMOST_AFTER" ] && [ "$FRONTMOST_BEFORE" != "$FRONTMOST_AFTER" ]; then
|
fail "debug overlay changed frontmost app from '$FRONTMOST_BEFORE' to '$FRONTMOST_AFTER'"
|
fi
|
|
sleep 1.0
|
swift "$SCRIPT_DIR/window-logic-qa.swift" --expect-no-debug-overlay --expect-no-debug-settings-child
|
|
for _ in {1..30}; do
|
if ! kill -0 "$DEBUG_PID" 2>/dev/null; then
|
break
|
fi
|
sleep 0.1
|
done
|
|
if kill -0 "$DEBUG_PID" 2>/dev/null; then
|
kill "$DEBUG_PID" 2>/dev/null || true
|
fail "debug overlay app did not quit"
|
fi
|
|
wait "$DEBUG_PID" 2>/dev/null || true
|
trap - EXIT
|
|
echo "Round0 QA passed"
|