llmkit 0.1.3

Production-grade LLM client - 100+ providers, 11,000+ models. Pure Rust.
Documentation
name: CI

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main, develop]

env:
  CARGO_TERM_COLOR: always
  RUST_BACKTRACE: 1

jobs:
  # Check documentation
  docs:
    name: Documentation
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6

      - name: Install Rust
        uses: dtolnay/rust-toolchain@stable

      - name: Check documentation
        run: RUSTDOCFLAGS="-D warnings" cargo doc --no-deps --all-features

  # Check formatting
  fmt:
    name: Format Check
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6

      - name: Install Rust
        uses: dtolnay/rust-toolchain@stable
        with:
          components: rustfmt

      - name: Check formatting
        run: cargo fmt -- --check

  # Linting with Clippy
  clippy:
    name: Clippy
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6

      - name: Install Rust
        uses: dtolnay/rust-toolchain@stable
        with:
          components: clippy

      - name: Cache
        uses: Swatinem/rust-cache@v2

      - name: Run Clippy
        run: cargo clippy --all-targets --all-features -- -D warnings

  # Build and test
  test:
    name: Test
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]
        rust: [stable]
        include:
          - os: ubuntu-latest
            rust: beta
          - os: ubuntu-latest
            rust: nightly
    steps:
      - uses: actions/checkout@v6

      - name: Install Rust
        uses: dtolnay/rust-toolchain@master
        with:
          toolchain: ${{ matrix.rust }}

      - name: Cache
        uses: Swatinem/rust-cache@v2
        with:
          key: ${{ matrix.rust }}

      - name: Build
        run: cargo build --verbose

      - name: Run tests
        run: cargo test --verbose

      - name: Build with all features
        run: cargo build --all-features --verbose

      - name: Run tests with all features
        run: cargo test --all-features --verbose

      - name: Build documentation
        run: cargo doc --no-deps --all-features

  # Test individual provider features
  features:
    name: Feature Tests
    runs-on: ubuntu-latest
    strategy:
      matrix:
        features:
          - "anthropic"
          - "openai"
          - "anthropic,openai"
          - "anthropic,openai,groq"
    steps:
      - uses: actions/checkout@v6

      - name: Install Rust
        uses: dtolnay/rust-toolchain@stable

      - name: Cache
        uses: Swatinem/rust-cache@v2

      - name: Build with features
        run: cargo build --no-default-features --features "${{ matrix.features }}"

      - name: Test with features
        run: cargo test --no-default-features --features "${{ matrix.features }}"

  # Python bindings test
  python:
    name: Python Bindings
    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
    steps:
      - uses: actions/checkout@v6

      - name: Set up Python
        uses: actions/setup-python@v6
        with:
          python-version: ${{ matrix.python-version }}

      - name: Install Rust
        uses: dtolnay/rust-toolchain@stable

      - name: Cache
        uses: Swatinem/rust-cache@v2

      - name: Install maturin
        run: pip install maturin pytest pytest-asyncio

      - name: Build Python package
        working-directory: llmkit-python
        run: maturin build --release --out dist

      - name: Install wheel
        run: pip install llmkit-python/dist/*.whl

      - name: Test Python bindings
        run: python -c "import llmkit; print('LLMKit Python bindings loaded successfully')"

  # Node.js bindings test
  nodejs:
    name: Node.js Bindings
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: ["20", "22", "24"]
    steps:
      - uses: actions/checkout@v6

      - name: Set up Node.js
        uses: actions/setup-node@v6
        with:
          node-version: ${{ matrix.node-version }}

      - name: Install Rust
        uses: dtolnay/rust-toolchain@stable

      - name: Cache
        uses: Swatinem/rust-cache@v2

      - name: Setup pnpm
        uses: pnpm/action-setup@v4
        with:
          version: 9

      - name: Build Node.js package
        working-directory: llmkit-node
        run: |
          pnpm install
          pnpm build

      - name: Test Node.js bindings
        working-directory: llmkit-node
        run: pnpm test run

  # Build examples
  examples:
    name: Build Examples
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6

      - name: Install Rust
        uses: dtolnay/rust-toolchain@stable

      - name: Cache
        uses: Swatinem/rust-cache@v2

      - name: Build examples
        run: cargo build --examples --all-features

  # Security audit
  audit:
    name: Security Audit
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6

      - name: Run security audit
        uses: actions-rust-lang/audit@v1

  # Check dependencies
  deny:
    name: Dependency Check
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6

      - name: Install Rust
        uses: dtolnay/rust-toolchain@stable

      - name: Check dependencies
        uses: EmbarkStudios/cargo-deny-action@v2

  # Code coverage (only on main branch)
  coverage:
    name: Code Coverage
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main' || github.event_name == 'pull_request'
    steps:
      - uses: actions/checkout@v6

      - name: Install Rust
        uses: dtolnay/rust-toolchain@stable

      - name: Cache
        uses: Swatinem/rust-cache@v2

      - name: Install tarpaulin
        run: |
          curl -Lo tarpaulin.tar.gz https://github.com/xd009642/tarpaulin/releases/latest/download/cargo-tarpaulin-x86_64-unknown-linux-gnu.tar.gz
          tar xzf tarpaulin.tar.gz
          mv cargo-tarpaulin ~/.cargo/bin/

      - name: Generate coverage
        run: cargo tarpaulin --lib --skip-clean --timeout 300 --out xml --exclude-files "tests/*" || true
        continue-on-error: true

      - name: Upload coverage to Codecov
        uses: codecov/codecov-action@v4
        with:
          files: ./cobertura.xml
          fail_ci_if_error: false