name: CI

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

concurrency:
  group: ci-${{ github.ref }}
  cancel-in-progress: true

defaults:
  run:
    shell: bash -eux {0}

env:
  HATCH_ENV: "cov"

jobs:
  check_release:
    runs-on: ubuntu-latest
    env:
      HATCH_ENV: ""
    steps:
      - uses: actions/checkout@v4
      - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
      - uses: jupyter-server/jupyter_releaser/.github/actions/check-release@v2
        with:
          token: ${{ secrets.GITHUB_TOKEN }}

  check_links:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
      - uses: jupyterlab/maintainer-tools/.github/actions/check-links@v1

  test:
    runs-on: ${{ matrix.os }}
    timeout-minutes: 20

    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-latest, windows-latest, macos-latest]
        python-version:
          - "3.10"
          - "3.14"
          - "3.14t"
        include:
          - os: windows-latest
            python-version: "3.12"
          - os: ubuntu-latest
            python-version: "pypy-3.11"
          - os: ubuntu-latest
            python-version: "3.11"
          - os: macos-latest
            python-version: "3.10"
    steps:
      - uses: actions/checkout@v4
      - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1

      - name: disable warnings on pypy or windows
        if: ${{ startsWith(matrix.python-version, 'pypy') || startsWith(matrix.os, 'windows') }}
        run: |
          echo "PYTEST_ADDOPTS=${PYTEST_ADDOPTS:-} -W default" >> $GITHUB_ENV

      - name: disable coverage on pypy
        if: ${{ startsWith(matrix.python-version, 'pypy') }}
        run: |
          echo "HATCH_ENV=test" >> $GITHUB_ENV

      - name: show env
        run: |
          hatch -e ${HATCH_ENV} run python -VV
          hatch -e ${HATCH_ENV} run pip freeze

      - name: Run the tests
        run: |
          hatch run ${HATCH_ENV}:test
        env:
          PYTHONTRACEMALLOC: "10"

      - uses: jupyterlab/maintainer-tools/.github/actions/upload-coverage@v1

  coverage:
    runs-on: ubuntu-latest
    needs:
      - test
    steps:
      - uses: actions/checkout@v4
      - uses: jupyterlab/maintainer-tools/.github/actions/report-coverage@v1
        with:
          fail_under: 78

  docs:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
      - name: Build API docs
        run: |
          hatch run docs:api
          # If this fails run `hatch run docs:api` locally
          # and commit.
          git status --porcelain
          if git status -s | grep "^\s*[AM]"; then
            exit 1
          fi
          echo "API docs done"
      - run: hatch run docs:build

  lint:
    name: Test Lint
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
      - name: Run Linters
        run: |
          hatch run typing:test
          hatch run lint:build
          pipx run interrogate -v .
          pipx run doc8 --max-line-length=200  --ignore-path=docs/source/other/full-config.rst

  test_minimum_verisons:
    name: Test Minimum Versions
    runs-on: ubuntu-latest
    timeout-minutes: 20
    steps:
      - uses: actions/checkout@v4
      - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
        with:
          dependency_type: minimum
          python_version: "3.10"

      - name: show env
        run: |
          hatch -e test run python -VV
          hatch -e test run pip freeze

      - name: Run the unit tests
        run: |
          hatch -vv run test:nowarn

      - name: Run the unit tests with orjson installed
        run: |
          hatch -e test run pip install orjson
          hatch -vv run test:nowarn

  test_prereleases:
    name: Test Prereleases
    timeout-minutes: 10
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
        with:
          dependency_type: pre
      - name: Run the tests
        run: |
          hatch run test:nowarn

  make_sdist:
    name: Make SDist
    runs-on: ubuntu-latest
    timeout-minutes: 10
    steps:
      - uses: actions/checkout@v4
      - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
      - uses: jupyterlab/maintainer-tools/.github/actions/make-sdist@v1

  test_sdist:
    runs-on: ubuntu-latest
    needs: [make_sdist]
    name: Install from SDist and Test
    timeout-minutes: 20
    steps:
      - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
      - uses: jupyterlab/maintainer-tools/.github/actions/test-sdist@v1
        with:
          test_command: pytest -vv

  tests_check: # This job does nothing and is only used for the branch protection
    if: always()
    needs:
      - coverage
      - docs
      - lint
      - check_links
      - test_minimum_verisons
      - test_prereleases
      - test_sdist
    runs-on: ubuntu-latest
    steps:
      - name: Decide whether the needed jobs succeeded or failed
        uses: re-actors/alls-green@release/v1
        with:
          jobs: ${{ toJSON(needs) }}
