Skip to content

R-6: Tracking-state and degradation chips on the camera tile #303

R-6: Tracking-state and degradation chips on the camera tile

R-6: Tracking-state and degradation chips on the camera tile #303

Workflow file for this run

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