name: CI

on:
  workflow_dispatch:
  pull_request:
    types: [opened, synchronize]
    paths-ignore:
      - '**/*.md'
      - '**/*.yml'
  push:
    branches:
      - main
    paths-ignore:
      - '**/*.md'
      - '**/*.yml'

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}
  cancel-in-progress: ${{ github.ref_name != 'main' }}

jobs:
  cache: # Warm cache factory for all other CI jobs
    name: Check and Build
    strategy:
      fail-fast: false
      matrix:
        include:
          - os: windows-latest
          - os: ubuntu-latest
          - os: macos-latest
    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/checkout@v4

      - name: Install Rust Toolchain
        uses: ./.github/actions/rustup
        with:
          save-cache: ${{ github.ref_name == 'main' }}

      - name: Install cargo-nextest
        if: runner.os != 'Windows'
        uses: taiki-e/install-action@cargo-nextest

      - name: Cargo check
        run: cargo ck

      - name: Build oxlint
        run: cargo build -p oxc_cli --bin oxlint # for cli snapshots

      # NAPI crashes nextest on windows
      # https://github.com/napi-rs/napi-rs/issues/1405
      - name: Build cache by Cargo Check and Cargo Test
        if: runner.os == 'Windows'
        run: cargo test run --no-run --workspace --all-features

      - name: Build cache by Cargo Check and Cargo Test
        if: runner.os != 'Windows'
        run: cargo nextest run --no-run --workspace --all-features

  wasm:
    name: Check Wasm
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install Rust Toolchain
        uses: ./.github/actions/rustup
        with:
          shared-key: 'wasm'
          # cache is saved from the website workflow

      - name: Check
        run: |
          rustup target add wasm32-unknown-unknown
          cargo check -p oxc_wasm --target wasm32-unknown-unknown
          cargo check -p oxc_resolver --target wasm32-unknown-unknown

  typos:
    name: Spell Check
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: crate-ci/typos@master
        with:
          files: .

  deny:
    name: Cargo Deny
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: dorny/paths-filter@v2
        id: filter
        with:
          filters: |
            src:
              - 'Cargo.lock'

      - name: Install cargo-deny
        if: steps.filter.outputs.src == 'true'
        uses: taiki-e/install-action@cargo-deny

      - if: steps.filter.outputs.src == 'true'
        run: cargo deny check

  format:
    name: Format
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install Rust
        uses: ./.github/actions/rustup
        with:
          fmt: true
          restore-cache: false

      - run: cargo fmt --all -- --check

  lint:
    name: Clippy
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install Rust
        uses: ./.github/actions/rustup
        with:
          clippy: true

      - name: Run Clippy
        run: cargo lint -- -D warnings

  ecosystem-test:
    name: Testing Linter with VSCode Repository
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Clone VSCode
        uses: actions/checkout@v4
        with:
          repository: microsoft/vscode
          path: ./vscode

      - name: Install Rust
        uses: ./.github/actions/rustup
        with:
          shared-key: oxlint
          save-cache: ${{ github.ref_name == 'main' }}

      - name: Build oxlint
        run: cargo build --release -p oxc_cli --bin oxlint

      - name: Run oxlint on VSCode and throw output to a temp file
        run: ./target/release/oxlint --quiet --ignore-path ./vscode/.eslintignore --allow no-control-regex ./vscode > ./log.tmp

      - name: Using grep to check if oxlint panic
        run: >
          if grep --quiet --ignore-case panic ./log.tmp; then
            exit 1
          fi

  doc:
    name: Doc
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install Rust
        uses: ./.github/actions/rustup
        with:
          docs: true

      - name: Run doc
        run: RUSTDOCFLAGS='-D warnings' cargo doc -p oxc

  test:
    name: Test
    strategy:
      fail-fast: false
      matrix:
        include:
          - os: windows-latest
          - os: ubuntu-latest
          - os: macos-latest
    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/checkout@v4

      - name: Install Rust Toolchain
        uses: ./.github/actions/rustup

      - name: Install cargo-nextest
        if: runner.os != 'Windows'
        uses: taiki-e/install-action@cargo-nextest

      - name: Build oxlint
        run: cargo build -p oxc_cli --bin oxlint # for cli snapshots

      # NAPI crashes nextest on windows
      # https://github.com/napi-rs/napi-rs/issues/1405
      - if: runner.os == 'Windows'
        run: cargo test

      - if: runner.os != 'Windows'
        run: cargo nextest run
