name: CI

on:
  pull_request:
  push:
    branches: [main]

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

permissions:
  contents: read

jobs:
  ci:
    runs-on: ubuntu-latest
    timeout-minutes: 15
    steps:
      - uses: actions/checkout@v4

      - uses: oven-sh/setup-bun@v2
        with:
          bun-version: latest

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

      - name: Typecheck
        run: bun run typecheck

      - name: Lint
        run: bun run lint

      - name: Unit tests
        run: bun run test

      - name: Next.js route slug consistency
        # `next build` does NOT catch mismatched dynamic-segment names
        # (e.g. mixing [id] and [userId] under the same parent). This
        # script catches it statically before build, in milliseconds.
        # Skips with exit 2 on non-Next.js repos (treated as success here).
        run: |
          if [ -f scripts/check-route-slugs.mjs ]; then
            node scripts/check-route-slugs.mjs || code=$?
            if [ "${code:-0}" = "1" ]; then exit 1; fi
          fi

      - name: Build-script hygiene (no devDeps in deploy scripts)
        # Vercel/Docker strip devDependencies during install. Any binary
        # invoked from build/prebuild/postinstall MUST be in dependencies
        # or be a plain `node script.mjs` call. Catches the
        # "tsx: command not found / exited 127" class of bug.
        run: |
          if [ -f scripts/check-build-scripts.mjs ]; then
            node scripts/check-build-scripts.mjs || code=$?
            if [ "${code:-0}" = "1" ]; then exit 1; fi
          fi

      - name: Build
        run: bun run build

  security:
    runs-on: ubuntu-latest
    timeout-minutes: 10
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - uses: oven-sh/setup-bun@v2
        with:
          bun-version: latest

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

      - name: Audit dependencies
        run: bun audit --audit-level=high
        continue-on-error: false

      - name: Gitleaks (secret scan)
        uses: gitleaks/gitleaks-action@v2
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

  e2e:
    runs-on: ubuntu-latest
    timeout-minutes: 30
    if: github.event_name == 'pull_request' || github.ref == 'refs/heads/main'
    steps:
      - uses: actions/checkout@v4

      - uses: oven-sh/setup-bun@v2
        with:
          bun-version: latest

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

      - name: Install Playwright browsers
        run: bunx playwright install --with-deps chromium

      - name: Run Playwright tests
        run: bunx playwright test

      - uses: actions/upload-artifact@v4
        if: failure()
        with:
          name: playwright-report
          path: playwright-report/
          retention-days: 14
