From ba6c49c8e5bfa5003af9b7764eebb60c18b792fe Mon Sep 17 00:00:00 2001 From: Cristian Magherusan-Stanciu Date: Sun, 3 May 2026 13:32:41 +0200 Subject: [PATCH] ci: pre-merge frontend build gate (closes #191) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add .github/workflows/frontend-build.yml — a pull_request-triggered job that runs npm run typecheck (tsc --noEmit) and npm run build (webpack) for any PR targeting feat/multicloud-web-frontend or main that touches frontend/** or the workflow file itself. Rationale for pull_request vs pull_request_target: pull_request_target executes in the base-branch context with access to repository secrets, making it a fork-exfiltration vector. pull_request is safe for untrusted-code builds — it runs in the PR-head context with no secrets. Paths filter restricts the gate to PRs that actually touch the frontend, avoiding wasted CI minutes on Go/Terraform-only PRs (~60s/run). Node version and action versions (checkout@v5, setup-node@v6, Node 24) match the existing frontend-build-sentinel.yml so both jobs run in the same environment. Concurrency group cancels stale runs on force-push. This is a companion to frontend-build-sentinel.yml (#177), not a replacement — the sentinel guards the protected branch post-merge (defence-in-depth for rebase/UI-merge slip-throughs); this gate catches failures before merge. --- .github/workflows/frontend-build.yml | 64 ++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 .github/workflows/frontend-build.yml diff --git a/.github/workflows/frontend-build.yml b/.github/workflows/frontend-build.yml new file mode 100644 index 00000000..2a92e240 --- /dev/null +++ b/.github/workflows/frontend-build.yml @@ -0,0 +1,64 @@ +name: Frontend build (PR) + +# Pre-merge gate: catches TypeScript errors and webpack build failures +# BEFORE a PR is merged, not after. Motivated by the post-mortem in #191: +# a TS6133 error rode through to the protected branch and caused all three +# post-merge deploy jobs to fail after spending minutes on infrastructure +# only to hit the same tsc error inside the Dockerfile frontend-builder stage. +# +# Companion to frontend-build-sentinel.yml, which guards the protected +# branch post-merge against rebases and GitHub-UI merge commits. +# This job guards the PR gate itself — the earlier the catch, the cheaper. +# +# Uses pull_request (not pull_request_target) so this job runs in the +# PR-head context with no access to repository secrets. pull_request_target +# executes in the base-branch context WITH secrets, which is a known +# fork-exfiltration vector and must not be used for untrusted code builds. +# +# See also: #177 (sentinel), #191 (this PR gate). + +on: + pull_request: + branches: + - feat/multicloud-web-frontend + - main + paths: + - "frontend/**" + - ".github/workflows/frontend-build.yml" + +permissions: + contents: read + +concurrency: + # Cancel redundant runs when new commits are pushed to the same PR. + group: frontend-build-pr-${{ github.ref }} + cancel-in-progress: true + +jobs: + build: + name: Build frontend + runs-on: ubuntu-latest + timeout-minutes: 5 + defaults: + run: + working-directory: frontend + + steps: + - name: Checkout + uses: actions/checkout@v5 + + - name: Set up Node.js + uses: actions/setup-node@v6 + with: + node-version: "24" + cache: "npm" + cache-dependency-path: frontend/package-lock.json + + - name: Install dependencies + run: npm ci + + - name: TypeScript typecheck + run: npm run typecheck + + - name: Build + run: npm run build