Merge pull request #51 from Coding-Dev-Tools/codex/railway-ready-final #313
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: ci | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| permissions: | |
| contents: read | |
| jobs: | |
| test: | |
| name: test + lint (full offline stack) | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| python-version: ["3.10", "3.11", "3.12"] | |
| steps: | |
| - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 | |
| - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| - name: Install (core + server/mcp/code extras; no torch — the offline gate) | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -e ".[test]" | |
| - name: Lint (ruff) | |
| run: ruff check . | |
| - name: Commercial manifest + strict-CSP drift gate | |
| run: | | |
| python scripts/check_commercial_manifest.py | |
| python scripts/externalize_dashboard_assets.py | |
| - name: Unit tests (full suite — extras-gated tests included) | |
| run: python -m pytest tests/ -q | |
| - name: Retrieval eval gate | |
| run: python -m eval.harness --dataset eval/datasets/sample.jsonl --k 5 | |
| - name: Retrieval eval gate — CodeMem (coding-agent wedge, incl. conflict resolution) | |
| run: python -m eval.harness --dataset eval/datasets/codemem.jsonl --k 5 | |
| - name: Ablation (vector-only vs hybrid) | |
| run: python -m eval.ablation | |
| core-py39: | |
| name: core floor (numpy-only, Python 3.9) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 | |
| - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6 | |
| with: | |
| python-version: "3.9" | |
| - name: Install (numpy-only core — the minimum supported runtime) | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install numpy pytest | |
| - name: Unit tests (extras-gated tests skip; the core must pass) | |
| run: python -m pytest tests/ -q | |
| - name: Retrieval eval gate | |
| run: python -m eval.harness --dataset eval/datasets/sample.jsonl --k 5 | |
| - name: Ablation | |
| run: python -m eval.ablation | |
| browser-accessibility: | |
| name: browser accessibility smoke | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 | |
| - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6 | |
| with: | |
| python-version: "3.11" | |
| - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 | |
| with: | |
| node-version: "24" | |
| - name: Install dashboard and browser test dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -e ".[test]" "uvicorn[standard]>=0.29" | |
| npm ci | |
| npx playwright install --with-deps chromium | |
| - name: Playwright desktop/mobile, keyboard, CSP, console, and axe checks | |
| run: npx playwright test | |
| docker-gate: | |
| # Keeps CI fast: the docker job always runs on push to main, but on PRs only | |
| # when image/deployment paths changed (Dockerfile, entrypoint, Railway, source, | |
| # pyproject.toml, or this workflow). No third-party actions — plain git diff. | |
| name: docker smoke — path gate | |
| runs-on: ubuntu-latest | |
| outputs: | |
| run: ${{ steps.decide.outputs.run }} | |
| steps: | |
| - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 | |
| with: | |
| fetch-depth: 0 | |
| - id: decide | |
| run: | | |
| if [ "${{ github.event_name }}" != "pull_request" ]; then | |
| echo "run=true" >> "$GITHUB_OUTPUT" | |
| elif git diff --name-only "${{ github.event.pull_request.base.sha }}" "${{ github.sha }}" \ | |
| | grep -qE '^(Dockerfile|docker-entrypoint\.sh|docker-compose\.yml|railway\.json|deploy/|\.dockerignore|engraphis/|scripts/|pyproject\.toml|\.github/workflows/ci\.yml)'; then | |
| echo "run=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "run=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| docker-smoke: | |
| name: docker build + health smoke | |
| runs-on: ubuntu-latest | |
| needs: docker-gate | |
| if: needs.docker-gate.outputs.run == 'true' | |
| steps: | |
| - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 | |
| - name: Build image | |
| run: docker build -t engraphis:ci . | |
| - name: Verify production image OCR runtime | |
| run: >- | |
| docker run --rm --entrypoint sh engraphis:ci -c | |
| 'python -c "import PIL, pytesseract" && command -v tesseract >/dev/null && | |
| tesseract --version | head -n 1' | |
| - name: Audit the exact production image dependency set | |
| run: >- | |
| docker run --rm --entrypoint sh engraphis:ci -c | |
| 'python -m pip install --no-cache-dir pip-audit && | |
| python -m pip_audit --local' | |
| - name: Run container (offline deterministic embedder — no model downloads) | |
| run: | | |
| docker run -d --name engraphis -p 8700:8700 \ | |
| -e ENGRAPHIS_EMBED_MODEL= \ | |
| -e ENGRAPHIS_LOOP_INTERVAL=0 \ | |
| -e ENGRAPHIS_HOST=0.0.0.0 \ | |
| -e ENGRAPHIS_SERVICE_MODE=customer \ | |
| engraphis:ci | |
| - name: Wait for /api/health, then check /api/ready | |
| run: | | |
| for i in $(seq 1 60); do | |
| code=$(curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:8700/api/health || true) | |
| if [ "$code" = "200" ]; then | |
| echo "healthy after ~${i}s" | |
| curl -fsS http://127.0.0.1:8700/api/ready | |
| exit 0 | |
| fi | |
| sleep 1 | |
| done | |
| echo "server never became healthy" | |
| docker logs engraphis | |
| exit 1 | |
| - name: Teardown | |
| if: always() | |
| run: docker rm -f engraphis | |
| build: | |
| name: build + install wheel | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 | |
| - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6 | |
| with: | |
| python-version: "3.11" | |
| - name: Build sdist + wheel and verify a clean install | |
| run: | | |
| python -m pip install --upgrade pip build pip-audit | |
| python -m build | |
| python -m venv .audit-venv | |
| .audit-venv/bin/python -m pip install --upgrade "pip>=26.1.2" "setuptools>=83" | |
| .audit-venv/bin/python -m pip install dist/*.whl | |
| AUDIT_SITE=$(.audit-venv/bin/python -c "import site; print(site.getsitepackages()[0])") | |
| python -m pip_audit --path "$AUDIT_SITE" | |
| .audit-venv/bin/python -c "import engraphis; print('wheel import OK')" |