Refactor MCP registration; docs & POMDP fixture #75
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] | |
| paths-ignore: | |
| - "**/*.md" | |
| - "doc/**" | |
| pull_request: | |
| types: [opened, synchronize, reopened, ready_for_review] | |
| branches: [main] | |
| paths-ignore: | |
| - "**/*.md" | |
| - "doc/**" | |
| workflow_dispatch: | |
| concurrency: | |
| group: ci-${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| permissions: | |
| contents: read | |
| defaults: | |
| run: | |
| shell: bash | |
| jobs: | |
| test: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 35 | |
| permissions: | |
| contents: read | |
| strategy: | |
| matrix: | |
| python-version: ["3.11", "3.12", "3.13"] | |
| fail-fast: false | |
| env: | |
| PYTHONPATH: src | |
| 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 uv | |
| uses: astral-sh/setup-uv@v5 | |
| with: | |
| enable-cache: true | |
| - name: Install dependencies (dev) | |
| run: uv sync --frozen --extra dev | |
| - name: Validate JAX + PyMDP stack (core) | |
| run: | | |
| uv run python -c "from utils.jax_stack_validation import verify_jax_pymdp_stack; verify_jax_pymdp_stack(); print('jax_stack_ok')" | |
| - name: Ruff format check | |
| if: matrix.python-version == '3.12' | |
| run: uv run ruff format --check src scripts | |
| - name: Ruff check | |
| if: matrix.python-version == '3.12' | |
| run: uv run ruff check src scripts | |
| - name: Repository terminology audit | |
| if: matrix.python-version == '3.12' | |
| run: uv run python scripts/check_repo_terminology.py --strict | |
| - name: Maintained documentation terminology audit | |
| if: matrix.python-version == '3.12' | |
| run: uv run python scripts/check_maintained_doc_terms.py --strict | |
| - name: Documentation audit | |
| if: matrix.python-version == '3.12' | |
| run: uv run python doc/development/docs_audit.py --strict --check-anchors --no-write | |
| - name: GNN documentation pattern audit | |
| if: matrix.python-version == '3.12' | |
| run: uv run python scripts/check_gnn_doc_patterns.py --strict | |
| - name: Mypy type check | |
| if: matrix.python-version == '3.12' | |
| run: uv run mypy src --show-error-codes | |
| - name: Pytest collect-only | |
| if: matrix.python-version == '3.12' | |
| run: | | |
| uv run pytest --collect-only src/tests/ -q --tb=no \ | |
| --ignore=src/tests/llm/test_llm_ollama.py \ | |
| --ignore=src/tests/llm/test_llm_ollama_integration.py | |
| - name: Focused PyMDP/POMDP tests | |
| if: matrix.python-version == '3.12' | |
| run: | | |
| uv run pytest \ | |
| src/tests/execute/test_pymdp_contracts.py \ | |
| src/tests/execute/test_discrete_models_pymdp.py \ | |
| src/tests/visualization/test_visualization_matrices.py \ | |
| -q --tb=short | |
| - name: Run unit and integration tests (skip pipeline & MCP) | |
| id: pytest | |
| run: | | |
| mkdir -p junit | |
| uv run pytest -m "not pipeline and not mcp" \ | |
| --tb=short \ | |
| -q \ | |
| --junitxml=junit/pytest-${{ matrix.python-version }}.xml | |
| - name: Pytest JUnit report | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: pytest-junit-${{ matrix.python-version }} | |
| path: junit/pytest-${{ matrix.python-version }}.xml | |
| if-no-files-found: warn | |
| - name: Test job summary | |
| if: always() | |
| run: | | |
| { | |
| echo "### Tests (Python ${{ matrix.python-version }})" | |
| echo "" | |
| echo "Outcome: **${{ steps.pytest.outcome }}**" | |
| echo "" | |
| echo "JUnit XML is attached as artifact \`pytest-junit-${{ matrix.python-version }}\` when present." | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| - name: MCP tool count assertion | |
| if: matrix.python-version == '3.12' | |
| run: | | |
| uv run python - <<'PY' | |
| import sys | |
| sys.path.insert(0, "src") | |
| from tests.mcp.test_mcp_audit import count_mcp_tools | |
| count = count_mcp_tools() | |
| print(f"MCP tools: {count}") | |
| if count < 130: | |
| raise SystemExit(f"MCP tool count regression: {count} < 130") | |
| print("MCP tool count OK") | |
| PY | |
| security: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 20 | |
| permissions: | |
| contents: read | |
| security-events: write | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.12" | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v5 | |
| with: | |
| enable-cache: true | |
| - name: Install dependencies (dev) | |
| run: uv sync --frozen --extra dev | |
| - name: Run Bandit scan (medium+ findings fail) | |
| id: bandit | |
| continue-on-error: true | |
| run: | | |
| uv run bandit -r src -c pyproject.toml \ | |
| --severity-level medium \ | |
| --confidence-level medium \ | |
| -f sarif \ | |
| -o bandit-results.sarif | |
| - name: Upload Bandit SARIF to code scanning | |
| if: always() && hashFiles('bandit-results.sarif') != '' | |
| uses: github/codeql-action/upload-sarif@v3 | |
| with: | |
| sarif_file: bandit-results.sarif | |
| category: bandit | |
| - name: Upload Bandit SARIF artifact | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: bandit-results | |
| path: bandit-results.sarif | |
| if-no-files-found: warn | |
| - name: Fail if Bandit reported issues | |
| if: steps.bandit.outcome == 'failure' | |
| run: exit 1 |