100enigma's picture
SimQuantum — AMD Developer Hackathon
da98415
Raw
History Blame Contribute Delete
7.06 kB
name: CI
on:
workflow_dispatch:
push:
branches: [main, "phase-*"]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
permissions:
contents: read
actions: read
strategy:
matrix:
python-version: ["3.10", "3.11"]
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip setuptools
pip install numpy scipy pytest pytest-cov ruff
pip install torch torchvision --index-url https://download.pytorch.org/whl/cpu
pip install scikit-learn scikit-optimize joblib opencv-python
pip install -e . --no-deps
- name: Lint with ruff
run: ruff check qdot/ tests/
continue-on-error: true # don't block on style during active dev
# ------------------------------------------------------------------
# Phase 0 tests (types, state, governance, HITL)
# ------------------------------------------------------------------
- name: Run Phase 0 tests
run: pytest tests/test_types.py tests/test_state.py -v --tb=short
# ------------------------------------------------------------------
# Phase 0 safety fuzz (zero violations — hard requirement)
# ------------------------------------------------------------------
- name: Safety fuzz test (required zero violations)
run: pytest tests/test_safety.py::TestFuzz -v
# ------------------------------------------------------------------
# Phase 0 simulator tests
# ------------------------------------------------------------------
- name: Run simulator tests
run: pytest tests/test_simulator.py -v --tb=short
# ------------------------------------------------------------------
# Phase 1 perception tests
# ------------------------------------------------------------------
- name: Run Phase 1 perception tests
run: pytest tests/test_perception.py -v --tb=short
# ------------------------------------------------------------------
# Phase 1 training smoke test (must pass — not continue-on-error)
# ------------------------------------------------------------------
#- name: Phase 1 fast training check (smoke test)
#run: |
#python experiments/train_phase1.py --fast --out /tmp/phase1_ci_check
#timeout-minutes: 15
#continue-on-error: false
- name: Phase 1 data generation check (smoke test)
run: |
python - <<'PYEOF'
from qdot.perception.dataset import CIMDataset, DatasetConfig
cfg = DatasetConfig(n_per_class=50, seed=42, augment=False)
ds = CIMDataset(cfg)
X, y = ds.generate()
assert X.shape == (150, 1, 64, 64), f"Unexpected shape: {X.shape}"
assert len(set(y.tolist())) == 3, "Missing classes"
print(f"Data generation OK: {X.shape}, classes={set(y.tolist())}")
PYEOF
timeout-minutes: 2
# ------------------------------------------------------------------
# Phase 2 planning tests (belief, sensing, BO, state machine)
# ------------------------------------------------------------------
- name: Run Phase 2 planning tests
run: pytest tests/test_planning.py -v --tb=short
# ------------------------------------------------------------------
# Phase 2 agent tests (translator, executive — no HITL blocking)
# ------------------------------------------------------------------
- name: Run Phase 2 agent tests
run: pytest tests/test_agent.py -v --tb=short
# ------------------------------------------------------------------
# Phase 0/1/2 integration test (full pipeline smoke test)
# ------------------------------------------------------------------
- name: Run Phase 0/1/2 integration test
run: pytest tests/test_integration_phase012.py -v --tb=short
# ------------------------------------------------------------------
# Phase 2 full test suite with coverage
# ------------------------------------------------------------------
- name: Full test suite with coverage
run: |
pytest tests/ -v --tb=short \
--cov=qdot \
--cov-report=term-missing \
--cov-fail-under=70
continue-on-error: true # coverage target is aspirational during active dev
# ------------------------------------------------------------------
# Phase 2 benchmark (full mode)
# Downloads trained Phase 1 checkpoint from train.yml artifact.
# Falls back to stub mode gracefully if artifact is unavailable.
# Only runs on main branch pushes (3.11 matrix only).
# ------------------------------------------------------------------
- name: Download Phase 1 checkpoint (cross-workflow)
id: checkpoint
if: github.ref == 'refs/heads/main' && matrix.python-version == '3.11'
uses: dawidd6/action-download-artifact@v6
with:
workflow: train.yml
name: phase1-checkpoint-latest
path: experiments/checkpoints/phase1/
if_no_artifact_found: ignore
continue-on-error: true
- name: Report checkpoint status
if: github.ref == 'refs/heads/main' && matrix.python-version == '3.11'
continue-on-error: true
run: |
if [ -f "experiments/checkpoints/phase1/model_0.pt" ]; then
echo "Trained checkpoint loaded — benchmark will use real classifier"
echo "CHECKPOINT_READY=1" >> "$GITHUB_ENV"
else
echo "No checkpoint found — benchmark running in stub mode (smoke test only)"
echo "CHECKPOINT_READY=0" >> "$GITHUB_ENV"
fi
- name: Phase 2 benchmark (full mode)
if: github.ref == 'refs/heads/main' && matrix.python-version == '3.11'
run: |
if [ "${CHECKPOINT_READY:-0}" = "1" ]; then
python experiments/benchmark_phase2.py \
--budget 8192 \
--n-trials 50 \
--max-steps 100 \
--out /tmp/phase2_benchmark
else
python experiments/benchmark_phase2.py \
--budget 8192 \
--n-trials 50 \
--max-steps 100 \
--skip-missing-checkpoints \
--out /tmp/phase2_benchmark
fi
timeout-minutes: 200
continue-on-error: true # benchmark is informational until fully integrated
- name: Upload Phase 2 benchmark results
if: always() && github.ref == 'refs/heads/main' && matrix.python-version == '3.11'
uses: actions/upload-artifact@v4
with:
name: phase2-benchmark-results
path: /tmp/phase2_benchmark/
retention-days: 7