name: CI on: push: branches: ["main", "master"] pull_request: env: FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true jobs: test: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 with: python-version: "3.11" cache: "pip" - name: Set up Node uses: actions/setup-node@v4 with: node-version: "22" - name: Install CI dependencies run: | python -m pip install --upgrade pip python -m pip install fastapi uvicorn[standard] python-multipart pillow numpy httpx jinja2 - name: Compile backend run: python -m compileall backend - name: Build frontend run: | npm --prefix frontend ci npm --prefix frontend run build - name: Smoke test FastAPI pages and posts run: | python - <<'PY' from fastapi.testclient import TestClient from backend.app.main import app client = TestClient(app, raise_server_exceptions=False) for path in ["/", "/board", "/post/1"]: response = client.get(path) assert response.status_code == 200, (path, response.status_code, response.text[:300]) created = client.post( "/api/v1/posts", json={ "title": "CI smoke test", "image_url": "data:image/png;base64,test", "prediction": "A", "confidence": 0.9, }, ) assert created.status_code == 200, created.text post_id = created.json()["id"] updated = client.put(f"/api/v1/posts/{post_id}", json={"title": "CI edited title"}) assert updated.status_code == 200, updated.text assert updated.json()["title"] == "CI edited title" PY - name: Check model files run: | python - <<'PY' from pathlib import Path model_path = Path("ai/model/keras_model.h5") labels_path = Path("ai/model/labels.txt") print(f"model file present: {model_path.exists()}") print(f"labels file present: {labels_path.exists()}") if labels_path.exists(): labels = [line.strip() for line in labels_path.read_text(encoding="utf-8").splitlines() if line.strip()] assert labels, "labels.txt is empty" print(f"labels count: {len(labels)}") PY