name: CI

# NOTE distilled from,
# https://github.com/orgs/community/discussions/26276
on:
  # any time a new update to 'main'
  push:
    branches:
      - main

  # for on all (forked) PRs to repo
  # NOTE, use a draft PR if you just want CI triggered..
  pull_request:

  # to run workflow manually from the "Actions" tab
  workflow_dispatch:

jobs:
  # ------ sdist ------
  # test that we can generate a software distribution and install it
  # thus avoid missing file issues after packaging.
  #
  # -[x] produce sdist with uv
  # ------ - ------
  sdist-linux:
    name: 'sdist'
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Install latest uv
        uses: astral-sh/setup-uv@v6

      - name: Build sdist as tar.gz
        run: uv build --sdist --python=3.13

      - name: Install sdist from .tar.gz
        # XXX must install under py3.13 (matching the build's
        # `--python=3.13`); the runner's default `python` is 3.12
        # which our `requires-python = ">=3.13"` now rejects.
        run: |
          uv venv --python 3.13
          uv pip install dist/*.tar.gz

  # ------ type-check ------
  # mypy:
  #   name: 'MyPy'
  #   runs-on: ubuntu-latest

  #   steps:
  #     - name: Checkout
  #       uses: actions/checkout@v4

  #     - name: Install latest uv
  #       uses: astral-sh/setup-uv@v6

  #     # faster due to server caching?
  #     # https://docs.astral.sh/uv/guides/integration/github/#setting-up-python
  #     - name: "Set up Python"
  #       uses: actions/setup-python@v6
  #       with:
  #         python-version-file: "pyproject.toml"

  #     # w uv
  #     # - name: Set up Python
  #     #   run: uv python install

  #     - name: Setup uv venv
  #       run: uv venv .venv --python=3.13

  #     - name: Install
  #       run: uv sync --dev

  #     # TODO, ty cmd over repo
  #     # - name: type check with ty
  #     #   run: ty ./tractor/

  #     # - uses: actions/cache@v3
  #     #     name: Cache uv virtenv as default .venv
  #     #     with:
  #     #       path: ./.venv
  #     #       key: venv-${{ hashFiles('uv.lock') }}

  #     - name: Run MyPy check
  #       run: mypy tractor/ --ignore-missing-imports --show-traceback


  testing:
    name: '${{ matrix.os }} Python${{ matrix.python-version }} spawn_backend=${{ matrix.spawn_backend }} tpt_proto=${{ matrix.tpt_proto }}'
    timeout-minutes: 16
    runs-on: ${{ matrix.os }}
    # Windows support is nascent: its full test suite remains
    # informational, while setup and the `import tractor` smoke below
    # are hard signals. Promote the test step to required once the
    # suite is green.

    strategy:
      fail-fast: false
      matrix:
        os: [
          ubuntu-latest,
          macos-latest,
          windows-latest,
        ]
        python-version: [
          '3.13',
          # '3.14',
        ]
        spawn_backend: [
          'trio',
          # 'mp_spawn',
          # 'mp_forkserver',
          # ?TODO^ is it worth it to get these running again?
          #
          # - [ ] next-gen backends, on 3.13+
          #   https://github.com/goodboy/tractor/issues/379
          # 'subinterpreter',
          # 'subint',
        ]
        tpt_proto: [
          'tcp',
          'uds',
        ]
        exclude:
          # UDS is POSIX-only; Windows has no `AF_UNIX` so the
          # backend is intentionally unavailable there.
          - os: windows-latest
            tpt_proto: 'uds'

    steps:
      - uses: actions/checkout@v4

      - name: 'Install uv + py-${{ matrix.python-version }}'
        uses: astral-sh/setup-uv@v6
        with:
          python-version: ${{ matrix.python-version }}

      # GH way.. faster?
      # - name: setup-python@v6
      #   uses: actions/setup-python@v6
      #   with:
      #     python-version: '${{ matrix.python-version }}'

      # consider caching for speedups?
      # https://docs.astral.sh/uv/guides/integration/github/#caching

      - name: Install the project w uv
        run: uv sync --all-extras --dev

      # - name: Install dependencies
      #   run: pip install -U . -r requirements-test.txt -r requirements-docs.txt --upgrade-strategy eager

      - name: List deps tree
        run: uv tree

      # hard signal for the Windows import-safety fix: `import
      # tractor` must succeed everywhere, and `HAS_UDS` reflects
      # platform capability (False on Windows, True on POSIX).
      - name: 'Smoke: import tractor'
        run: uv run python -c "import sys; import tractor; from tractor.ipc._uds import HAS_UDS; assert sys.platform != 'win32' or not HAS_UDS; print('import tractor OK | HAS_UDS=', HAS_UDS)"

      - name: Run tests
        # Actor/PTY scheduling on macOS can fail a different
        # timing-sensitive node between otherwise-green runs. Retry
        # only that matrix leg; deterministic failures still fail
        # after the final attempt.
        continue-on-error: ${{ matrix.os == 'windows-latest' }}
        run: >
          uv run
          pytest
          tests/
          -rsx
          --spawn-backend=${{ matrix.spawn_backend }}
          --tpt-proto=${{ matrix.tpt_proto }}
          --capture=fd
          --reruns=${{ matrix.os == 'macos-latest' && 2 || 0 }}
          --reruns-delay=1

  # XXX legacy NOTE XXX
  #
  # We skip 3.10 on windows for now due to not having any collabs to
  # debug the CI failures. Anyone wanting to hack and solve them is very
  # welcome, but our primary user base is not using that OS.

  # TODO: use job filtering to accomplish instead of repeated
  # boilerplate as is above XD:
  # - https://docs.github.com/en/actions/learn-github-actions/managing-complex-workflows
  # - https://docs.github.com/en/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix
  # - https://docs.github.com/en/actions/learn-github-actions/workflow-syntax-for-github-actions#jobsjob_idif
  # testing-windows:
  #   name: '${{ matrix.os }} Python ${{ matrix.python }} - ${{ matrix.spawn_backend }}'
  #   timeout-minutes: 12
  #   runs-on: ${{ matrix.os }}

  #   strategy:
  #     fail-fast: false
  #     matrix:
  #       os: [windows-latest]
  #       python: ['3.10']
  #       spawn_backend: ['trio', 'mp']

  #   steps:

  #     - name: Checkout
  #       uses: actions/checkout@v2

  #     - name: Setup python
  #       uses: actions/setup-python@v2
  #       with:
  #         python-version: '${{ matrix.python }}'

  #     - name: Install dependencies
  #       run: pip install -U . -r requirements-test.txt -r requirements-docs.txt --upgrade-strategy eager

  #     # TODO: pretty sure this solves debugger deps-issues on windows, but it needs to
  #     # be verified by someone with a native setup.
  #     # - name: Force pyreadline3
  #     #   run: pip uninstall pyreadline; pip install -U pyreadline3

  #     - name: List dependencies
  #       run: pip list

  #     - name: Run tests
  #       run: pytest tests/ --spawn-backend=${{ matrix.spawn_backend }} -rsx
