name: Selfhosted Studio E2E Tests on: push: branches: [master] pull_request: # Cancel old builds on new commit for same workflow + branch/PR concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: true jobs: test: name: 'E2E tests' timeout-minutes: 60 runs-on: blacksmith-8vcpu-ubuntu-2404 strategy: fail-fast: false matrix: framework: [next, tanstack] shardIndex: [1, 2] shardTotal: [2] outputs: tests_ran: ${{ steps.filter.outputs.studio == 'true' }} permissions: contents: read id-token: write env: OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} # Consumed by `apps/studio/scripts/dispatch.js` to pick which framework # build/start scripts run. `next` keeps the existing pages-router flow; # `tanstack` exercises the Vite/TanStack-Start migration in parallel # so we catch regressions on either side per-PR. STUDIO_FRAMEWORK: ${{ matrix.framework }} steps: - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false # On push events paths-filter diffs against github.event.before with # local git; without enough history it falls back to a git fetch that # fails unauthenticated (persist-credentials is false). fetch-depth: 50 - uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2 id: filter with: filters: | studio: - 'packages/pg-meta/**' - 'packages/ui/**' - 'packages/ui-patterns/**' - 'apps/studio/**' - 'apps/ui-library/**' - 'apps/design-system/**' - 'e2e/studio/**' - 'pnpm-lock.yaml' - '.github/workflows/studio-e2e-test.yml' - uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 if: steps.filter.outputs.studio == 'true' name: Install pnpm with: run_install: false - name: Use Node.js if: steps.filter.outputs.studio == 'true' uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: node-version-file: '.nvmrc' cache: 'pnpm' - name: Install dependencies if: steps.filter.outputs.studio == 'true' run: pnpm install --frozen-lockfile - name: Install Playwright Browsers if: steps.filter.outputs.studio == 'true' run: pnpm -C e2e/studio exec playwright install chromium --with-deps --only-shell - name: Set up NextJS/Turbo cache if: steps.filter.outputs.studio == 'true' uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: # See here for caching with `yarn`, `bun` or other package managers https://github.com/actions/cache/blob/main/examples.md or you can leverage caching with actions/setup-node https://github.com/actions/setup-node path: | apps/studio/.next/build apps/studio/.next/cache # Generate a new cache whenever packages or source files change. key: ${{ runner.os }}-nextjs-${{ hashFiles('pnpm-lock.yaml') }}-${{ hashFiles('apps/studio/**/*.js', 'apps/studio/**/*.jsx', 'apps/studio/**/*.ts', 'apps/studio/**/*.tsx') }} # If source files changed but packages didn't, rebuild from a prior cache. restore-keys: | ${{ runner.os }}-nextjs-${{ hashFiles('pnpm-lock.yaml') }}- # Authenticate with AWS ECR to avoid rate limiting - name: configure aws credentials if: steps.filter.outputs.studio == 'true' && !github.event.pull_request.head.repo.fork uses: aws-actions/configure-aws-credentials@5fd3084fc36e372ff1fff382a39b10d03659f355 # v2.2.0 with: role-to-assume: ${{ secrets.PROD_AWS_ROLE }} aws-region: us-east-1 - uses: docker/login-action@af1e73f918a031802d376d3c8bbc3fe56130a9b0 # v4.4.0 if: steps.filter.outputs.studio == 'true' && !github.event.pull_request.head.repo.fork with: registry: public.ecr.aws - name: Pre-start diagnostics run: | docker ps -a sudo ss -tlnp | grep 54322 || echo "54322 free" - name: Start supabase if: steps.filter.outputs.studio == 'true' run: SKIP_ASSET_UPLOAD=1 pnpm run e2e:setup:cli - name: Failure diagnostics if: failure() run: | docker ps -a sudo ss -tlnp | grep 54322 || echo "54322 not listening" docker logs $(docker ps -aq) 2>&1 || true - name: Build studio if: steps.filter.outputs.studio == 'true' # `MODE=test` so the Vite build (TanStack) loads `.env.test` for env # resolution; Next ignores it but reads `NODE_ENV=test` for the same # purpose. Vite's `vite.config.ts` overrides the bundle NODE_ENV to # 'production' regardless of input, mirroring Next's build behaviour # so vitest-only constants (e.g. `API_URL`) don't bleed in here. run: SKIP_ASSET_UPLOAD=1 NODE_ENV=test MODE=test NODE_OPTIONS="--max-old-space-size=4096" pnpm run build:studio - name: 🚀 Run Playwright tests against local studio build if: steps.filter.outputs.studio == 'true' id: playwright run: PWTEST_SHARD_WEIGHTS=62:38 pnpm e2e --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }} - name: Upload blob report to GitHub Actions Artifacts if: always() && steps.filter.outputs.studio == 'true' uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: blob-report-${{ matrix.framework }}-${{ matrix.shardIndex }} path: e2e/studio/blob-report retention-days: 7 - name: Fail job if tests failed if: steps.filter.outputs.studio == 'true' && steps.playwright.outcome != 'success' run: | echo "E2E tests failed" >&2 exit 1 merge-reports: name: 'E2E reports (${{ matrix.framework }})' # Merge reports after playwright-tests, even if some shards have failed if: ${{ !cancelled() && needs.test.outputs.tests_ran == 'true' }} needs: [test] runs-on: blacksmith-4vcpu-ubuntu-2404 strategy: fail-fast: false matrix: framework: [next, tanstack] permissions: contents: write pull-requests: write steps: - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false - name: Use Node.js uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: node-version-file: '.nvmrc' - name: Download blob reports from GitHub Actions Artifacts uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v 5.0.0 with: path: e2e/studio/blob-report pattern: blob-report-${{ matrix.framework }}-* merge-multiple: true - name: Merge Playwright reports run: npx playwright merge-reports --config=e2e/studio/playwright.merge.config.ts -- e2e/studio/blob-report - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: playwright-artifacts-${{ matrix.framework }} path: | e2e/studio/playwright-report/ e2e/studio/test-results/ retention-days: 7 - name: Comment Playwright test results on PR if: always() && github.event_name == 'pull_request' && !github.event.pull_request.head.repo.fork uses: daun/playwright-report-comment@be9e270edd5ad86038604d3caa84a819a6ff6fed # v3.10.0 with: report-file: e2e/studio/test-results/test-results.json comment-title: '🎭 Playwright Test Results (${{ matrix.framework }})' merge-results: name: 'E2E results' runs-on: ubuntu-latest permissions: {} needs: [test] if: ${{ !cancelled() && needs.test.outputs.tests_ran == 'true' }} steps: - name: All tests ok if: ${{ !(contains(needs.*.result, 'failure')) }} run: exit 0 - name: Some tests failed if: ${{ contains(needs.*.result, 'failure') }} run: exit 1