name: Rust checks

on:
  push:
    branches: [latest]
    tags:
      - 'r*'
  pull_request:
  schedule:
    - cron: "0 0 * * *" # daily

env:
  PIXI_VERSION: "v0.63.2"

jobs:
  check:
    name: Check
    runs-on: ubuntu-latest
    steps:
      - name: Checkout sources
        uses: actions/checkout@v6

      - name: set up pixi
        uses: prefix-dev/setup-pixi@v0.9.4
        with:
          pixi-version: ${{ env.PIXI_VERSION }}
          cache: true
          cache-write: ${{ github.event_name == 'push' && github.ref_name == 'latest' }}
          frozen: true

      - uses: Swatinem/rust-cache@v2

      - name: Run cargo check
        run: |
          pixi run cargo check

  test:
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        build: [beta, stable, windows, macos]
        include:
          - build: macos
            os: macos-latest
            rust: stable
            continue: false
          - build: windows
            os: windows-latest
            rust: stable
            continue: true
          - build: beta
            os: ubuntu-latest
            rust: beta
            continue: false
          - build: stable
            os: ubuntu-latest
            rust: stable
            continue: false
    steps:
      - uses: actions/checkout@v6

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

      - uses: Swatinem/rust-cache@v2

      - uses: taiki-e/install-action@nextest

      - name: Run tests
        run: |
          cargo nextest run

  test_all_features:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6

      - name: set up pixi
        uses: prefix-dev/setup-pixi@v0.9.4
        with:
          pixi-version: ${{ env.PIXI_VERSION }}
          cache: true
          cache-write: ${{ github.event_name == 'push' && github.ref_name == 'latest' }}
          frozen: true

      - uses: Swatinem/rust-cache@v2

      - name: Run tests for all feature combinations
        run: pixi run check-features

  coverage:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6

      - name: set up pixi
        uses: prefix-dev/setup-pixi@v0.9.4
        with:
          pixi-version: ${{ env.PIXI_VERSION }}
          cache: true
          cache-write: ${{ github.event_name == 'push' && github.ref_name == 'latest' }}
          frozen: true
      - uses: Swatinem/rust-cache@v2

      - name: Collect coverage data
        run: pixi run coverage-rust

      - name: Upload Rust coverage to codecov
        uses: codecov/codecov-action@v3
        with:
          flags: rust
          fail_ci_if_error: true
          files: lcov.info

  lints:
    name: Lints
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        build: [beta, stable]
        include:
          - build: beta
            rust: beta
          - build: stable
            rust: stable
    steps:
      - name: Checkout sources
        uses: actions/checkout@v6

      - name: Install Rust toolchain
        uses: dtolnay/rust-toolchain@master
        with:
          toolchain: ${{ matrix.rust }}
          components: "clippy, rustfmt"

      - uses: Swatinem/rust-cache@v2

      - name: Run cargo fmt
        run: |
          cargo fmt --all -- --check

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

  wasm-pack:
    name: Check if wasm-pack builds a valid package for the sourmash crate
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6

      - name: set up pixi
        uses: prefix-dev/setup-pixi@v0.9.4
        with:
          pixi-version: ${{ env.PIXI_VERSION }}
          cache: true
          cache-write: ${{ github.event_name == 'push' && github.ref_name == 'latest' }}
          frozen: true
      - uses: Swatinem/rust-cache@v2

      - name: run wasm tests
        continue-on-error: true  ## TODO: remove this when tests works again...
        run: pixi run -e wasm test-wasm

      - name: run wasm-pack build
        run: pixi run -e wasm build-wasm

      - name: Prepare package for NPM publishing
        run: pixi run -e wasm pack-npm

      - name: Publish to NPM
        if: startsWith(github.ref, 'refs/tags/r')
        run: pixi run -e wasm publish-npm
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

      - uses: actions/upload-artifact@v6
        with:
          path: 'pkg/sourmash*.tgz'

  publish:
    name: Publish (on tags, dry-run otherwise)
    runs-on: ubuntu-latest
    steps:
      - name: Checkout sources
        uses: actions/checkout@v6

      - name: set up pixi
        uses: prefix-dev/setup-pixi@v0.9.4
        with:
          pixi-version: ${{ env.PIXI_VERSION }}
          cache: true
          cache-write: ${{ github.event_name == 'push' && github.ref_name == 'latest' }}
          frozen: true
      - uses: Swatinem/rust-cache@v2

      - name: Check semver
        run: pixi run semver-check

      - name: Make sure we can publish the sourmash crate
        run: pixi run cargo publish --dry-run --manifest-path src/core/Cargo.toml

      # Login to crates.io on tags
      - name: login to crates.io
        if: startsWith(github.ref, 'refs/tags/r')
        run: pixi run cargo login ${{ secrets.CRATES_IO_TOKEN }}

      # Publish to crates.io on tags
      - name: Publish to crates.io
        if: startsWith(github.ref, 'refs/tags/r')
        run: pixi run cargo publish --manifest-path src/core/Cargo.toml

  minimum_rust_version:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6

      - name: set up pixi
        uses: prefix-dev/setup-pixi@v0.9.4
        with:
          pixi-version: ${{ env.PIXI_VERSION }}
          cache: true
          cache-write: ${{ github.event_name == 'push' && github.ref_name == 'latest' }}
          frozen: true
      - uses: Swatinem/rust-cache@v2

      - name: check if README matches MSRV defined here
        run: grep '1.74.0' src/core/README.md

      - name: Check if it builds properly
        run: pixi run check-msrv

  check_cbindgen:
    name: "Check if cbindgen runs cleanly for generating the C headers"
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6

      - name: set up pixi
        uses: prefix-dev/setup-pixi@v0.9.4
        with:
          pixi-version: ${{ env.PIXI_VERSION }}
          cache: true
          cache-write: ${{ github.event_name == 'push' && github.ref_name == 'latest' }}
          frozen: true
      - uses: Swatinem/rust-cache@v2

      - run: pixi run cbindgen-generate

      - name: check if headers have the same content
        run: |
          git update-index --refresh
          git diff
          git diff-index --quiet HEAD -- include/sourmash.h || echo "::error file=include/sourmash.h::Header doesn't match committed file, did you forget to rerun cbindgen?"
