name: CI

on:
  push:
    branches:
      - main
  pull_request:
    branches:
      - main

env:
  COLUMNS: 150

jobs:
  lint:
    name: Lint
    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: ["3.10", "3.13"]
    steps:
      - uses: actions/checkout@v4

      - name: Install uv
        uses: astral-sh/setup-uv@v4

      - name: Set up Python ${{ matrix.python-version }}
        run: uv python install ${{ matrix.python-version }}

      - name: Install dependencies
        run: uv sync --python ${{ matrix.python-version }} --group lint

      - name: Run ruff format check
        run: uv run ruff format --check

      - name: Run ruff lint
        run: uv run ruff check

  typecheck:
    name: Type Check
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install uv
        uses: astral-sh/setup-uv@v4

      - name: Set up Python
        run: uv python install 3.12

      - name: Install dependencies
        run: uv sync --all-extras --group dev --group lint

      - name: Run Pyright
        run: uv run pyright

      - name: Run MyPy
        run: uv run mypy pydantic_deep tests

  test:
    name: Test Python ${{ matrix.python-version }}
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        python-version: ["3.10", "3.11", "3.12", "3.13"]
    steps:
      - uses: actions/checkout@v4

      - name: Install uv
        uses: astral-sh/setup-uv@v4

      - name: Set up Python ${{ matrix.python-version }}
        run: uv python install ${{ matrix.python-version }}

      - name: Install dependencies
        run: uv sync --python ${{ matrix.python-version }} --all-extras --group dev

      - name: Run tests with coverage
        run: |
          uv run coverage run -m pytest
          uv run coverage report
          uv run coverage lcov -o coverage.lcov

      - name: Upload coverage to Coveralls
        if: matrix.python-version == '3.12'
        uses: coverallsapp/github-action@v2
        with:
          file: coverage.lcov

  security:
    name: Security Scan
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install uv
        uses: astral-sh/setup-uv@v4

      - name: Set up Python
        run: uv python install 3.12

      - name: Install dependencies
        run: uv sync --python 3.12 --group lint

      - name: Run Bandit security scanner
        run: uv run bandit -r pydantic_deep -x tests -ll

  docs:
    name: Build Documentation
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install uv
        uses: astral-sh/setup-uv@v4

      - name: Set up Python
        run: uv python install 3.12

      - name: Install dependencies
        run: uv sync --group docs

      - name: Build docs
        run: uv run mkdocs build

  install:
    # Every job above syncs the development environment, which holds far more
    # than `pip install pydantic-deep` does - so 0.3.45 shipped importing `httpx`
    # and building a DuckDuckGo search fallback that neither it nor its
    # dependencies installed. This installs the package alone and builds the
    # default agent.
    name: Fresh Install
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install uv
        uses: astral-sh/setup-uv@v4

      - name: Install the package alone
        run: |
          uv venv --python 3.12 "$RUNNER_TEMP/fresh"
          uv pip install --python "$RUNNER_TEMP/fresh/bin/python" .

      - name: Import it and build the default agent
        run: |
          "$RUNNER_TEMP/fresh/bin/python" - <<'PY'
          from pydantic_deep import create_deep_agent

          create_deep_agent(model="test")
          print("the default agent builds")
          PY

  all-checks:
    name: All Checks Passed
    runs-on: ubuntu-latest
    needs: [lint, typecheck, security, test, docs, install]
    steps:
      - name: All checks passed
        run: echo "All CI checks passed successfully!"
