From c86aa190355513b571a4c60faacee48eac03b389 Mon Sep 17 00:00:00 2001 From: Oscar Costoya Vidal Date: Fri, 20 Feb 2026 16:22:08 +0100 Subject: [PATCH 1/6] ci: avoid test runner hangs by removing swift test --parallel --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 495eab6..f584c10 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -37,7 +37,7 @@ jobs: run: swift build --build-tests - name: Run tests - run: swift test --parallel + run: swift test - name: CLI smoke test run: swift run snapshot-report --help From 6667416824d35ef765435e430309a4a0b1f89df1 Mon Sep 17 00:00:00 2001 From: Oscar Costoya Vidal Date: Fri, 20 Feb 2026 17:47:13 +0100 Subject: [PATCH 2/6] release: package and install SnapshotReportCore resource bundle --- .github/workflows/nightly.yml | 3 +++ .github/workflows/release.yml | 3 +++ scripts/generate-homebrew-formula.sh | 1 + 3 files changed, 7 insertions(+) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 0cb4ab8..628d69b 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -46,7 +46,9 @@ jobs: mkdir -p "dist/${ROOT}" BIN=".build/${ARCH}-apple-macosx/release/snapshot-report" + BUNDLE=".build/${ARCH}-apple-macosx/release/SnapshotReportKit_SnapshotReportCore.bundle" cp "${BIN}" "dist/${ROOT}/snapshot-report" + cp -R "${BUNDLE}" "dist/${ROOT}/SnapshotReportKit_SnapshotReportCore.bundle" chmod +x "dist/${ROOT}/snapshot-report" tar -C dist -czf "dist/${ROOT}.tar.gz" "${ROOT}" @@ -160,6 +162,7 @@ jobs: def install bin.install "snapshot-report" => "snapshot-report-nightly" + bin.install "SnapshotReportKit_SnapshotReportCore.bundle" end test do diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index dc7e9bd..fe5db3e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -41,7 +41,9 @@ jobs: mkdir -p "dist/${ROOT}" BIN=".build/${ARCH}-apple-macosx/release/snapshot-report" + BUNDLE=".build/${ARCH}-apple-macosx/release/SnapshotReportKit_SnapshotReportCore.bundle" cp "${BIN}" "dist/${ROOT}/snapshot-report" + cp -R "${BUNDLE}" "dist/${ROOT}/SnapshotReportKit_SnapshotReportCore.bundle" chmod +x "dist/${ROOT}/snapshot-report" tar -C dist -czf "dist/${ROOT}.tar.gz" "${ROOT}" @@ -143,6 +145,7 @@ jobs: def install bin.install "snapshot-report" + bin.install "SnapshotReportKit_SnapshotReportCore.bundle" end test do diff --git a/scripts/generate-homebrew-formula.sh b/scripts/generate-homebrew-formula.sh index 982b1a9..35300d1 100755 --- a/scripts/generate-homebrew-formula.sh +++ b/scripts/generate-homebrew-formula.sh @@ -34,6 +34,7 @@ class SnapshotReport < Formula def install bin.install "snapshot-report" + bin.install "SnapshotReportKit_SnapshotReportCore.bundle" end test do From 069a73fb621d6d64aab37f0e91dc258cf053e281 Mon Sep 17 00:00:00 2001 From: Oscar Costoya Vidal Date: Fri, 20 Feb 2026 17:49:00 +0100 Subject: [PATCH 3/6] ci: prevent PR test runs from being auto-canceled --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f584c10..cf48bed 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,8 +8,8 @@ on: workflow_dispatch: concurrency: - group: ci-${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true + group: ci-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: ${{ github.event_name == 'push' }} jobs: build-and-test: From 4763d6e51766032a2f8571a2ebd9537dd49be8d1 Mon Sep 17 00:00:00 2001 From: Oscar Costoya Vidal Date: Fri, 20 Feb 2026 17:50:37 +0100 Subject: [PATCH 4/6] ci: add swift test watchdog and heartbeat logging --- .github/workflows/ci.yml | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cf48bed..42939a6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -37,7 +37,39 @@ jobs: run: swift build --build-tests - name: Run tests - run: swift test + run: | + set -euo pipefail + LOG_FILE="$(mktemp -t swift-test-log.XXXXXX)" + echo "Running swift test (logs: ${LOG_FILE})" + + swift test --verbose >"${LOG_FILE}" 2>&1 & + TEST_PID=$! + START_TS=$(date +%s) + TIMEOUT_SECONDS=$((20 * 60)) + + while kill -0 "${TEST_PID}" 2>/dev/null; do + NOW_TS=$(date +%s) + ELAPSED=$((NOW_TS - START_TS)) + echo "[ci] swift test still running (${ELAPSED}s elapsed)" + + if [ "${ELAPSED}" -ge "${TIMEOUT_SECONDS}" ]; then + echo "[ci] ERROR: swift test exceeded timeout (${TIMEOUT_SECONDS}s)" + kill -TERM "${TEST_PID}" 2>/dev/null || true + sleep 5 + kill -KILL "${TEST_PID}" 2>/dev/null || true + echo "===== swift test log (tail) =====" + tail -n 200 "${LOG_FILE}" || true + exit 124 + fi + + sleep 30 + done + + wait "${TEST_PID}" + STATUS=$? + echo "===== swift test log (tail) =====" + tail -n 200 "${LOG_FILE}" || true + exit "${STATUS}" - name: CLI smoke test run: swift run snapshot-report --help From 49a549b677177af41980b783d02df854cf2accfa Mon Sep 17 00:00:00 2001 From: Oscar Costoya Vidal Date: Fri, 20 Feb 2026 17:55:10 +0100 Subject: [PATCH 5/6] ci: improve swift test watchdog diagnostics and failure handling --- .github/workflows/ci.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 42939a6..81b7fc9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -39,7 +39,7 @@ jobs: - name: Run tests run: | set -euo pipefail - LOG_FILE="$(mktemp -t swift-test-log.XXXXXX)" + LOG_FILE="$(mktemp -t swift-test-log.XXXXXX.log)" echo "Running swift test (logs: ${LOG_FILE})" swift test --verbose >"${LOG_FILE}" 2>&1 & @@ -51,6 +51,9 @@ jobs: NOW_TS=$(date +%s) ELAPSED=$((NOW_TS - START_TS)) echo "[ci] swift test still running (${ELAPSED}s elapsed)" + ps -p "${TEST_PID}" -o pid=,ppid=,%cpu=,%mem=,etime=,command= || true + echo "===== swift test log (tail -n 40) =====" + tail -n 40 "${LOG_FILE}" || true if [ "${ELAPSED}" -ge "${TIMEOUT_SECONDS}" ]; then echo "[ci] ERROR: swift test exceeded timeout (${TIMEOUT_SECONDS}s)" @@ -65,8 +68,10 @@ jobs: sleep 30 done + set +e wait "${TEST_PID}" STATUS=$? + set -e echo "===== swift test log (tail) =====" tail -n 200 "${LOG_FILE}" || true exit "${STATUS}" From 81ac2e40cc4a29d89f4f78261a6ce97bdd18d65b Mon Sep 17 00:00:00 2001 From: Oscar Costoya Vidal Date: Fri, 20 Feb 2026 17:59:15 +0100 Subject: [PATCH 6/6] ci: run xctest bundle directly to avoid swift test wrapper hang --- .github/workflows/ci.yml | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 81b7fc9..e39f5df 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -39,28 +39,36 @@ jobs: - name: Run tests run: | set -euo pipefail - LOG_FILE="$(mktemp -t swift-test-log.XXXXXX.log)" - echo "Running swift test (logs: ${LOG_FILE})" + LOG_FILE="$(mktemp -t xctest-log.XXXXXX.log)" + TEST_BUNDLE="$(find .build -type d -name 'SnapshotReportKitPackageTests.xctest' | head -n 1)" + if [ -z "${TEST_BUNDLE}" ]; then + echo "[ci] ERROR: test bundle not found under .build" + find .build -maxdepth 4 -type d -name '*.xctest' -print || true + exit 1 + fi - swift test --verbose >"${LOG_FILE}" 2>&1 & + echo "Running xctest bundle: ${TEST_BUNDLE}" + echo "Logs: ${LOG_FILE}" + + xcrun xctest "${TEST_BUNDLE}" >"${LOG_FILE}" 2>&1 & TEST_PID=$! START_TS=$(date +%s) - TIMEOUT_SECONDS=$((20 * 60)) + TIMEOUT_SECONDS=$((10 * 60)) while kill -0 "${TEST_PID}" 2>/dev/null; do NOW_TS=$(date +%s) ELAPSED=$((NOW_TS - START_TS)) - echo "[ci] swift test still running (${ELAPSED}s elapsed)" + echo "[ci] xctest still running (${ELAPSED}s elapsed)" ps -p "${TEST_PID}" -o pid=,ppid=,%cpu=,%mem=,etime=,command= || true - echo "===== swift test log (tail -n 40) =====" + echo "===== xctest log (tail -n 40) =====" tail -n 40 "${LOG_FILE}" || true if [ "${ELAPSED}" -ge "${TIMEOUT_SECONDS}" ]; then - echo "[ci] ERROR: swift test exceeded timeout (${TIMEOUT_SECONDS}s)" + echo "[ci] ERROR: xctest exceeded timeout (${TIMEOUT_SECONDS}s)" kill -TERM "${TEST_PID}" 2>/dev/null || true sleep 5 kill -KILL "${TEST_PID}" 2>/dev/null || true - echo "===== swift test log (tail) =====" + echo "===== xctest log (tail) =====" tail -n 200 "${LOG_FILE}" || true exit 124 fi @@ -72,7 +80,7 @@ jobs: wait "${TEST_PID}" STATUS=$? set -e - echo "===== swift test log (tail) =====" + echo "===== xctest log (tail) =====" tail -n 200 "${LOG_FILE}" || true exit "${STATUS}"