From e5e58ed9320d3174f43910f83be39a0f4fe87fc1 Mon Sep 17 00:00:00 2001 From: Anso Date: Fri, 10 Apr 2026 13:47:07 -0400 Subject: [PATCH] ci: capture backend and frontend logs for E2E failures (#481) When an E2E test flakes in CI, the backend and frontend stdout is gone the moment the step exits. That makes a failed run extremely hard to triage: you get the Playwright report but nothing from the services underneath it. Redirect both dev servers to files under the workspace's ci-logs/ directory and include that directory in the failure-case artifact upload, so the report and the service logs travel together. Log files live under $GITHUB_WORKSPACE rather than /tmp because actions/upload-artifact@v4+ computes a common parent directory across all path entries. Mixing repo-relative paths with /tmp paths makes '/' the common root, which v4+ then strips from the artifact, silently dropping the absolute entries. Keeping everything under the workspace avoids that footgun. `stdbuf -oL -eL` forces line-buffered output on both services. Node stdout is block-buffered when redirected to a regular file, so a crash or abort can lose the final few hundred lines - exactly the output you need when debugging a CI failure. Also remove the duplicated `E2E_USERNAME: admin` / `E2E_PASSWORD: password123` env blocks from the e2e and update-screenshots jobs. Those values were already the fallback defaults in e2e/helpers.ts (`process.env.E2E_USERNAME ?? 'admin'`), so the env blocks were doing nothing on the default path and created two sources of truth for the same literals. e2e/helpers.ts remains the canonical source; callers that want to override the creds still set E2E_USERNAME / E2E_PASSWORD as job-level env. --- .github/actions/start-app/action.yml | 15 +++++++++++---- .github/workflows/ci.yml | 9 ++------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/.github/actions/start-app/action.yml b/.github/actions/start-app/action.yml index c5c2312d..2c26756c 100644 --- a/.github/actions/start-app/action.yml +++ b/.github/actions/start-app/action.yml @@ -47,13 +47,20 @@ runs: run: npm ci working-directory: ./frontend - - name: Create compose directory + - name: Create compose directory and log dir shell: bash - run: mkdir -p ${{ inputs.compose-dir }} + run: | + mkdir -p ${{ inputs.compose-dir }} + mkdir -p "${{ github.workspace }}/ci-logs" + # Log files live under $GITHUB_WORKSPACE so actions/upload-artifact@v4+ can + # include them alongside repo-relative paths like e2e/report/. Mixing those + # with /tmp paths makes '/' the common root and v4+ strips the absolute + # entries from the artifact. `stdbuf -oL -eL` forces line-buffered output + # so a crash doesn't lose the final few hundred lines to block buffering. - name: Start backend shell: bash - run: node dist/index.js & + run: stdbuf -oL -eL node dist/index.js > "${{ github.workspace }}/ci-logs/backend.log" 2>&1 & working-directory: ./backend env: JWT_SECRET: ${{ inputs.jwt-secret }} @@ -63,7 +70,7 @@ runs: - name: Start frontend dev server shell: bash - run: npm run dev & + run: stdbuf -oL -eL npm run dev > "${{ github.workspace }}/ci-logs/frontend.log" 2>&1 & working-directory: ./frontend - name: Wait for services to be ready diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5eff45ae..f6fa878a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -153,11 +153,8 @@ jobs: - name: Run E2E tests run: npx playwright test - env: - E2E_USERNAME: admin - E2E_PASSWORD: password123 - - name: Upload E2E report + - name: Upload E2E report and service logs if: failure() uses: actions/upload-artifact@v7 with: @@ -165,6 +162,7 @@ jobs: path: | e2e/report/ test-results/ + ci-logs/ retention-days: 7 # --------------------------------------------------------------------------- @@ -194,9 +192,6 @@ jobs: - name: Capture screenshots run: npx playwright test e2e/screenshots.spec.ts --project=chromium - env: - E2E_USERNAME: admin - E2E_PASSWORD: password123 - name: Open / update screenshots PR id: create-pr