name: Rust

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

env:
  CARGO_TERM_COLOR: always

jobs:
  build:
    strategy:
      matrix:
        os: [ubuntu-latest, macos-14]
    runs-on: ${{ matrix.os }}

    steps:
      - uses: actions/checkout@v3

      - name: Install rust
        uses: dtolnay/rust-toolchain@master
        with:
          toolchain: stable

      - uses: actions/cache@v3
        with:
          path: |
            ~/.cargo/registry
            ~/.cargo/git
            target
          key: ${{ runner.os }}-cargo-release-${{ hashFiles('**/Cargo.lock') }}

      - name: Run cargo build common
        run: cargo build -p atuin-common --locked --release

      - name: Run cargo build client
        run: cargo build -p atuin-client --locked --release

      - name: Run cargo build server
        run: cargo build -p atuin-server --locked --release

      - name: Run cargo build main
        run: cargo build --all --locked --release

  cross-compile:
    strategy:
      matrix:
        # There was an attempt to make cross-compiles also work on FreeBSD, but that failed with:
        #
        # warning: libelf.so.2, needed by <...>/libkvm.so, not found (try using -rpath or -rpath-link)
        target: [x86_64-unknown-illumos]
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Install cross
        uses: taiki-e/install-action@v1
        with:
          tool: cross

      - uses: actions/cache@v3
        with:
          path: |
            ~/.cargo/registry
            ~/.cargo/git
            target
          key: ${{ matrix.target }}-cross-compile-${{ hashFiles('**/Cargo.lock') }}

      - name: Run cross build common
        run: cross build -p atuin-common --locked --target ${{ matrix.target }}

      - name: Run cross build client
        run: cross build -p atuin-client --locked --target ${{ matrix.target }}

      - name: Run cross build server
        run: cross build -p atuin-server --locked --target ${{ matrix.target }}

      - name: Run cross build main
        run: |
          cross build --all --locked --target ${{ matrix.target }}

  unit-test:
    strategy:
      matrix:
        os: [ubuntu-latest, macos-14]
    runs-on: ${{ matrix.os }}

    steps:
      - uses: actions/checkout@v3

      - name: Install rust
        uses: dtolnay/rust-toolchain@master
        with:
          toolchain: stable

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

      - uses: actions/cache@v3
        with:
          path: |
            ~/.cargo/registry
             ~/.cargo/git
             target
          key: ${ runner.os }-cargo-debug-${{ hashFiles('**/Cargo.lock') }}

      - name: Run cargo test
        run: cargo nextest run --lib --bins

  check:
    strategy:
      matrix:
        os: [ubuntu-latest, macos-14]
    runs-on: ${{ matrix.os }}

    steps:
      - uses: actions/checkout@v3

      - name: Install rust
        uses: dtolnay/rust-toolchain@master
        with:
          toolchain: stable

      - uses: actions/cache@v3
        with:
          path: |
            ~/.cargo/registry
             ~/.cargo/git
             target
          key: ${ runner.os }-cargo-debug-${{ hashFiles('**/Cargo.lock') }}

      - name: Run cargo check (all features)
        run: cargo check --all-features --workspace

      - name: Run cargo check (no features)
        run: cargo check --no-default-features --workspace

      - name: Run cargo check (sync)
        run: cargo check --no-default-features --features sync --workspace

      - name: Run cargo check (server)
        run: cargo check --no-default-features --features server --workspace

      - name: Run cargo check (client only)
        run: cargo check --no-default-features --features client --workspace

  integration-test:
    runs-on: ubuntu-latest

    services:
      postgres:
        image: postgres
        env:
          POSTGRES_USER: atuin
          POSTGRES_PASSWORD: pass
          POSTGRES_DB: atuin
        ports:
          - 5432:5432

    steps:
      - uses: actions/checkout@v3

      - name: Install rust
        uses: dtolnay/rust-toolchain@master
        with:
          toolchain: stable

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

      - uses: actions/cache@v3
        with:
          path: |
            ~/.cargo/registry
             ~/.cargo/git
             target
          key: ${ runner.os }-cargo-debug-${{ hashFiles('**/Cargo.lock') }}

      - name: Run cargo test
        run: cargo nextest run --test '*'
        env:
          ATUIN_DB_URI: postgres://atuin:pass@localhost:5432/atuin

  clippy:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3

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

      - uses: actions/cache@v3
        with:
          path: |
            ~/.cargo/registry
            ~/.cargo/git
            target
          key: ${{ runner.os }}-cargo-debug-${{ hashFiles('**/Cargo.lock') }}

      - name: Run clippy
        run: cargo clippy -- -D warnings

  format:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3

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

      - name: Format
        run: cargo fmt -- --check
