name: preview-regression

permissions:
  contents: read

# Suppress hyperframes CLI telemetry from HeyGen's own CI runs.
# External users' CI continues to emit telemetry unless they set this themselves.
env:
  HYPERFRAMES_NO_TELEMETRY: "1"

on:
  pull_request:
  push:
    branches:
      - main

concurrency:
  group: preview-regression-${{ github.ref }}
  cancel-in-progress: true

jobs:
  changes:
    name: Detect changes
    runs-on: ubuntu-latest
    timeout-minutes: 2
    outputs:
      preview: ${{ steps.filter.outputs.preview }}
    steps:
      - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
        with:
          fetch-depth: 0
      - uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # v4
        id: filter
        with:
          token: ""
          filters: |
            preview:
              - "packages/core/**"
              - "packages/parsers/**"
              - "packages/studio-server/**"
              - "packages/lint/**"
              - "packages/player/**"
              - "packages/studio/**"
              - "packages/cli/**"
              - "packages/producer/src/parity-harness.ts"
              - "packages/producer/src/parity-fixtures.ts"
              - "packages/producer/tests/parity/**"
              - "package.json"
              - "bun.lock"
              - ".github/workflows/preview-regression.yml"

  preflight:
    name: Preflight (lint + format)
    needs: changes
    if: needs.changes.outputs.preview == 'true'
    runs-on: ubuntu-latest
    timeout-minutes: 5
    steps:
      - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
      - uses: ./.github/actions/preflight

  preview-parity:
    name: Preview parity
    needs: [changes, preflight]
    if: needs.changes.outputs.preview == 'true'
    runs-on: ubuntu-latest
    timeout-minutes: 20
    steps:
      - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4

      - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2

      - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
        with:
          node-version: 22

      - run: bun install --frozen-lockfile

      - name: Build workspace packages (required for vite config loading)
        run: |
          bun run --filter '@hyperframes/{parsers,lint,studio-server}' build
          bun run --cwd packages/core build

      - name: Run Studio preview routing regression
        run: |
          bun run --cwd packages/studio test -- vite.thumbnail.test.ts src/utils/projectRouting.test.ts src/utils/frameCapture.test.ts
          bun run --cwd packages/studio-server test -- src/routes/thumbnail.test.ts

      - name: Build preview runtime
        run: bun run --cwd packages/core build:hyperframes-runtime

      - name: Prepare parity fixtures
        run: bun run --cwd packages/producer parity:fixtures:ci

      - name: Install ffmpeg
        run: sudo apt-get update -qq && sudo apt-get install -y --no-install-recommends ffmpeg

      - name: Set up Chrome
        id: setup-chrome
        uses: browser-actions/setup-chrome@c785b87e244131f27c9f19c1a33e2ead956ab7ce # v1
        with:
          chrome-version: stable

      - name: Start parity fixture server
        run: |
          cd packages/producer/tests/parity/fixtures
          python3 -m http.server 4173 --bind 127.0.0.1 > /tmp/preview-parity-http.log 2>&1 &
          echo "$!" > /tmp/preview-parity-http.pid
          for _ in $(seq 1 30); do
            if curl -fsS http://127.0.0.1:4173/minimal-wysiwyg.html >/dev/null; then
              exit 0
            fi
            sleep 1
          done
          cat /tmp/preview-parity-http.log
          exit 1

      - name: Run preview parity check
        working-directory: packages/producer
        env:
          PUPPETEER_EXECUTABLE_PATH: ${{ steps.setup-chrome.outputs.chrome-path }}
        run: bun run parity:check:ci

      - name: Upload parity artifacts
        if: failure()
        uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
        with:
          name: preview-parity-artifacts
          path: packages/producer/.debug/parity-harness-ci/
          if-no-files-found: ignore
          retention-days: 30

  preview-regression:
    runs-on: ubuntu-latest
    needs: [changes, preview-parity]
    if: always()
    steps:
      - name: Check results
        env:
          PREVIEW_FILTER_RESULT: ${{ needs.changes.outputs.preview }}
          PREVIEW_PARITY_RESULT: ${{ needs.preview-parity.result }}
        run: |
          {
            echo "## Preview regression gate"
            echo ""
            echo "- paths-filter \`preview\` matched: \`${PREVIEW_FILTER_RESULT}\`"
            echo "- preview-parity result: \`${PREVIEW_PARITY_RESULT}\`"
            echo ""
          } >> "$GITHUB_STEP_SUMMARY"

          if [ "${PREVIEW_FILTER_RESULT}" != "true" ]; then
            echo "::notice title=Preview regression::SKIPPED — no preview/runtime changes. Auto-pass."
            echo "**Status:** SKIPPED (no preview/runtime changes — auto-pass)" >> "$GITHUB_STEP_SUMMARY"
            exit 0
          fi

          if [ "${PREVIEW_PARITY_RESULT}" != "success" ]; then
            echo "**Status:** FAILED" >> "$GITHUB_STEP_SUMMARY"
            echo "Preview parity check failed"
            exit 1
          fi

          echo "**Status:** PASSED" >> "$GITHUB_STEP_SUMMARY"
