name: Compile and run tests

permissions: read-all

on:
  merge_group:
  push:
    branches:
      - main
  pull_request:

jobs:
  run-tests:
    name: Tests on ${{ matrix.os }} with node ${{ matrix.node }}
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        os:
          - ubuntu-latest
          - windows-latest
          - macos-latest
        node:
          - 22
          - 24
          - 26

    steps:
      - name: Check out repository
        uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
        with:
          fetch-depth: 2

      - name: Set up Node.js
        uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
        with:
          cache: npm
          node-version: 22 # build works only with 22+.

      - name: Install dependencies
        shell: bash
        run: npm ci
        env:
          PUPPETEER_SKIP_DOWNLOAD: true

      - name: Install browser
        shell: bash
        run: npx puppeteer browsers install chrome

      - name: Build
        run: npm run bundle
        env:
          NODE_OPTIONS: '--max_old_space_size=4096'

      - name: Set up Node.js
        uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
        with:
          cache: npm
          node-version: ${{ matrix.node }}

      - name: Disable AppArmor
        if: ${{ matrix.os == 'ubuntu-latest' }}
        shell: bash
        run: echo 0 | sudo tee /proc/sys/kernel/apparmor_restrict_unprivileged_userns

      - name: Run tests
        shell: bash
        # Retry tests if they fail in the merge queue.
        run: >
          npm run test:no-build --
          ${{ matrix.os == 'windows-latest' && '--test-concurrency=1' || '' }}
          ${{ github.event_name == 'merge_group' && '--retry' || '' }}

  # Gating job for branch protection.
  test-success:
    name: '[Required] Tests passed'
    runs-on: ubuntu-latest
    needs: run-tests
    if: ${{ !cancelled() }}
    steps:
      - if: ${{ needs.run-tests.result != 'success' }}
        run: 'exit 1'
      - run: 'exit 0'
