R-6: Tracking-state and degradation chips on the camera tile #303
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| on: | |
| push: | |
| branches: ["main"] | |
| pull_request: | |
| branches: ["main"] | |
| concurrency: | |
| group: ci-${{ github.ref }} | |
| cancel-in-progress: true | |
| env: | |
| # Qt runs headless on CI runners (no display). | |
| QT_QPA_PLATFORM: offscreen | |
| # Windows runners can default to a legacy console codepage; selftest prints | |
| # Unicode status marks, so force UTF-8 for every Python subprocess. | |
| PYTHONUTF8: "1" | |
| # Unit tests must not perform real Ultralytics/Torch ONNX exports. Those | |
| # native exporters can leave CI runners unstable after pytest has passed. | |
| AUTOPTZ_NO_MODEL_EXPORT: "1" | |
| jobs: | |
| test: | |
| name: ${{ matrix.os }} / Python ${{ matrix.python-version }} | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - os: macos-14 # Apple Silicon (arm64) | |
| python-version: "3.12" | |
| - os: windows-latest # x64 | |
| python-version: "3.12" | |
| - os: ubuntu-latest # x64 (Linux) | |
| python-version: "3.12" | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Python ${{ matrix.python-version }} | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| cache: pip | |
| - name: Install Linux Qt/headless system libs | |
| if: runner.os == 'Linux' | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y --no-install-recommends \ | |
| libegl1 libgl1 libxkbcommon0 libdbus-1-3 \ | |
| libxcb-cursor0 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 \ | |
| libxcb-randr0 libxcb-render-util0 libxcb-shape0 libxcb-xinerama0 \ | |
| x11-utils | |
| - name: Install dependencies | |
| run: python tools/install.py --ci --dev --editable | |
| - name: Lint (ruff) | |
| if: matrix.os == 'ubuntu-latest' | |
| run: ruff check autoptz/ tests/ tools/ | |
| - name: Format check (ruff format) | |
| if: matrix.os == 'ubuntu-latest' | |
| run: ruff format --check autoptz/ tests/ tools/ | |
| - name: Type check (mypy) | |
| if: matrix.os == 'ubuntu-latest' | |
| # Strict gate on the typed core (runtime + config). The UI/pipeline are | |
| # mid typing-migration and excluded in pyproject; expand this as they land. | |
| run: mypy autoptz/engine/runtime/ autoptz/config/ | |
| - name: Run unit tests (sharded per file) | |
| # The native stack (Qt offscreen + torch + cv2 + AVFoundation + cyndilib) | |
| # accumulates state across a single-process run and segfaults late in the | |
| # full suite on EVERY OS (Linux/macOS SIGSEGV, Windows abort). Every test | |
| # file passes in isolation, so run each file in its own process — a heavy | |
| # file's teardown can't then corrupt later files. ``shell: bash`` works on | |
| # the Windows runner via git-bash; ``set +e`` lets the loop run all files | |
| # and still fail the job (with the offending file named) if any file fails. | |
| # A heavy file can still INTERMITTENTLY crash at native teardown (a rare | |
| # SIGSEGV/abort that --reruns can't catch because it kills the process), so | |
| # retry a crashed/failed file up to 3 times in fresh processes; a file that | |
| # fails all 3 is a real failure and fails the job. | |
| shell: bash | |
| run: | | |
| set +e | |
| failed=0 | |
| for f in tests/test_*.py; do | |
| rc=1 | |
| for attempt in 1 2 3; do | |
| echo "::group::$f (attempt $attempt)" | |
| pytest "$f" -q -p no:cacheprovider --timeout=120 | |
| rc=$? | |
| echo "::endgroup::" | |
| [ "$rc" -eq 0 ] && break | |
| echo "::warning file=$f::$f failed on attempt $attempt (exit $rc); retrying in a fresh process" | |
| done | |
| if [ "$rc" -ne 0 ]; then | |
| echo "::error file=$f::pytest failed for $f after 3 attempts (exit $rc)" | |
| failed=1 | |
| fi | |
| done | |
| exit "$failed" | |
| - name: Selftest | |
| # Run with spawn-safe multiprocessing; timeout guard | |
| run: python -m autoptz --selftest --log-level INFO | |
| timeout-minutes: 2 |