Files
SeedPass/scripts/run_ci_tests.sh
T
thePR0M3TH3ANandClaude Opus 5 0509c48def Measure the critical-coverage floor on Linux, not once per platform
With every Windows test finally passing — 1239 passed, 0 failed — the last
red was the critical-coverage gate: manager.py at 59.80% against a 60.00%
floor, on Windows only. It measures 60.74% on Linux.

The gap is not missing tests. Windows runs MORE of them (1239 against 1223)
and still covers less of that module, because manager.py holds POSIX-only
paths that cannot execute there at all. A floor checked on Windows therefore
measures platform reachability rather than test quality, and fails by two
tenths of a point for a reason no test author can act on.

So the floor is measured on Linux, the same reasoning as the lockfile check
earlier in this session: a property of the codebase is one question about one
artifact and wants asking once, on a canonical platform, not re-derived per
matrix entry where platform differences make the number wobble. Every
platform still RUNS the full suite and the 20% overall floor; only the
per-module floor is Linux-measured.

Recorded separately, because the gate being right does not make the number
good: a 2970-statement module central to the application sits at 60% with no
headroom, and its uncovered part is almost all interactive prompt handling.
Raising it honestly means extracting logic out of the input() loops, not
writing tests that drive prompts.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01Vtx94nXDmNgXEeThUZP4QN
2026-08-20 11:49:17 -04:00

116 lines
4.1 KiB
Bash
Executable File

#!/usr/bin/env bash
set -eo pipefail
mkdir -p artifacts/coverage
if [[ "${TUI2_SMOKE_GATE:-0}" == "1" ]]; then
./scripts/tui2_check_smoke.sh
fi
# Pick an interpreter that can actually import pytest, not merely the first
# one named "python" on PATH. On Windows the MSYS2 toolchain is prepended to
# PATH so native wheels can build, and MSYS2 ships its own python.exe -- so a
# bare `python` resolved to that one and the whole suite died with "No module
# named pytest", after the determinism gate had already passed using the
# `pytest` executable, which MSYS2 does not provide.
candidates=()
[[ -x ".venv/bin/python" ]] && candidates+=(".venv/bin/python")
# setup-python exports pythonLocation but does not necessarily put it first on
# PATH. On Windows the MSYS2 toolchain is prepended so native wheels can
# build, and it ships its own python.exe AND python3 -- so BOTH bare names
# resolve to an interpreter with no pytest, and the toolchain that has to be
# on PATH is the very thing that hides the interpreter we want.
if [[ -n "${pythonLocation:-}" ]]; then
candidates+=("${pythonLocation}/python" "${pythonLocation}/python.exe" "${pythonLocation}/bin/python")
fi
candidates+=(python python3)
# Last resort: pytest itself is resolvable here (the determinism gate runs it
# that way), so its own directory locates a usable interpreter.
if command -v pytest >/dev/null 2>&1; then
pytest_dir="$(dirname "$(command -v pytest)")"
candidates+=("$pytest_dir/python" "$pytest_dir/python.exe" "$pytest_dir/../python" "$pytest_dir/../python.exe")
fi
py_bin=""
for candidate in "${candidates[@]}"; do
if "$candidate" -c "import pytest" >/dev/null 2>&1; then
py_bin="$candidate"
break
fi
done
if [[ -z "$py_bin" ]]; then
echo "no interpreter can import pytest; tried:" >&2
printf ' %s\n' "${candidates[@]}" >&2
exit 1
fi
echo "test interpreter: $py_bin"
if [[ "${DETERMINISM_GATE:-1}" == "1" ]]; then
./scripts/run_determinism_tests.sh
fi
pytest_args=(-vv)
if [[ -n "${STRESS_ARGS:-}" ]]; then
pytest_args+=(${STRESS_ARGS})
fi
if [[ "${RUNNER_OS:-}" == "Windows" ]]; then
pytest_args+=(-n 1)
fi
pytest_args+=(
--cov=src
--cov-report=xml
--cov-report=term-missing
--cov-report=json:artifacts/coverage/coverage.json
--cov-fail-under=20
src/tests
)
timeout_bin="timeout"
if ! command -v "$timeout_bin" >/dev/null 2>&1; then
if command -v gtimeout >/dev/null 2>&1; then
timeout_bin="gtimeout"
else
timeout_bin=""
fi
fi
if [[ -n "$timeout_bin" ]]; then
$timeout_bin 15m "$py_bin" -m pytest "${pytest_args[@]}" 2>&1 | tee pytest.log
status=${PIPESTATUS[0]}
else
echo "timeout command not found; running tests without timeout" >&2
"$py_bin" -m pytest "${pytest_args[@]}" 2>&1 | tee pytest.log
status=${PIPESTATUS[0]}
fi
if [[ $status -eq 124 ]]; then
echo "::error::Tests exceeded 15-minute limit"
tail -n 20 pytest.log
exit 1
fi
# The critical-coverage floor is a property of the codebase, not of a
# platform, so it is measured on one. src/seedpass/core/manager.py holds
# POSIX-only paths that cannot execute on Windows at all: it measures 60.74%
# on Linux and 59.80% on Windows against a 60.00% floor -- and Windows runs
# MORE tests, not fewer (1239 against 1223), so the gap is code that is
# unreachable there rather than tests that did not run. A floor checked on
# Windows measures platform reachability instead of test quality, and fails
# by two tenths of a point for reasons no test author can act on.
if [[ $status -eq 0 && "${CRITICAL_COVERAGE_GATE:-1}" == "1" ]]; then
if [[ "${RUNNER_OS:-Linux}" == "Linux" ]]; then
"$py_bin" scripts/check_critical_coverage.py \
artifacts/coverage/coverage.json \
--json-output artifacts/coverage/critical_gate.full.json
else
echo "critical coverage gate: not run on ${RUNNER_OS:-this platform}" \
"(the floor is measured on Linux -- see the comment above)"
fi
fi
if [[ $status -eq 0 && "${TUI2_COVERAGE_GATE:-0}" == "1" ]]; then
./scripts/tui2_coverage_gate.sh
fi
if [[ $status -eq 0 && "${TUI3_COVERAGE_GATE:-1}" == "1" ]]; then
./scripts/tui3_coverage_gate.sh
fi
exit $status