name: E2E Tests on: push: branches: [main] paths: - "apps/backend/**" - "apps/web/**" - "apps/packages/**" - "apps/pnpm-lock.yaml" - ".github/workflows/e2e-tests.yml" - "!**/*.md" pull_request: branches: [main] paths: - "apps/backend/**" - "apps/web/**" - "apps/packages/**" - "apps/pnpm-lock.yaml" - ".github/workflows/e2e-tests.yml" - "!**/*.md" concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true permissions: contents: read jobs: build: name: Build runs-on: ubuntu-latest timeout-minutes: 10 steps: - name: Checkout code uses: actions/checkout@v4 - name: Set up Go uses: actions/setup-go@v5 with: go-version-file: apps/backend/go.mod cache-dependency-path: apps/backend/go.sum - name: Set up pnpm uses: pnpm/action-setup@v4 with: version: "9" - name: Set up Node.js uses: actions/setup-node@v6 with: node-version: "24" - name: Install dependencies working-directory: apps run: pnpm install --frozen-lockfile - name: Build backend and web run: make build-backend build-web - name: Upload backend build uses: actions/upload-artifact@v4 with: name: e2e-backend-build path: apps/backend/bin/ retention-days: 1 # Tar the .next directory to preserve pnpm symlinks in the standalone build. # upload-artifact dereferences symlinks which breaks the Node.js module resolution. - name: Package web build run: tar -cf apps/web/next-build.tar -C apps/web .next - name: Upload web build uses: actions/upload-artifact@v4 with: name: e2e-web-build path: apps/web/next-build.tar retention-days: 1 e2e: name: E2E Shard ${{ matrix.shard }}/10 needs: build runs-on: ubuntu-latest timeout-minutes: 10 strategy: fail-fast: false matrix: shard: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] steps: - name: Checkout code uses: actions/checkout@v4 - name: Set up pnpm uses: pnpm/action-setup@v4 with: version: "9" - name: Set up Node.js uses: actions/setup-node@v6 with: node-version: "24" - name: Install dependencies working-directory: apps run: pnpm install --frozen-lockfile - name: Install Playwright browsers working-directory: apps/web run: npx playwright install chromium --with-deps - name: Download backend build uses: actions/download-artifact@v4 with: name: e2e-backend-build path: apps/backend/bin/ - name: Make backend binaries executable run: chmod +x apps/backend/bin/* - name: Download web build uses: actions/download-artifact@v4 with: name: e2e-web-build path: apps/web/ - name: Extract web build working-directory: apps/web run: tar -xf next-build.tar && rm next-build.tar - name: Run E2E tests (shard ${{ matrix.shard }}/10) working-directory: apps/web run: npx playwright test --config e2e/playwright.config.ts --shard=${{ matrix.shard }}/10 - name: Upload blob report if: always() uses: actions/upload-artifact@v4 with: name: blob-report-${{ matrix.shard }} path: apps/web/e2e/blob-report/ retention-days: 3 - name: Upload test results if: failure() uses: actions/upload-artifact@v4 with: name: test-results-${{ matrix.shard }} path: apps/web/e2e/test-results/ retention-days: 7 e2e-report: name: Merge E2E Reports needs: e2e if: always() runs-on: ubuntu-latest timeout-minutes: 5 steps: - name: Checkout code uses: actions/checkout@v4 - name: Set up pnpm uses: pnpm/action-setup@v4 with: version: "9" - name: Set up Node.js uses: actions/setup-node@v6 with: node-version: "24" - name: Install dependencies working-directory: apps run: pnpm install --frozen-lockfile - name: Download blob reports uses: actions/download-artifact@v4 with: path: apps/web/e2e/blob-reports pattern: blob-report-* merge-multiple: true - name: Merge reports working-directory: apps/web run: npx playwright merge-reports --reporter=html ./e2e/blob-reports - name: Upload merged report uses: actions/upload-artifact@v4 with: name: playwright-report path: apps/web/playwright-report/ retention-days: 14