Skip to content

Refactor MCP registration; docs & POMDP fixture #75

Refactor MCP registration; docs & POMDP fixture

Refactor MCP registration; docs & POMDP fixture #75

Workflow file for this run

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