From be84950344f179dff87516f18387d07a49b662d4 Mon Sep 17 00:00:00 2001 From: arzafran Date: Fri, 10 Jul 2026 15:55:14 -0300 Subject: [PATCH 1/3] fix: propagate unit-test runner failures again run_suite read $? after a branchless 'if', which is always 0, so any XCTest failure exited 0 and CI reported red suites as green. Capture the status directly with '|| exit_code=$?'. Also fix the guard test's xcodebuild stub: its split-stateful case fabricated two log lines per invocation, so the runner's two real passes logged four calls and the guard failed even on correct behavior. Log the actual arguments once per invocation instead. --- scripts/ci-run-unit-tests.sh | 15 ++++++++------- tests/test_ci_unit_test_runner_behavior.sh | 5 +++-- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/scripts/ci-run-unit-tests.sh b/scripts/ci-run-unit-tests.sh index 83056107c5c..cee891db623 100755 --- a/scripts/ci-run-unit-tests.sh +++ b/scripts/ci-run-unit-tests.sh @@ -76,15 +76,16 @@ run_unit_tests_with_retry() { run_suite() { local mode="${1:-serial}" local label="${2:-Unit tests}" + local exit_code=0 - if run_unit_tests_with_retry "$mode"; then - return 0 - fi + # Capture the status directly; `$?` after a branchless `if` is always 0, + # which silently turned test failures into successes. + run_unit_tests_with_retry "$mode" || exit_code=$? - local exit_code=$? - # run_unit_tests_with_retry failures can carry non-zero statuses; keep that signal. - echo "${label} failed with exit code $exit_code" - exit "$exit_code" + if [[ "$exit_code" -ne 0 ]]; then + echo "${label} failed with exit code $exit_code" + exit "$exit_code" + fi } if [[ "$TEST_SCOPE" == "split-stateful" ]]; then diff --git a/tests/test_ci_unit_test_runner_behavior.sh b/tests/test_ci_unit_test_runner_behavior.sh index 2cd959a0c61..62eb8babdaf 100755 --- a/tests/test_ci_unit_test_runner_behavior.sh +++ b/tests/test_ci_unit_test_runner_behavior.sh @@ -33,8 +33,9 @@ log_call() { case "${TEST_SCENARIO:?}" in split-stateful) - log_call "$0 -skip-testing:${STATEFUL_TEST_CLASS} -parallel-testing-enabled YES" - log_call "$0 -only-testing:${STATEFUL_TEST_CLASS} -skip-testing:${STATEFUL_TEST_SKIP} -parallel-testing-enabled NO" + # Log the arguments the runner actually passed; the runner is expected to + # invoke xcodebuild once per pass (parallel, then stateful). + log_call "$0 $*" echo "Test Suite 'All tests' passed" exit 0 ;; From 3e6b185577be47b34721c65e98cdd78da6283b3d Mon Sep 17 00:00:00 2001 From: arzafran Date: Fri, 10 Jul 2026 15:55:14 -0300 Subject: [PATCH 2/3] fix: unshallow change-detection fetch so merge-base resolves The --depth=1 fetch of the base and head SHAs grafts away their parent history, so 'git diff BASE...HEAD' dies with 'no merge base' on every pull request and all gated jobs skip. The checkout already uses fetch-depth: 0, so a plain fetch is correct and effectively free. --- .github/workflows/ci-macos-compat.yml | 2 +- .github/workflows/ci.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci-macos-compat.yml b/.github/workflows/ci-macos-compat.yml index 96c3ba2ff86..ee8bc854ff4 100644 --- a/.github/workflows/ci-macos-compat.yml +++ b/.github/workflows/ci-macos-compat.yml @@ -43,7 +43,7 @@ jobs: BASE_SHA="${{ github.event.pull_request.base.sha }}" HEAD_SHA="${{ github.event.pull_request.head.sha }}" - git fetch --no-tags --depth=1 origin "${BASE_SHA}" "${HEAD_SHA}" + git fetch --no-tags origin "${BASE_SHA}" "${HEAD_SHA}" CHANGED_FILES="$(git diff --name-only "${BASE_SHA}...${HEAD_SHA}")" RUN_COMPAT_TESTS=false if [[ -z "${CHANGED_FILES}" ]]; then diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2dc43cbcd88..acf5b51c77d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -66,7 +66,7 @@ jobs: BASE_SHA="${{ github.event.pull_request.base.sha }}" HEAD_SHA="${{ github.event.pull_request.head.sha }}" - git fetch --no-tags --depth=1 origin "${BASE_SHA}" "${HEAD_SHA}" + git fetch --no-tags origin "${BASE_SHA}" "${HEAD_SHA}" CHANGED_FILES="$(git diff --name-only "${BASE_SHA}...${HEAD_SHA}")" RUN_APP_JOBS=false RUN_REMOTE_DAEMON_JOBS=false From 5fae804edac31ef5c253138a9e46ed8e5ec7dd07 Mon Sep 17 00:00:00 2001 From: arzafran Date: Fri, 10 Jul 2026 16:05:15 -0300 Subject: [PATCH 3/3] ci: run unit tests serially until parallel mode is proven The split-stateful parallel mode landed in the same commit as the exit-code bug that reported failing suites as green, so it has never had an honestly-reported passing run. With failures propagating again, the parallel pass fails dozens of AppKit-adjacent tests across multiple test runner processes on both macos-15 and macos-26. Return to the serial scope that was green before the split; re-enable parallelism separately once the suite is parallel-safe. --- .github/workflows/ci-macos-compat.yml | 2 +- .github/workflows/ci.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci-macos-compat.yml b/.github/workflows/ci-macos-compat.yml index ee8bc854ff4..43285cffd18 100644 --- a/.github/workflows/ci-macos-compat.yml +++ b/.github/workflows/ci-macos-compat.yml @@ -203,7 +203,7 @@ jobs: - name: Run unit tests env: PROGRAMA_SKIP_ZIG_BUILD: ${{ matrix.skip_zig && '1' || '0' }} - PROGRAMA_UNIT_TEST_SCOPE: split-stateful + PROGRAMA_UNIT_TEST_SCOPE: serial run: | ./scripts/ci-run-unit-tests.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index acf5b51c77d..f3636e6ecd5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -300,7 +300,7 @@ jobs: - name: Run unit tests env: - PROGRAMA_UNIT_TEST_SCOPE: split-stateful + PROGRAMA_UNIT_TEST_SCOPE: serial run: ./scripts/ci-run-unit-tests.sh - name: Run bundled Ghostty theme picker helper regression