# Run the project's test suite on every PR push and on push to main. # # The suite uses stdlib `unittest` discovery — no external Python # dependencies are required to execute it. Tests are split by directory: # # tests/unit/ — pure unit tests; always run # tests/integration/ — need a reachable Docker daemon; skip cleanly # (via tests/_docker.py:skip_unless_docker) when # Docker isn't available on the runner # tests/canaries/ — upstream regression canaries; run on a separate # schedule (see canaries.yml), not here # # This workflow assumes the Gitea Actions runner exposes the host Docker # socket to the job container so `docker` commands inside the job can # reach the daemon. If that's not yet configured on the runner the # integration tests will skip rather than fail. name: test on: push: branches: - main paths: - '**.py' pull_request: paths: - '**.py' jobs: unit: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 with: python-version: "3.12" - name: Install dev requirements run: python3 -m pip install -r requirements-dev.txt - name: Run unit tests run: python3 -m coverage run -m unittest discover -t . -s tests/unit -v - name: Report unit coverage run: python3 -m coverage report -m integration: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 with: python-version: "3.12" - name: Show environment run: | python3 --version if command -v docker >/dev/null 2>&1; then docker version || true else echo "docker not on PATH — integration tests will skip" fi - name: Run integration tests run: python3 -m unittest discover -t . -s tests/integration -v # Combined unit+integration coverage + the diff-coverage gate. # See docs/decisions/0004-coverage-policy.md. The hard gate is diff # coverage (new/changed lines >= 90%); the combined + critical reports # are informational and degrade gracefully when the runner has no # Docker (integration tests skip, those modules just read lower). coverage: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 with: fetch-depth: 0 - name: Set up Python uses: actions/setup-python@v5 with: python-version: "3.12" - name: Install dev requirements run: python3 -m pip install -r requirements-dev.txt - name: Combined coverage (unit + integration) run: PYTHON=python3 bash scripts/coverage.sh critical - name: Diff-coverage gate (changed lines >= 90%) run: | git fetch --no-tags origin main:refs/remotes/origin/main python3 scripts/diff_coverage.py --base origin/main --min 90