From b27bc07f821d854a5ae7cdee5453fc8599ce3780 Mon Sep 17 00:00:00 2001 From: Anso Date: Fri, 10 Apr 2026 14:39:55 -0400 Subject: [PATCH] ci: reuse backend dist/ in E2E instead of rebuilding (#488) The backend CI job already runs `tsc` against backend/src/ and only marks the job green after build + tests + lint + audit all pass. The E2E job then checked out the same source and ran the same tsc again inside the start-app composite. Upload backend/dist/ as a 1-day retention artifact at the end of the backend job, download it in the E2E job before invoking the composite, and gate the composite's "Build backend" step on a new `skip-backend-build` input. The update-screenshots job (which also uses the composite but has no upstream backend job) leaves the input at its default of 'false' and continues to build from source. Savings are modest (~10-15s per E2E run, on top of what setup-node's ~/.npm cache already buys us) but the real win is the contract: the dist/ that E2E exercises is now byte-for-byte the same artifact that the backend job verified, eliminating a whole class of "works in backend job, breaks in E2E" drift. --- .github/actions/start-app/action.yml | 10 ++++++++++ .github/workflows/ci.yml | 23 +++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/.github/actions/start-app/action.yml b/.github/actions/start-app/action.yml index 2c26756c..6043d0d7 100644 --- a/.github/actions/start-app/action.yml +++ b/.github/actions/start-app/action.yml @@ -14,6 +14,15 @@ inputs: port: required: false default: '3000' + skip-backend-build: + description: > + When 'true', skip running `npm run build` in backend/ and assume the + caller has already materialized backend/dist (e.g. via download-artifact + from an upstream job that already built and verified it). Leave 'false' + for standalone invocations like the update-screenshots job that do not + run in a job graph with a prior build step. + required: false + default: 'false' runs: using: composite @@ -38,6 +47,7 @@ runs: working-directory: ./backend - name: Build backend + if: inputs.skip-backend-build != 'true' shell: bash run: npm run build working-directory: ./backend diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ec383971..e4c0848f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -68,6 +68,17 @@ jobs: working-directory: ./backend run: npm audit --audit-level=high + # Hand the freshly-verified dist/ to the E2E job so it does not have to + # re-run `tsc` on the same source. retention-days is the minimum; this + # artifact is only needed for the downstream e2e job in the same run. + - name: Upload backend dist + uses: actions/upload-artifact@v7 + with: + name: backend-dist + path: backend/dist + retention-days: 1 + if-no-files-found: error + frontend: name: Frontend (Build, Lint) runs-on: ubuntu-latest @@ -158,8 +169,20 @@ jobs: - name: Checkout Code uses: actions/checkout@v6 + # Reuse the dist/ that the `backend` job produced and verified, instead + # of running `tsc` a second time against the same source tree. The + # composite action's `skip-backend-build` input short-circuits its build + # step when this artifact is already in place. + - name: Download backend dist + uses: actions/download-artifact@v7 + with: + name: backend-dist + path: backend/dist + - name: Start app & install Playwright uses: ./.github/actions/start-app + with: + skip-backend-build: 'true' - name: Run E2E tests run: npx playwright test