name: Python - Merge - Tests

on:
  workflow_dispatch:
  pull_request:
    branches: ["main"]
  merge_group:
    branches: ["main"]
  schedule:
    - cron: "0 0 * * *" # Run at midnight UTC daily

permissions:
  contents: write
  id-token: write

env:
  # Configure a constant location for the uv cache
  UV_CACHE_DIR: /tmp/.uv-cache
  RUN_INTEGRATION_TESTS: "true"
  RUN_SAMPLES_TESTS: ${{ vars.RUN_SAMPLES_TESTS }}

jobs:
  paths-filter:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      pull-requests: read
    outputs:
      pythonChanges: ${{ steps.filter.outputs.python}}
    steps:
      - uses: actions/checkout@v5
      - uses: dorny/paths-filter@v3
        id: filter
        with:
          filters: |
            python:
              - 'python/**'
      # run only if 'python' files were changed
      - name: python tests
        if: steps.filter.outputs.python == 'true'
        run: echo "Python file"
      # run only if not 'python' files were changed
      - name: not python tests
        if: steps.filter.outputs.python != 'true'
        run: echo "NOT python file"
  python-tests-core:
    name: Python Tests - Core
    needs: paths-filter
    if: github.event_name != 'pull_request' && needs.paths-filter.outputs.pythonChanges == 'true'
    runs-on: ${{ matrix.os }}
    environment: ${{ matrix.environment }}
    strategy:
      fail-fast: true
      matrix:
        python-version: ["3.10"]
        os: [ubuntu-latest]
        environment: ["integration"]
    env:
      UV_PYTHON: ${{ matrix.python-version }}
      OPENAI_CHAT_MODEL_ID: ${{ vars.OPENAI__CHATMODELID }}
      OPENAI_RESPONSES_MODEL_ID: ${{ vars.OPENAI__RESPONSESMODELID }}
      OPENAI_API_KEY: ${{ secrets.OPENAI__APIKEY }}
      ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
      ANTHROPIC_CHAT_MODEL_ID: ${{ vars.ANTHROPIC_CHAT_MODEL_ID }}
      AZURE_OPENAI_CHAT_DEPLOYMENT_NAME: ${{ vars.AZUREOPENAI__CHATDEPLOYMENTNAME }}
      AZURE_OPENAI_RESPONSES_DEPLOYMENT_NAME: ${{ vars.AZUREOPENAI__RESPONSESDEPLOYMENTNAME }}
      AZURE_OPENAI_ENDPOINT: ${{ vars.AZUREOPENAI__ENDPOINT }}
      LOCAL_MCP_URL: ${{ vars.LOCAL_MCP__URL }}
    defaults:
      run:
        working-directory: python
    steps:
      - uses: actions/checkout@v5
      - name: Set up python and install the project
        id: python-setup
        uses: ./.github/actions/python-setup
        with:
          python-version: ${{ matrix.python-version }}
          os: ${{ runner.os }}
        env:
          # Configure a constant location for the uv cache
          UV_CACHE_DIR: /tmp/.uv-cache
      - name: Azure CLI Login
        if: github.event_name != 'pull_request'
        uses: azure/login@v2
        with:
          client-id: ${{ secrets.AZURE_CLIENT_ID }}
          tenant-id: ${{ secrets.AZURE_TENANT_ID }}
          subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
      - name: Test with pytest
        timeout-minutes: 10
        run: uv run poe all-tests -n logical --dist loadfile --dist worksteal --timeout 300 --retries 3 --retry-delay 10
        working-directory: ./python
      - name: Test core samples
        timeout-minutes: 10
        if: env.RUN_SAMPLES_TESTS == 'true'
        run: uv run pytest tests/samples/ -m "openai" -m "azure"
        working-directory: ./python
      - name: Surface failing tests
        if: always()
        uses: pmeier/pytest-results-action@v0.7.2
        with:
          path: ./python/**.xml
          summary: true
          display-options: fEX
          fail-on-empty: false
          title: Test results

  python-tests-azure-ai:
    name: Python Tests - Azure AI
    needs: paths-filter
    if: github.event_name != 'pull_request' && needs.paths-filter.outputs.pythonChanges == 'true'
    runs-on: ${{ matrix.os }}
    environment: ${{ matrix.environment }}
    strategy:
      fail-fast: true
      matrix:
        python-version: ["3.10"]
        os: [ubuntu-latest]
        environment: ["integration"]
    env:
      UV_PYTHON: ${{ matrix.python-version }}
      AZURE_AI_PROJECT_ENDPOINT: ${{ secrets.AZUREAI__ENDPOINT }}
      AZURE_AI_MODEL_DEPLOYMENT_NAME: ${{ vars.AZUREAI__DEPLOYMENTNAME }}
      LOCAL_MCP_URL: ${{ vars.LOCAL_MCP__URL }}
    defaults:
      run:
        working-directory: python
    steps:
      - uses: actions/checkout@v5
      - name: Set up python and install the project
        id: python-setup
        uses: ./.github/actions/python-setup
        with:
          python-version: ${{ matrix.python-version }}
          os: ${{ runner.os }}
        env:
          # Configure a constant location for the uv cache
          UV_CACHE_DIR: /tmp/.uv-cache
      - name: Azure CLI Login
        if: github.event_name != 'pull_request'
        uses: azure/login@v2
        with:
          client-id: ${{ secrets.AZURE_CLIENT_ID }}
          tenant-id: ${{ secrets.AZURE_TENANT_ID }}
          subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
      - name: Test with pytest
        timeout-minutes: 10
        run: uv run poe azure-ai-tests -n logical --dist loadfile --dist worksteal --timeout 300 --retries 3 --retry-delay 10
        working-directory: ./python
      - name: Test Azure AI samples
        timeout-minutes: 10
        if: env.RUN_SAMPLES_TESTS == 'true'
        run: uv run pytest tests/samples/ -m "azure-ai"
        working-directory: ./python
      - name: Surface failing tests
        if: always()
        uses: pmeier/pytest-results-action@v0.7.2
        with:
          path: ./python/**.xml
          summary: true
          display-options: fEX
          fail-on-empty: false
          title: Test results

  # TODO: Add python-tests-lab

  python-integration-tests-check:
    if: always()
    runs-on: ubuntu-latest
    needs:
      [
        python-tests-core,
        python-tests-azure-ai
      ]
    steps:

      - name: Fail workflow if tests failed
        id: check_tests_failed
        if: contains(join(needs.*.result, ','), 'failure')
        uses: actions/github-script@v8
        with:
          script: core.setFailed('Integration Tests Failed!')

      - name: Fail workflow if tests cancelled
        id: check_tests_cancelled
        if: contains(join(needs.*.result, ','), 'cancelled')
        uses: actions/github-script@v8
        with:
          script: core.setFailed('Integration Tests Cancelled!')
