#!/usr/bin/env bash # validate-ios-skipped-tests.sh — Fail when iOS test results contain non-allowlisted skipped tests. set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" usage() { cat <<'EOF' Usage: scripts/validate-ios-skipped-tests.sh [allowlist_file] Arguments: xcresult_path Path to .xcresult bundle generated by xcodebuild test allowlist_file Optional allowlist of skipped test names (one per line, # comments allowed) Default: audit/ios-skipped-tests-allowlist.txt EOF } if [[ "${1:-}" == "--help" || "${1:-}" == "-h" ]]; then usage exit 0 fi RESULT_PATH="${1:-}" if [[ -z "$RESULT_PATH" ]]; then usage exit 1 fi ALLOWLIST_PATH="${2:-$PROJECT_ROOT/audit/ios-skipped-tests-allowlist.txt}" require_cmd() { if ! command -v "$1" >/dev/null 2>&1; then echo "Missing required command: $1" >&2 exit 1 fi } require_cmd xcrun require_cmd jq require_cmd sort require_cmd comm require_cmd mktemp if [[ ! -d "$RESULT_PATH" ]]; then echo "xcresult bundle not found: $RESULT_PATH" >&2 exit 1 fi TMP_JSON="$(mktemp)" TMP_SKIPPED="$(mktemp)" TMP_ALLOWLIST="$(mktemp)" TMP_UNALLOWED="$(mktemp)" cleanup() { rm -f "$TMP_JSON" "$TMP_SKIPPED" "$TMP_ALLOWLIST" "$TMP_UNALLOWED" } trap cleanup EXIT if ! xcrun xcresulttool get test-results tests --path "$RESULT_PATH" --format json > "$TMP_JSON" 2>/dev/null; then echo "Failed to parse xcresult test results: $RESULT_PATH" >&2 exit 1 fi jq -r ' .. | objects | select((.result == "Skipped") or (.status == "Skipped") or (.outcome == "Skipped") or (.testStatus == "Skipped")) | (.name // .identifier // empty) ' "$TMP_JSON" | sed '/^[[:space:]]*$/d' | sort -u > "$TMP_SKIPPED" if [[ -f "$ALLOWLIST_PATH" ]]; then { grep -vE '^[[:space:]]*(#|$)' "$ALLOWLIST_PATH" || true } | sed 's/[[:space:]]*$//' | sed '/^[[:space:]]*$/d' | sort -u > "$TMP_ALLOWLIST" else : > "$TMP_ALLOWLIST" fi if [[ ! -s "$TMP_SKIPPED" ]]; then echo "Skipped-test gate: PASS (no skipped iOS tests)" exit 0 fi comm -23 "$TMP_SKIPPED" "$TMP_ALLOWLIST" > "$TMP_UNALLOWED" if [[ -s "$TMP_UNALLOWED" ]]; then echo "Skipped-test gate: FAIL (non-allowlisted skipped iOS tests found)" cat "$TMP_UNALLOWED" | sed 's/^/ - /' if [[ -s "$TMP_ALLOWLIST" ]]; then echo "Allowlist used: $ALLOWLIST_PATH" else echo "Allowlist is empty: $ALLOWLIST_PATH" fi exit 1 fi echo "Skipped-test gate: PASS (all skipped iOS tests are allowlisted)" exit 0