name: pytest

on:
  push:
    branches:
      - main
  pull_request:
  workflow_dispatch:

env:
  KICAD_VERSION: "9.0"

jobs:
  pytest:
    #runs-on: blacksmith-4vcpu-ubuntu-2404
    #runs-on: blacksmith-32vcpu-ubuntu-2404-arm
    runs-on: blacksmith-32vcpu-ubuntu-2404
    #runs-on: [self-hosted]
    #runs-on: ubuntu-latest
    env:
      UV_PYTHON: "3.14"
    steps:
      - name: Checkout code
        uses: actions/checkout@v6
        with:
          fetch-depth: 100
          fetch-tags: true

      - name: Prepare artifacts dir
        run: mkdir -p artifacts

      - name: Check for uv
        id: check-uv
        run: echo "has-uv=$(command -v uv >/dev/null 2>&1 && echo true || echo false)" >> "$GITHUB_OUTPUT"

      - name: Install uv + Python
        if: steps.check-uv.outputs.has-uv != 'true'
        uses: astral-sh/setup-uv@v7
        with:
          python-version: "3.14"
          enable-cache: true
          cache-dependency-glob: "uv.lock"

      - name: "Install dependencies"
        run: |
          uv sync --dev --no-install-project --frozen

      - name: Compute zig cache key
        id: zig-hash
        run: |
          PYTHON=$(uv python find)
          echo "hash=$($PYTHON src/faebryk/core/zig/compute_hash.py)" >> "$GITHUB_OUTPUT"
          echo "pyver=$($PYTHON -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}")')" >> "$GITHUB_OUTPUT"

      - name: Restore zig cache
        id: zig-cache
        uses: actions/cache/restore@v4
        with:
          path: src/faebryk/core/zig/zig-out
          key: zig-${{ runner.os }}-${{ runner.arch }}-py${{ steps.zig-hash.outputs.pyver }}-${{ steps.zig-hash.outputs.hash }}

      - name: "Compile & build package"
        run: |
          uv pip install --no-deps .
        env:
          ATOPILE_ZIG_OUT_DIR: ${{ github.workspace }}/src/faebryk/core/zig/zig-out

      - name: Save zig cache
        if: steps.zig-cache.outputs.cache-hit != 'true'
        uses: actions/cache/save@v4
        with:
          path: src/faebryk/core/zig/zig-out
          key: zig-${{ runner.os }}-${{ runner.arch }}-py${{ steps.zig-hash.outputs.pyver }}-${{ steps.zig-hash.outputs.hash }}

      - name: Check ato version
        run: |
          PYTHON=$(uv python find)
          git describe --tags --dirty --long
          $PYTHON -c "import importlib.metadata; print(importlib.metadata.version('atopile'))"
          $PYTHON -m atopile self-check
          $PYTHON -m atopile --version
          $PYTHON -m atopile --semver

      - name: Run pytest
        id: pytest
        continue-on-error: true
        # FIXME timeout
        run: |
          PYTHON=$(uv python find)
          $PYTHON -m atopile dev test --ci --timeout=120
        env:
          GH_TOKEN: ${{ github.token }}
          COLUMNS: 150 # rich console width will be pulled from this
          FBRK_TEST_REPORT_INTERVAL: 10
          FBRK_TEST_LONG_THRESHOLD: 30
          FBRK_TEST_SHOW_PYTEST_OUTPUT: 0
          FBRK_TEST_WORKERS: -2 # 32 threads/16 cpus -> 32 workers
          FBRK_TEST_PERIODIC_HTML: 0
          FBRK_TEST_GENERATE_HTML: 1
          # threshold for worker to restart after exceeding after a test run
          FBRK_TEST_WORKER_MEMORY_LIMIT_MB: 1024
          PYTHON_UNBUFFERED: 1
          FBRK_TEST_LOG_VIEWER: 0
          
      - name: Upload test report json artifact
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: test-report.json
          path: artifacts/test-report.json
          if-no-files-found: error
          
      - name: Upload test report html artifact
        uses: actions/upload-artifact@v4
        with:
          name: test-report.html
          path: artifacts/test-report.html
          if-no-files-found: warn

      - name: Check pytest status
        if: steps.pytest.outcome == 'failure'
        run: exit 1
