ci-mirror: split into ci-venv / ci-precommit / ci-pytest, pytest under xdist

The single ci-mirror manual hook took ~100 s (pre-commit --all-files plus a
serial clean-venv pytest, ~85 s), past the 60 s per-action cap. ci_mirror.sh
now takes a subcommand (venv|precommit|pytest|all; default all = the old
one-shot behaviour) and each step is its own manual hook, ordered so the
venv rebuild runs first in its own call. The clean-venv pytest runs
-n auto --dist worksteal; branch coverage stays at 100% (pytest-cov merges
the workers).

Measured (timeout 58): ci-venv 27.0 s cold / 0.1 s warm, ci-precommit
32.6 s, ci-pytest 12.6 s, flutter-test-coverage 46.5 s, web-coverage 1.7 s.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PAhbNszs5JKdtnD4uBi3xp
This commit is contained in:
Krzysztof Rudnicki 2026-10-17 16:46:14 +02:00
parent ac65def3ef
commit 67f942284e
2 changed files with 49 additions and 7 deletions

View File

@ -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

View File

@ -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 "$@"