qdrant-datafusion 0.1.1

Qdrant integration for Apache DataFusion
Documentation
name: CI

concurrency:
  group: ${{ github.repository }}-${{ github.head_ref || github.sha }}-${{ github.workflow }}
  cancel-in-progress: true

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]
  workflow_dispatch:

permissions:
  contents: read
  checks: write

env:
  CARGO_TERM_COLOR: always
  RUST_BACKTRACE: 1
  RUSTFLAGS: '-C debuginfo=line-tables-only -C incremental=false'

jobs:
  changes:
    name: Detect Changes
    runs-on: ubuntu-latest
    outputs:
      code: ${{ steps.changes.outputs.code }}
    steps:
    - uses: actions/checkout@v4
    - uses: dorny/paths-filter@master
      id: changes
      with:
        predicate-quantifier: 'every'
        filters: |
          code:
            - '**'
            - '!**.md'
            - '!docs/**'
            - '!.claude/**'
            - '!.gitignore'
            - '!.justfile'
            - '!LICENSE'
            - '!.github/workflows/pr.yml'
            - '!.github/workflows/release.yml'
            - '!.github/workflows/security.yml'
            - '!.github/dependabot.yml'
            - '!.github/labeler.yml'

  check:
    name: Check
    runs-on: ubuntu-latest
    needs: changes
    if: needs.changes.outputs.code == 'true'
    steps:
    - uses: actions/checkout@v4

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

    - name: Install Rust nightly (for formatting)
      uses: dtolnay/rust-toolchain@nightly
      with:
        components: rustfmt

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

    - name: Run clippy
      run: cargo +stable clippy --profile ci --all-features --all-targets -- -D warnings

  test-unit:
    name: Unit Tests
    runs-on: ubuntu-latest
    needs: changes
    if: needs.changes.outputs.code == 'true'
    strategy:
      matrix:
        features:
          - "test-utils"
    steps:
    - uses: actions/checkout@v4

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

    - name: Cache cargo registry
      uses: actions/cache@v4
      with:
        path: ~/.cargo/registry
        key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }}

    - name: Cache cargo index
      uses: actions/cache@v4
      with:
        path: ~/.cargo/git
        key: ${{ runner.os }}-cargo-index-${{ hashFiles('**/Cargo.lock') }}

    - name: Cache cargo build
      uses: actions/cache@v4
      with:
        path: target
        key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('**/Cargo.lock') }}-${{ github.job }}-${{ strategy.job-index }}

    - name: Run unit tests
      run: |
        cargo test --lib --profile ci -F ${{ matrix.features }} -- --nocapture --show-output

  test-integration:
    name: Integration Tests
    runs-on: ubuntu-latest
    needs: changes
    if: needs.changes.outputs.code == 'true'
    strategy:
      matrix:
        features:
          - "test-utils"
    steps:
    - uses: actions/checkout@v4

    - name: Login to Docker Hub
      uses: docker/login-action@v3
      with:
        username: ${{ secrets.DOCKER_USERNAME }}
        password: ${{ secrets.DOCKER_PASSWORD }}

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

    - name: Cache cargo registry
      uses: actions/cache@v4
      with:
        path: ~/.cargo/registry
        key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }}

    - name: Cache cargo index
      uses: actions/cache@v4
      with:
        path: ~/.cargo/git
        key: ${{ runner.os }}-cargo-index-${{ hashFiles('**/Cargo.lock') }}

    - name: Cache cargo build
      uses: actions/cache@v4
      with:
        path: target
        key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('**/Cargo.lock') }}-${{ github.job }}-${{ strategy.job-index }}

    - name: Run integration tests
      run: |
        cargo test --profile ci -F ${{ matrix.features }} --test "e2e" -- --nocapture --show-output

    # TODO: Convert doc test to tests and reenable
    # - name: Run doc tests
    #   run: cargo +${{ matrix.rust }} test --doc --all-features

  coverage:
    name: Code Coverage
    runs-on: ubuntu-latest
    needs: changes
    if: needs.changes.outputs.code == 'true'
    steps:
    - uses: actions/checkout@v4

    - name: Login to Docker Hub
      uses: docker/login-action@v3
      with:
        username: ${{ secrets.DOCKER_USERNAME }}
        password: ${{ secrets.DOCKER_PASSWORD }}

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

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

    - name: Generate code coverage
      run: |
        cargo llvm-cov clean --workspace
        cargo llvm-cov --lcov --no-report --ignore-filename-regex "(examples).*" -F test-utils
        cargo llvm-cov report --lcov --output-path lcov.info

    - name: Upload coverage to Codecov
      uses: codecov/codecov-action@v5
      with:
        token: ${{ secrets.CODECOV_TOKEN }}
        files: lcov.info
        fail_ci_if_error: true
        disable_telem: true

  # Summary job that branch protection can depend on
  ci-success:
    name: CI Success
    needs: [changes, check, test-unit, test-integration, coverage]
    runs-on: ubuntu-latest
    if: always()
    steps:
      - name: Check if all jobs succeeded
        run: |
          # If only docs changed, that's success
          if [[ "${{ needs.changes.outputs.code }}" == "false" ]]; then
            echo "Documentation-only change ✅"
            exit 0
          fi

          # Otherwise check that all CI jobs succeeded
          if [[ "${{ needs.check.result }}" != "success" ||
                "${{ needs.test-unit.result }}" != "success" ||
                "${{ needs.test-integration.result }}" != "success" ||
                "${{ needs.coverage.result }}" != "success" ]]; then
            echo "One or more jobs failed ❌"
            exit 1
          fi
          echo "All CI jobs passed successfully! ✅"