name: Alembic Migration Validation

on:
  pull_request:
    branches: [ main ]
  pull_request_target:
    branches: [ main ]
    types: [labeled]

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}

jobs:
  changed-files:
    # Run on pull_request OR on pull_request_target only when labeled "safe to test"
    if: github.event_name == 'pull_request' || (github.event_name == 'pull_request_target' && contains(github.event.pull_request.labels.*.name, 'safe to test'))
    runs-on: ubuntu-latest
    name: changed-files
    outputs:
      all_changed_files: ${{ steps.changed-files.outputs.all_changed_files }}
      any_changed: ${{ steps.changed-files.outputs.any_changed }}
    steps:
      - uses: actions/checkout@v4
        with:
          repository: ${{ github.event.pull_request.head.repo.full_name }}
          ref: ${{ github.event.pull_request.head.ref }}
          fetch-depth: 0
      - name: Get changed files
        id: changed-files
        uses: tj-actions/changed-files@v44
        with:
          files: |
            alembic/**
            .github/workflows/alembic-validation.yml

  test-sqlite:
    needs: [ changed-files ]
    if: ${{ needs.changed-files.outputs.any_changed == 'true' }}
    runs-on: [self-hosted, medium]
    timeout-minutes: 15
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          repository: ${{ github.event.pull_request.head.repo.full_name }}
          ref: ${{ github.event.pull_request.head.ref }}

      - name: Install dependencies
        shell: bash
        working-directory: .
        run: uv sync --no-install-project ${{ inputs.install-args || '--extra sqlite --extra external-tools --extra dev --extra cloud-tool-sandbox' }}
      - name: Test alembic migration
        working-directory: .
        run: |
          uv run alembic upgrade head
          # kinda janky but I think this might not matter for sqlite?
          # uv run alembic check

      - name: Cleanup persistent data
        if: ${{ always() }}
        working-directory: .
        run: |
          echo "Cleaning up persistent data..."
          sudo rm -rf ~/.letta || true

  test-postgres:
    needs: [ changed-files ]
    if: ${{ needs.changed-files.outputs.any_changed == 'true' }}
    runs-on: [self-hosted, medium]
    timeout-minutes: 15
    services:
      postgres:
        image: pgvector/pgvector:pg17
        ports:
          - 5432:5432
        env:
          POSTGRES_HOST_AUTH_METHOD: trust
          POSTGRES_DB: postgres
          POSTGRES_USER: postgres
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          repository: ${{ github.event.pull_request.head.repo.full_name }}
          ref: ${{ github.event.pull_request.head.ref }}

      - name: Install dependencies
        shell: bash
        working-directory: .
        run: uv sync --no-install-project ${{ inputs.install-args || '--extra postgres --extra external-tools --extra dev --extra cloud-tool-sandbox' }}
      - name: Test alembic migration
        working-directory: .
        env:
          LETTA_PG_PORT: 5432
          LETTA_PG_USER: postgres
          LETTA_PG_PASSWORD: postgres
          LETTA_PG_DB: postgres
          LETTA_PG_HOST: localhost
        run: |
          psql -h localhost -U postgres -d postgres -c 'CREATE EXTENSION IF NOT EXISTS vector;'
          uv run alembic upgrade head
          uv run alembic check

      - name: Print docker logs if tests fail
        if: ${{ failure() || cancelled() }}
        run: |
          echo "Printing Docker Logs..."
          docker logs $(docker ps -aq --filter "ancestor=pgvector/pgvector:pg17") || true

      - name: Cleanup containers and volumes
        if: ${{ always() }}
        run: |
          echo "Cleaning up containers and volumes..."
          docker stop $(docker ps -aq --filter "ancestor=pgvector/pgvector:pg17") || true
          docker rm $(docker ps -aq --filter "ancestor=pgvector/pgvector:pg17") || true
          docker volume prune -f || true
          docker system prune -f || true
