# TODO: Replace `wait-for-server` with dedicated command
#       https://github.com/PrefectHQ/prefect/issues/6990

name: Integration tests
on:
  pull_request:
    paths:
      - .github/workflows/integration-tests.yaml
      - "src/prefect/**/*.py"
      - pyproject.toml
      - ui/**
      - .nvmrc
      - Dockerfile
      - integration-tests/*
  push:
    branches:
      - main
    paths:
      - .github/workflows/integration-tests.yaml
      - "**/*.py"
      - pyproject.toml
      - ui/**
      - .nvmrc
      - Dockerfile

jobs:
  compatibility-tests:
    name: Integration tests @${{ matrix.server-version.version }}
    timeout-minutes: 10
    runs-on: ubuntu-latest

    strategy:
      fail-fast: false
      matrix:
        server-version: [
            # These versions correspond to Prefect image tags, the patch version is
            # excluded to always pull the latest patch of each minor version.  The ref
            # should generally be set to the latest patch release for that version.
            { version: "main", ref: "main" },
          ]

    steps:
      - uses: actions/checkout@v6
        with:
          persist-credentials: false
          fetch-depth: 0

      - name: Set up uv
        uses: astral-sh/setup-uv@v7
        with:
          enable-cache: true
          python-version: "3.10"
          cache-dependency-glob: "pyproject.toml"

      - name: Start server@${{ matrix.server-version.version }}
        if: ${{ matrix.server-version.version != 'main' }}
        env:
          PREFECT_API_URL: http://127.0.0.1:4200/api
          PREFECT_SERVER_LOGGING_LEVEL: DEBUG
          PREFECT_EXPERIMENTAL_EVENTS: "true"
        run: >
          docker run \
            --name "prefect-server" \
            -d \
            -p 4200:4200 \
            -e PREFECT_API_URL=${{ env.PREFECT_API_URL }} \
            -e PREFECT_SERVER_LOGGING_LEVEL=${{ env.PREFECT_SERVER_LOGGING_LEVEL }} \
            ${{ matrix.server-version.image }} \
            prefect server start --analytics-off --host 0.0.0.0

          uv run ./scripts/wait-for-server.py

      - name: Start server
        if: ${{ matrix.server-version.version == 'main' }}
        env:
          PREFECT_API_URL: http://127.0.0.1:4200/api
          PREFECT_SERVER_LOGGING_LEVEL: DEBUG
          PREFECT_SERVER_CONCURRENCY_LEASE_STORAGE: "prefect.server.concurrency.lease_storage.filesystem"
          PREFECT_SERVER_SERVICES_REPOSSESSOR_LOOP_SECONDS: "1"
        run: >
          uv run prefect server start --analytics-off --host 0.0.0.0 2>&1 > server.log &
          uv run ./scripts/wait-for-server.py

      - name: Run integration flows
        env:
          PREFECT_API_URL: http://127.0.0.1:4200/api
          PREFECT_SERVER_CONCURRENCY_LEASE_STORAGE: "prefect.server.concurrency.lease_storage.filesystem"
          SERVER_VERSION: ${{ matrix.server-version.version }}
        run: >
          uv run pytest integration-tests/ -n auto -vv

      - name: Show server logs
        if: always()
        run: |
          cat server.log || echo "No logs available"
          docker logs prefect-server || echo "No logs available"

  prefect-client-compatibility-tests:
    name: Prefect Client Compatibility Tests
    timeout-minutes: 10
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
        with:
          persist-credentials: false
          fetch-depth: 0

          
      - name: Create a temp dir to stage our build
        run: |
          echo "TMPDIR=$(mktemp -d)" >> $GITHUB_ENV

      - name: Prepare files for prefect-client build (omit the local build)
        run: sh client/build_client.sh
        env:
          TMPDIR: ${{ env.TMPDIR }}
        
      - name: Set up uv
        uses: astral-sh/setup-uv@v7
        with:
          enable-cache: true
          python-version: "3.10"
          cache-dependency-glob: "pyproject.toml"
          activate-environment: true
          working-directory: ${{ env.TMPDIR }}

      - name: Install `prefect-client`
        run: |
          cat pyproject.toml
          uv build
          uv pip install dist/*.tar.gz
        working-directory: ${{ env.TMPDIR }}

      - name: Verify the CLI isn't available in the active environment
        run: |
          prefect --help && { echo "Prefect CLI should not be available in the active environment"; exit 1; } || echo "Prefect CLI is not available in the active environment"
      - name: Start server
        env:
          PREFECT_API_URL: http://127.0.0.1:4200/api
          PREFECT_SERVER_LOGGING_LEVEL: DEBUG
        run: >
          uv run prefect server start --analytics-off --host 0.0.0.0 2>&1 > server.log &
          uv run --isolated ./scripts/wait-for-server.py

      - name: Verify the CLI isn't available in the active environment
        run: |
          prefect --help && { echo "Prefect CLI should not be available in the active environment"; exit 1; } || echo "Prefect CLI is not available in the active environment"

      - name: Run integration flows
        env:
          PREFECT_API_URL: http://127.0.0.1:4200/api
        run: |
          # Install dependencies for integration tests. We don't want to install the whole project because that will override the prefect-client build.
          # We ignore some test files because they rely on server code that is not available in the client build.
          uv pip install pytest \
            uv \
            docker \
            sqlalchemy \
            pytest-mypy-plugins \
            pytest-asyncio \
            pytest-xdist \
            pytest-timeout \
            pytest-env
          pytest --ignore=integration-tests/test_task_worker.py --ignore=integration-tests/test_concurrency_leases.py --ignore=integration-tests/test_deploy.py integration-tests/ -n auto -vv

  sqlite-3-24-0:
    name: Test SQLite 3.24.0 Compatibility
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
        with:
          fetch-depth: 0

      - name: Test with SQLite 3.24.0
        run: >
          docker build -t prefect-server-old-sqlite \
            --build-arg SQLITE_VERSION=3240000 \
            --build-arg SQLITE_YEAR=2018 \
            -f .github/docker/old-sqlite.Dockerfile . &&
          docker run prefect-server-old-sqlite sh -c "prefect server database downgrade --yes -r base && prefect server database upgrade --yes"

  sqlite-3-31-1:
    name: Test SQLite 3.31.1 Compatibility
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
        with:
          fetch-depth: 0

      - name: Test with SQLite 3.31.1
        run: >
          docker build -t prefect-server-new-sqlite \
            --build-arg SQLITE_VERSION=3310100 \
            --build-arg SQLITE_YEAR=2020 \
            -f .github/docker/old-sqlite.Dockerfile . &&
          docker run prefect-server-new-sqlite sh -c "prefect server database downgrade --yes -r base && prefect server database upgrade --yes"
