# Workflow that runs python tests
name: Run Python Tests

# The jobs in this workflow are required, so they must run at all times
# * Always run on "main"
# * Always run on PRs
on:
  push:
    branches:
      - main
  pull_request:

# If triggered by a PR, it will be in the same group. However, each commit on main will be in its own unique group
concurrency:
  group: ${{ github.workflow }}-${{ (github.head_ref && github.ref) || github.run_id }}
  cancel-in-progress: true

jobs:
  # Run python tests on Linux
  test-on-linux:
    name: Python Tests on Linux
    runs-on: ubuntu-24.04
    env:
      INSTALL_DOCKER: "0" # Set to '0' to skip Docker installation
    strategy:
      matrix:
        python-version: ["3.12"]
    permissions:
      # For coverage comment and python-coverage-comment-action branch
      pull-requests: write
      contents: write
    steps:
      - uses: actions/checkout@v6
      - name: Set up Docker Buildx
        id: buildx
        uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4
      - name: Install tmux
        run: sudo apt-get update && sudo apt-get install -y tmux
      - name: Setup Node.js
        uses: actions/setup-node@v6
        with:
          node-version: "22.x"
          cache: 'npm'
          cache-dependency-path: frontend/package-lock.json
      - name: Install poetry via pipx
        run: pipx install poetry
      - name: Set up Python
        uses: actions/setup-python@v6
        with:
          python-version: ${{ matrix.python-version }}
          cache: "poetry"
      - name: Install Python dependencies using Poetry
        run: |
          poetry install --with dev,test,runtime
          poetry run pip install pytest-xdist
          poetry run pip install pytest-rerunfailures
      - name: Build Environment
        run: make build
      - name: Run Unit Tests
        run: PYTHONPATH=".:$PYTHONPATH" poetry run pytest --forked -n auto -s ./tests/unit --cov=openhands --cov-branch
        env:
          COVERAGE_FILE: ".coverage.${{ matrix.python_version }}"
      - name: Store coverage file
        uses: actions/upload-artifact@v7
        with:
          name: coverage-openhands
          path: |
            .coverage.${{ matrix.python_version }}
            .coverage.runtime.${{ matrix.python_version }}
          include-hidden-files: true

  test-enterprise:
    name: Enterprise Python Unit Tests
    runs-on: ubuntu-24.04
    strategy:
      matrix:
        python-version: ["3.12"]
    steps:
      - uses: actions/checkout@v6
      - name: Install poetry via pipx
        run: pipx install poetry
      - name: Set up Python
        uses: actions/setup-python@v6
        with:
          python-version: ${{ matrix.python-version }}
          cache: "poetry"
      - name: Install Python dependencies using Poetry
        working-directory: ./enterprise
        run: poetry install --with dev,test
      - name: Run Unit Tests
        # Use base working directory for coverage paths to line up.
        run: PYTHONPATH=".:$PYTHONPATH" poetry run --project=enterprise pytest --forked -n auto -s -p no:ddtrace -p no:ddtrace.pytest_bdd -p no:ddtrace.pytest_benchmark ./enterprise/tests/unit --cov=enterprise --cov-branch
        env:
          COVERAGE_FILE: ".coverage.enterprise.${{ matrix.python_version }}"
      - name: Store coverage file
        uses: actions/upload-artifact@v7
        with:
          name: coverage-enterprise
          path: ".coverage.enterprise.${{ matrix.python_version }}"
          include-hidden-files: true

  coverage-comment:
    name: Coverage Comment
    if: github.event_name == 'pull_request'
    runs-on: ubuntu-latest
    needs: [test-on-linux, test-enterprise]

    permissions:
      pull-requests: write
      contents: write
    steps:
      - uses: actions/checkout@v6

      - uses: actions/download-artifact@v8
        id: download
        with:
          pattern: coverage-*
          merge-multiple: true

      - name: Coverage comment
        id: coverage_comment
        uses: py-cov-action/python-coverage-comment-action@53ff7553078bad69030786e486677315346c2dd2 # v3
        with:
          GITHUB_TOKEN: ${{ github.token }}
          MERGE_COVERAGE_FILES: true
