diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 0b34e79..2b84158 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -179,9 +179,28 @@ repos: - repo: local hooks: - - id: ci-mirror - name: CI mirror (clean-venv pytest + pre-commit --all-files) - entry: bash scripts/ci_mirror.sh + # The CI mirror, one step per hook so each call stays under the 60 s + # action cap. Order matters: ci-venv (re)builds .ci-mirror-venv from + # requirements.txt when it changed, so ci-pytest only reuses it. + - id: ci-venv + name: CI mirror (clean requirements.txt venv) + entry: bash scripts/ci_mirror.sh venv + language: system + pass_filenames: false + always_run: true + require_serial: true + stages: [manual] + - id: ci-precommit + name: CI mirror (pre-commit --all-files) + entry: bash scripts/ci_mirror.sh precommit + language: system + pass_filenames: false + always_run: true + require_serial: true + stages: [manual] + - id: ci-pytest + name: CI mirror (clean-venv pytest, xdist) + entry: bash scripts/ci_mirror.sh pytest language: system pass_filenames: false always_run: true diff --git a/scripts/ci_mirror.sh b/scripts/ci_mirror.sh index 4c8908a..5c59375 100755 --- a/scripts/ci_mirror.sh +++ b/scripts/ci_mirror.sh @@ -18,6 +18,12 @@ # Runs on demand (`scripts/check_gate_stamp.sh full`, pre-commit's manual # stage) and in CI. It left the pre-push path on 2026-09-20: 10+ minutes # per push under the resource cap, for work finish_auto.sh had just done. +# +# Usage: ci_mirror.sh [venv|precommit|pytest|all] [pytest args...] +# Each step is its own manual hook (ci-venv, ci-precommit, ci-pytest) so no +# single call outlives the 60 s action cap; `all` (the default) is the old +# one-shot behaviour. pytest runs under xdist (-n auto --dist worksteal): +# serial it was ~85 s, and pytest-cov merges the workers' coverage. # ============================================================================ set -euo pipefail @@ -80,15 +86,32 @@ run_precommit_all_files() { run_pytest_clean_venv() { log "pytest in the clean venv (mirrors the Tests workflow)" - "$VENV_DIR/bin/python" -m pytest "$@" || fail "pytest (clean requirements.txt venv)" + "$VENV_DIR/bin/python" -m pytest -n auto --dist worksteal "$@" \ + || fail "pytest (clean requirements.txt venv)" } main() { + local mode="all" + case "${1:-}" in + venv | precommit | pytest | all) mode="$1"; shift ;; + *) ;; + esac + + case "$mode" in + precommit) run_precommit_all_files; return ;; + *) ;; + esac require_file ensure_venv - run_precommit_all_files - run_pytest_clean_venv "$@" - log "all CI gates passed locally — safe to push" + case "$mode" in + venv) ;; + pytest) run_pytest_clean_venv "$@" ;; + *) + run_precommit_all_files + run_pytest_clean_venv "$@" + log "all CI gates passed locally — safe to push" + ;; + esac } main "$@"