Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 34 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,21 @@ on:
- master
- "feat/**"
pull_request:
workflow_dispatch:
inputs:
run_reports:
description: "Run report-generation job"
required: false
default: "false"
type: choice
options: ["false", "true"]

concurrency:
group: ci-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
lint-test-report:
lint-type-test:
runs-on: ubuntu-latest

steps:
Expand Down Expand Up @@ -38,6 +50,27 @@ jobs:
run: |
PYTHONPATH=src pytest

generate-reports:
runs-on: ubuntu-latest
needs: [lint-type-test]
if: >
(github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master')) ||
(github.event_name == 'workflow_dispatch' && github.event.inputs.run_reports == 'true')

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.11"

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e ".[dev]"

- name: Generate reports
run: |
PYTHONPATH=src python src/ai_quality_agent.py --profile dev --performance-analysis --overhead-analysis
Expand Down
10 changes: 10 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,16 @@ PYTHONPATH=src python src/ai_quality_agent.py --profile dev --performance-analys
4. **Green CI**: Ensure tests, Ruff, and **mypy** pass locally.
5. **Docs**: If you change CLI flags, config shape, or inference behavior, update `README.md` and any affected file under `docs/`.

## Fast pre-push check (recommended)

Use one command to run the same quality gates CI enforces for PRs:

```bash
bash scripts/dev_prepush_check.sh
```

This keeps PR feedback fast and avoids common red-X cycles caused by lint/type/test drift.

## Code style

Follow existing patterns in nearby modules (logging, typing, error messages). Prefer clear names and small functions over clever one-liners.
Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,12 @@ docker run --rm \
```bash
python -m pip install -U pip
pip install -e ".[dev]"
bash scripts/dev_prepush_check.sh
```

Or run each check manually:

```bash
ruff check src tests app.py test_connection.py
mypy --explicit-package-bases src
MYPYPATH=src mypy --explicit-package-bases app.py test_connection.py
Expand Down
14 changes: 14 additions & 0 deletions scripts/dev_prepush_check.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/usr/bin/env bash
set -euo pipefail

echo "[prepush] Ruff"
ruff check src tests app.py test_connection.py

echo "[prepush] mypy"
mypy --explicit-package-bases src
MYPYPATH=src mypy --explicit-package-bases app.py test_connection.py

echo "[prepush] pytest (CI parity)"
PYTHONPATH=src pytest

echo "[prepush] all checks passed"
2 changes: 1 addition & 1 deletion src/agent/loopback_planner.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import json
import logging
from importlib import import_module
from typing import Any, Dict, List, Optional, Protocol
from typing import Any, Dict, List, Protocol

from models.contracts import LoopbackPlan

Expand Down
8 changes: 6 additions & 2 deletions tests/test_metrics_pool.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from PIL import Image
import pytest

from engine.vision_math import calculate_metrics
from util.metrics_pool import MetricsProcessPool
Expand All @@ -10,7 +11,10 @@ def test_metrics_process_pool_matches_inline(tmp_path):

expected = calculate_metrics(str(image_path))

with MetricsProcessPool(max_workers=2) as pool:
actual = pool.calculate(str(image_path))
try:
with MetricsProcessPool(max_workers=2) as pool:
actual = pool.calculate(str(image_path))
except (PermissionError, NotImplementedError) as exc:
pytest.skip(f"Process pool unavailable on this environment: {exc}")

assert actual == expected
Loading