# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

name: CI

on:
  push:
    branches:
      - main
  pull_request:
    paths:
      - '**'                              # Include all files and directories in the repository by default.
      - '!.github/ISSUE_TEMPLATE/**'      # Exclude files and directories that don't impact tests or code like templates, metadata, and documentation.
      - '!scripts/**'
      - '!website/**'
      - '!.asf.yml'
      - '!.gitattributes'
      - '!.gitignore'
      - '!CONTRIBUTING.md'
      - '!CHANGELOG.md'
      - '!LICENSE'
      - '!NOTICE'
      - '!README.md'

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}
  cancel-in-progress: true

permissions:
  contents: read

jobs:
  check:
    runs-on: ${{ matrix.os }}
    strategy:
      max-parallel: 15
      matrix:
        os:
          - ubuntu-latest
          - macos-latest
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
        with:
          persist-credentials: false

      - name: Setup Rust toolchain
        uses: ./.github/actions/setup-builder

      - name: Check License Header
        uses: apache/skywalking-eyes/header@61275cc80d0798a405cb070f7d3a8aaf7cf2c2c1 # v0.8.0

      - name: Check toml format
        run: make check-toml

      - name: Install protoc
        uses: arduino/setup-protoc@c65c819552d16ad3c9b72d9dfd5ba5237b9c906b # v3
        with:
          repo-token: ${{ secrets.GITHUB_TOKEN }}

      - name: Cargo format
        run: make check-fmt

      - name: Check diff
        run: git diff --exit-code

      - name: Cargo clippy
        run: make check-clippy

      - name: Cargo Machete
        run: make cargo-machete

  build:
    runs-on: ${{ matrix.os }}
    strategy:
      max-parallel: 15
      matrix:
        os:
          - ubuntu-latest
          - macos-latest
          - windows-latest
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
        with:
          persist-credentials: false

      - name: Setup Rust toolchain
        uses: ./.github/actions/setup-builder

      - name: Cache Rust artifacts
        uses: swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2

      - name: Install protoc
        uses: arduino/setup-protoc@c65c819552d16ad3c9b72d9dfd5ba5237b9c906b # v3
        with:
          repo-token: ${{ secrets.GITHUB_TOKEN }}

      - name: Build
        run: make build

  build_with_no_default_features:
    runs-on: ${{ matrix.os }}
    strategy:
      max-parallel: 15
      matrix:
        os:
          - ubuntu-latest
          - macos-latest
          - windows-latest
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
        with:
          persist-credentials: false

      - name: Setup Rust toolchain
        uses: ./.github/actions/setup-builder

      - name: Cache Rust artifacts
        uses: swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2

      - name: Build
        run: cargo build -p iceberg --no-default-features

  tests:
    runs-on: ubuntu-latest
    strategy:
      max-parallel: 15
      matrix:
        test-suite:
          - { name: "default", args: "--all-targets --all-features --workspace" }
          - { name: "doc", args: "--doc --all-features --workspace" }
    name: Tests (${{ matrix.test-suite.name }})
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
        with:
          persist-credentials: false

      - name: Setup Rust toolchain
        uses: ./.github/actions/setup-builder

      - name: Install protoc
        uses: arduino/setup-protoc@c65c819552d16ad3c9b72d9dfd5ba5237b9c906b # v3
        with:
          repo-token: ${{ secrets.GITHUB_TOKEN }}

      - name: Cache Rust artifacts
        uses: swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
        with:
          key: ${{ matrix.test-suite.name }}

      - name: Install cargo-nextest
        if: matrix.test-suite.name == 'default'
        uses: taiki-e/install-action@0fde6d128a3d980ceac30be8c8b8739abd963b81 # v2.70.0
        with:
          tool: cargo-nextest

      - name: Start Docker containers
        if: matrix.test-suite.name == 'default'
        run: make docker-up

      - name: Run tests
        shell: bash
        env:
          # Disable debug info to speed up compilation and reduce artifact size
          RUSTFLAGS: "-C debuginfo=0"
        run: |
          if [ "${{ matrix.test-suite.name }}" = "default" ]; then
            cargo nextest run ${{ matrix.test-suite.args }}
          else
            cargo test --no-fail-fast ${{ matrix.test-suite.args }}
          fi

      - name: Stop Docker containers
        if: always() && matrix.test-suite.name == 'default'
        run: make docker-down

  msrv:
    name: Verify MSRV
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
        with:
          persist-credentials: false
      - name: Install protoc
        uses: arduino/setup-protoc@c65c819552d16ad3c9b72d9dfd5ba5237b9c906b # v3
        with:
          repo-token: ${{ secrets.GITHUB_TOKEN }}
      - name: Get MSRV
        id: get-msrv
        uses: ./.github/actions/get-msrv
      - name: Setup MSRV Rust toolchain
        uses: ./.github/actions/setup-builder
        with:
          rust-version: ${{ steps.get-msrv.outputs.msrv }}
      - name: Setup Nightly Rust toolchain
        uses: ./.github/actions/setup-builder
      - name: Check MSRV
        run: make check-msrv
