name: Build

on:
  push:
    branches: ['main']
  pull_request:
  schedule:
    - cron: '0 0 * * *'

permissions:
  contents: read

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}
  cancel-in-progress: true

env:
  PIP_DISABLE_PIP_VERSION_CHECK: 1

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

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

      - name: Build
        uses: ./.github/actions/build-dist

  test:
    runs-on: ubuntu-latest
    timeout-minutes: 20
    strategy:
      fail-fast: false
      matrix:
        # used by the jupyterlab/maintainer-tools base-setup action
        python-version: ['3.9', '3.10', '3.11', '3.12', '3.13']
    steps:
      - name: Checkout
        uses: actions/checkout@v6

      - name: Base Setup
        uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1

      - name: Test the package
        run: hatch run cov:test

      - name: JavaScript tests
        run: |
          hatch run js_test

      - name: Integration Tests
        run: |
          pip install .
          cd
          jupyter labextension list 2>&1 | grep -ie "@jupyter-notebook/lab-extension.*enabled.*ok" -
          jupyter server extension list 2>&1 | grep -ie "notebook.*enabled" -
          python -m jupyterlab.browser_check

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

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

  test_docs:
    name: Test Docs
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
      - run: |
          sudo apt-get update
          sudo apt install enchant-2  # for spelling

          # pandoc is not up to date in the ubuntu repos, so we install directly
          wget https://github.com/jgm/pandoc/releases/download/2.14.2/pandoc-2.14.2-1-amd64.deb && sudo dpkg -i pandoc-2.14.2-1-amd64.deb
      - run: hatch run docs:build

  test_minimum_versions:
    name: Test Minimum Versions
    timeout-minutes: 20
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
        with:
          dependency_type: minimum
          python_version: '3.10'
      - name: Run the unit tests
        run: |
          hatch run test:nowarn || hatch run test:nowarn --lf

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

  install:
    needs: [build]
    runs-on: ${{ matrix.os }}
    timeout-minutes: 15
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]
        python: ['3.9', '3.11', '3.13']
        include:
          - python: '3.9'
            dist: 'notebook*.tar.gz'
          - python: '3.11'
            dist: 'notebook*.whl'
          - python: '3.13'
            dist: 'notebook*.whl'
          - os: windows-latest
            py_cmd: python
          - os: macos-latest
            py_cmd: python3
          - os: ubuntu-latest
            py_cmd: python
    steps:
      - name: Install Python
        uses: actions/setup-python@v6
        with:
          python-version: ${{ matrix.python }}
          allow-prereleases: true
      - uses: actions/download-artifact@v6
        with:
          name: notebook-dist-${{ github.run_number }}
          path: ./dist
      - name: Install the prerequisites
        run: |
          ${{ matrix.py_cmd }} -m pip install -U pip wheel
      - name: Install the package
        run: |
          cd dist
          ${{ matrix.py_cmd }} -m pip install -vv ${{ matrix.dist }}
      - name: Validate environment
        run: |
          ${{ matrix.py_cmd }} -m pip freeze
          ${{ matrix.py_cmd }} -m pip check
      - name: Validate the install
        run: |
          jupyter labextension list
          jupyter labextension list 2>&1 | grep -ie "@jupyter-notebook/lab-extension.*enabled.*ok" -
          jupyter server extension list
          jupyter server extension list 2>&1 | grep -ie "notebook.*enabled" -
          jupyter notebook --version
          jupyter notebook --help

  check_links:
    runs-on: ubuntu-latest
    timeout-minutes: 10
    steps:
      - uses: actions/checkout@v6
      - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
      - uses: jupyterlab/maintainer-tools/.github/actions/check-links@v1
        with:
          ignore_links: 'https://playwright.dev/docs/test-cli/ https://blog.jupyter.org/.* https://mybinder.org/v2/gh/jupyter/notebook/main https://nbviewer.jupyter.org https://stackoverflow.com https://github.com/[^/]+/?$'
          ignore_glob: 'ui-tests/test/notebooks/*'

  test_lint:
    name: Test Lint
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - 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 docs/source *.md
          npm install -g yarn
          yarn
          yarn eslint:check
          yarn prettier:check
          yarn build:utils
          yarn integrity

  tests_check: # This job does nothing and is only used for the branch protection
    if: always()
    needs:
      - coverage
      - install
      - test_lint
      - test_docs
      - test_minimum_versions
      - test_prereleases
      - check_links
    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) }}
