rulesxp 0.3.1

Multi-language rules expression evaluator supporting JSONLogic and Scheme with strict typing
Documentation
name: CI

on:
  push:
    branches: [ main, feature/pipeline-test ]
  pull_request:
    branches: [ main ]

env:
  CARGO_TERM_COLOR: always
  MSRV: '1.90'

jobs:
  test:
    name: Test Suite
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        rust-version: ['msrv', 'stable']
        cargo-args:
          - '--no-default-features'
          - '--no-default-features --features scheme'
          - '--no-default-features --features jsonlogic'
          - '--no-default-features --features scheme,jsonlogic'

    steps:
    - name: Checkout code
      uses: actions/checkout@v6

    - name: Resolve toolchain
      id: resolve
      shell: bash
      run: |
        rust="${{ matrix.rust-version }}"
        [[ "$rust" == "msrv" ]] && rust="$MSRV"
        echo "toolchain=$rust" >> "$GITHUB_OUTPUT"

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

    - name: Install clippy (stable only)
      if: matrix.rust-version == 'stable'
      run: rustup component add clippy

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

    - name: Run tests
      run: cargo test --all-targets ${{ matrix.cargo-args }} --verbose

    - name: Run clippy
      if: matrix.rust-version == 'stable'
      run: cargo clippy --all-targets ${{ matrix.cargo-args }} -- -D warnings

    - name: Run doc tests (all features)
      run: cargo test --doc --all-features

  coverage:
    name: Code Coverage
    runs-on: ubuntu-latest

    steps:
    - name: Checkout code
      uses: actions/checkout@v6

    - name: Install Rust
      uses: dtolnay/rust-toolchain@stable
      with:
        components: llvm-tools-preview

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

    - name: Install cargo-llvm-cov
      uses: taiki-e/install-action@cargo-llvm-cov

    - name: Generate code coverage
      run: |
        cargo llvm-cov --all-features --workspace --html --output-dir coverage-html
        cargo llvm-cov --all-features --workspace --lcov --output-path lcov.info --no-run

    - name: Upload coverage HTML
      uses: actions/upload-artifact@v7
      with:
        name: coverage-report
        path: coverage-html/
        retention-days: 30

    - name: Upload to Codecov
      if: env.CODECOV_TOKEN != ''
      uses: codecov/codecov-action@v5
      with:
        files: lcov.info
        fail_ci_if_error: true
      env:
        CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

  fmt:
    name: Formatting
    runs-on: ubuntu-latest

    steps:
    - name: Checkout code
      uses: actions/checkout@v6

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

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

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

  docs:
    name: Documentation
    runs-on: ubuntu-latest

    steps:
    - name: Checkout code
      uses: actions/checkout@v6

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

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

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

    - name: Check for broken links in docs
      run: cargo doc --all-features --no-deps 2>&1 | grep -i "warning\|error" && exit 1 || exit 0

  fuzz-build:
    # This job ensures the fuzz crate compiles on the nightly toolchain.
    # Actual fuzzing runs on a schedule in fuzz.yml, not here.
    name: Fuzz Build Check
    runs-on: ubuntu-latest

    steps:
    - name: Checkout code
      uses: actions/checkout@v6

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

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

    - name: Install cargo-fuzz
      run: cargo install cargo-fuzz

    - name: Check fuzz crate compilation
      run: cargo fuzz build

  security:
    name: Security Audit
    runs-on: ubuntu-latest

    steps:
    - name: Checkout code
      uses: actions/checkout@v6

    - name: Install cargo-audit
      uses: taiki-e/install-action@v2
      with:
        tool: cargo-audit

    - name: Run security audit
      run: cargo audit

  minimal-versions:
    name: Minimal Versions
    runs-on: ubuntu-latest

    steps:
    - name: Checkout code
      uses: actions/checkout@v6

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

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

    - name: Install cargo-hack and cargo-minimal-versions
      uses: taiki-e/install-action@v2
      with:
        tool: cargo-hack,cargo-minimal-versions

    - name: Check minimal versions
      run: cargo +nightly minimal-versions check --direct --all-features