name: AutoGPT Platform - Frontend CI

on:
  push:
    branches: [master, dev]
    paths:
      - ".github/workflows/platform-frontend-ci.yml"
      - "autogpt_platform/frontend/**"
  pull_request:
    paths:
      - ".github/workflows/platform-frontend-ci.yml"
      - "autogpt_platform/frontend/**"
  merge_group:
  workflow_dispatch:

concurrency:
  group: ${{ github.workflow }}-${{ github.event_name == 'merge_group' && format('merge-queue-{0}', github.ref) || format('{0}-{1}', github.ref, github.event.pull_request.number || github.sha) }}
  cancel-in-progress: ${{ github.event_name == 'pull_request' }}

defaults:
  run:
    shell: bash
    working-directory: autogpt_platform/frontend

jobs:
  setup:
    runs-on: ubuntu-latest
    outputs:
      cache-key: ${{ steps.cache-key.outputs.key }}
      components-changed: ${{ steps.filter.outputs.components }}

    steps:
      - name: Checkout repository
        uses: actions/checkout@v6

      - name: Check for component changes
        uses: dorny/paths-filter@v3
        id: filter
        with:
          filters: |
            components:
              - 'autogpt_platform/frontend/src/components/**'

      - name: Set up Node.js
        uses: actions/setup-node@v6
        with:
          node-version: "22.18.0"

      - name: Enable corepack
        run: corepack enable

      - name: Generate cache key
        id: cache-key
        run: echo "key=${{ runner.os }}-pnpm-${{ hashFiles('autogpt_platform/frontend/pnpm-lock.yaml', 'autogpt_platform/frontend/package.json') }}" >> $GITHUB_OUTPUT

      - name: Cache dependencies
        uses: actions/cache@v5
        with:
          path: ~/.pnpm-store
          key: ${{ steps.cache-key.outputs.key }}
          restore-keys: |
            ${{ runner.os }}-pnpm-${{ hashFiles('autogpt_platform/frontend/pnpm-lock.yaml') }}
            ${{ runner.os }}-pnpm-

      - name: Install dependencies
        run: pnpm install --frozen-lockfile

  lint:
    runs-on: ubuntu-latest
    needs: setup

    steps:
      - name: Checkout repository
        uses: actions/checkout@v6

      - name: Set up Node.js
        uses: actions/setup-node@v6
        with:
          node-version: "22.18.0"

      - name: Enable corepack
        run: corepack enable

      - name: Restore dependencies cache
        uses: actions/cache@v5
        with:
          path: ~/.pnpm-store
          key: ${{ needs.setup.outputs.cache-key }}
          restore-keys: |
            ${{ runner.os }}-pnpm-${{ hashFiles('autogpt_platform/frontend/pnpm-lock.yaml') }}
            ${{ runner.os }}-pnpm-

      - name: Install dependencies
        run: pnpm install --frozen-lockfile

      - name: Run lint
        run: pnpm lint

  chromatic:
    runs-on: ubuntu-latest
    needs: setup
    # Disabled: to re-enable, remove 'false &&' from the condition below
    if: >-
      false
      && (github.ref == 'refs/heads/dev' || github.base_ref == 'dev')
      && needs.setup.outputs.components-changed == 'true'

    steps:
      - name: Checkout repository
        uses: actions/checkout@v6
        with:
          fetch-depth: 0

      - name: Set up Node.js
        uses: actions/setup-node@v6
        with:
          node-version: "22.18.0"

      - name: Enable corepack
        run: corepack enable

      - name: Restore dependencies cache
        uses: actions/cache@v5
        with:
          path: ~/.pnpm-store
          key: ${{ needs.setup.outputs.cache-key }}
          restore-keys: |
            ${{ runner.os }}-pnpm-${{ hashFiles('autogpt_platform/frontend/pnpm-lock.yaml') }}
            ${{ runner.os }}-pnpm-

      - name: Install dependencies
        run: pnpm install --frozen-lockfile

      - name: Run Chromatic
        uses: chromaui/action@latest
        with:
          projectToken: chpt_9e7c1a76478c9c8
          onlyChanged: true
          workingDir: autogpt_platform/frontend
          token: ${{ secrets.GITHUB_TOKEN }}
          exitOnceUploaded: true

  e2e_test:
    runs-on: big-boi
    needs: setup
    strategy:
      fail-fast: false

    steps:
      - name: Checkout repository
        uses: actions/checkout@v6
        with:
          submodules: recursive

      - name: Set up Node.js
        uses: actions/setup-node@v6
        with:
          node-version: "22.18.0"

      - name: Enable corepack
        run: corepack enable

      - name: Copy default supabase .env
        run: |
          cp ../.env.default ../.env

      - name: Copy backend .env and set OpenAI API key
        run: |
          cp ../backend/.env.default ../backend/.env
          echo "OPENAI_INTERNAL_API_KEY=${{ secrets.OPENAI_API_KEY }}" >> ../backend/.env
        env:
          # Used by E2E test data script to generate embeddings for approved store agents
          OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Cache Docker layers
        uses: actions/cache@v5
        with:
          path: /tmp/.buildx-cache
          key: ${{ runner.os }}-buildx-frontend-test-${{ hashFiles('autogpt_platform/docker-compose.yml', 'autogpt_platform/backend/Dockerfile', 'autogpt_platform/backend/pyproject.toml', 'autogpt_platform/backend/poetry.lock') }}
          restore-keys: |
            ${{ runner.os }}-buildx-frontend-test-

      - name: Run docker compose
        run: |
          NEXT_PUBLIC_PW_TEST=true docker compose -f ../docker-compose.yml up -d
        env:
          DOCKER_BUILDKIT: 1
          BUILDX_CACHE_FROM: type=local,src=/tmp/.buildx-cache
          BUILDX_CACHE_TO: type=local,dest=/tmp/.buildx-cache-new,mode=max

      - name: Move cache
        run: |
          rm -rf /tmp/.buildx-cache
          if [ -d "/tmp/.buildx-cache-new" ]; then
            mv /tmp/.buildx-cache-new /tmp/.buildx-cache
          fi

      - name: Wait for services to be ready
        run: |
          echo "Waiting for rest_server to be ready..."
          timeout 60 sh -c 'until curl -f http://localhost:8006/health 2>/dev/null; do sleep 2; done' || echo "Rest server health check timeout, continuing..."
          echo "Waiting for database to be ready..."
          timeout 60 sh -c 'until docker compose -f ../docker-compose.yml exec -T db pg_isready -U postgres 2>/dev/null; do sleep 2; done' || echo "Database ready check timeout, continuing..."

      - name: Create E2E test data
        run: |
          echo "Creating E2E test data..."
          # First try to run the script from inside the container
          if docker compose -f ../docker-compose.yml exec -T rest_server test -f /app/autogpt_platform/backend/test/e2e_test_data.py; then
            echo "✅ Found e2e_test_data.py in container, running it..."
            docker compose -f ../docker-compose.yml exec -T rest_server sh -c "cd /app/autogpt_platform && python backend/test/e2e_test_data.py" || {
              echo "❌ E2E test data creation failed!"
              docker compose -f ../docker-compose.yml logs --tail=50 rest_server
              exit 1
            }
          else
            echo "⚠️ e2e_test_data.py not found in container, copying and running..."
            # Copy the script into the container and run it
            docker cp ../backend/test/e2e_test_data.py $(docker compose -f ../docker-compose.yml ps -q rest_server):/tmp/e2e_test_data.py || {
              echo "❌ Failed to copy script to container"
              exit 1
            }
            docker compose -f ../docker-compose.yml exec -T rest_server sh -c "cd /app/autogpt_platform && python /tmp/e2e_test_data.py" || {
              echo "❌ E2E test data creation failed!"
              docker compose -f ../docker-compose.yml logs --tail=50 rest_server
              exit 1
            }
          fi

      - name: Restore dependencies cache
        uses: actions/cache@v5
        with:
          path: ~/.pnpm-store
          key: ${{ needs.setup.outputs.cache-key }}
          restore-keys: |
            ${{ runner.os }}-pnpm-${{ hashFiles('autogpt_platform/frontend/pnpm-lock.yaml') }}
            ${{ runner.os }}-pnpm-

      - name: Install dependencies
        run: pnpm install --frozen-lockfile

      - name: Install Browser 'chromium'
        run: pnpm playwright install --with-deps chromium

      - name: Run Playwright tests
        run: pnpm test:no-build
        continue-on-error: false

      - name: Upload Playwright report
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: playwright-report
          path: playwright-report
          if-no-files-found: ignore
          retention-days: 3

      - name: Upload Playwright test results
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: playwright-test-results
          path: test-results
          if-no-files-found: ignore
          retention-days: 3

      - name: Print Final Docker Compose logs
        if: always()
        run: docker compose -f ../docker-compose.yml logs

  integration_test:
    runs-on: ubuntu-latest
    needs: setup

    steps:
      - name: Checkout repository
        uses: actions/checkout@v6
        with:
          submodules: recursive

      - name: Set up Node.js
        uses: actions/setup-node@v6
        with:
          node-version: "22.18.0"

      - name: Enable corepack
        run: corepack enable

      - name: Restore dependencies cache
        uses: actions/cache@v5
        with:
          path: ~/.pnpm-store
          key: ${{ needs.setup.outputs.cache-key }}
          restore-keys: |
            ${{ runner.os }}-pnpm-${{ hashFiles('autogpt_platform/frontend/pnpm-lock.yaml') }}
            ${{ runner.os }}-pnpm-

      - name: Install dependencies
        run: pnpm install --frozen-lockfile

      - name: Generate API client
        run: pnpm generate:api

      - name: Run Integration Tests
        run: pnpm test:unit
