name: Integration Tests

on:
  push:
    branches: [main]
  pull_request:

permissions:
  contents: read

jobs:
  tests:
    strategy:
      fail-fast: false
      matrix:
        node-version: [20]

        runner:
          - name: Windows
            os: windows-latest

          - name: Linux
            os: namespace-profile-default

          - name: macOS
            os: macos-14

        integration:
          - upgrade
          - vite
          - cli
          - postcss
          - oxide
          - webpack

        # Exclude windows and macos from being built on feature branches
        run-all:
          - ${{ github.ref == 'refs/heads/main' || contains(github.event.pull_request.body, '[ci-all]') }}
        exclude:
          - run-all: false
            runner:
              name: Windows
          - run-all: false
            runner:
              name: macOS

    runs-on: ${{ matrix.runner.os }}
    timeout-minutes: 30

    name: ${{ matrix.runner.name }} /  ${{ matrix.integration }}

    steps:
      - uses: actions/checkout@v4
      - uses: pnpm/action-setup@v4

      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
          cache: 'pnpm'

      # Cargo already skips downloading dependencies if they already exist
      - name: Cache cargo
        uses: actions/cache@v4
        with:
          path: |
            ~/.cargo/bin/
            ~/.cargo/registry/index/
            ~/.cargo/registry/cache/
            ~/.cargo/git/db/
            target/
          key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}

      # Cache the `oxide` Rust build
      - name: Cache oxide build
        uses: actions/cache@v4
        with:
          path: |
            ./crates/node/*.node
            ./crates/node/*.wasm
            ./crates/node/index.d.ts
            ./crates/node/index.js
            ./crates/node/browser.js
            ./crates/node/tailwindcss-oxide.wasi-browser.js
            ./crates/node/tailwindcss-oxide.wasi.cjs
            ./crates/node/wasi-worker-browser.mjs
            ./crates/node/wasi-worker.mjs
          key: ${{ runner.os }}-oxide-${{ hashFiles('./crates/**/*') }}

      - name: Setup WASM target
        run: rustup target add wasm32-wasip1-threads

      - name: Install dependencies
        run: pnpm install

      - name: Build
        run: pnpm run build
        env:
          CARGO_PROFILE_RELEASE_LTO: 'off'
          CARGO_TARGET_X86_64_PC_WINDOWS_MSVC_LINKER: 'lld-link'

      - name: Test ${{ matrix.integration }} 1/3
        run: pnpm run test:integrations ./integrations/${{ matrix.integration }} --shard 1/3
        env:
          GITHUB_WORKSPACE: ${{ github.workspace }}

      - name: Test ${{ matrix.integration }} 2/3
        run: pnpm run test:integrations ./integrations/${{ matrix.integration }} --shard 2/3
        env:
          GITHUB_WORKSPACE: ${{ github.workspace }}

      - name: Test ${{ matrix.integration }} 3/3
        run: pnpm run test:integrations ./integrations/${{ matrix.integration }} --shard 3/3
        env:
          GITHUB_WORKSPACE: ${{ github.workspace }}

      - name: Notify Discord
        if: failure() && github.ref == 'refs/heads/main'
        uses: discord-actions/message@v2
        with:
          webhookUrl: ${{ secrets.DISCORD_WEBHOOK_URL }}
          message: 'The [most recent build](<${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}>) on the `main` branch has failed.'