From f3001159f91beed9ca4c5d779b6ba3761e1742be Mon Sep 17 00:00:00 2001 From: Daniel Han Date: Wed, 10 Jun 2026 06:10:16 -0700 Subject: [PATCH] Frontend CI: hard-fail unreviewed npm install scripts (#6139) Completes the allowScripts rollout: upgrade CI npm to the 11.x line (node 22 bundles 10.x, which predates the gate) with a loud version guard so the flag can never silently degrade into a warning, then run npm ci --strict-allow-scripts. A dependency that introduces install scripts not covered by the committed policy now fails the job with npm's approve-scripts/deny-scripts instructions; the pre-commit sync hook keeps existing pins fresh after bumps. --- .github/workflows/studio-frontend-ci.yml | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/.github/workflows/studio-frontend-ci.yml b/.github/workflows/studio-frontend-ci.yml index 3abfea8450..b42086f191 100644 --- a/.github/workflows/studio-frontend-ci.yml +++ b/.github/workflows/studio-frontend-ci.yml @@ -62,6 +62,19 @@ jobs: with: node-version: '22' + # node 22 bundles npm 10.x, which predates allowScripts. Move to the + # 11.x line and fail loudly if the gate is still missing, so the + # strict flag below can never silently degrade into a warning. + - name: Upgrade npm to 11.x (allowScripts enforcement) + working-directory: ${{ github.workspace }} + run: | + npm install -g npm@^11 --no-fund --no-audit + V=$(npm -v) + case "$V" in + 11.1[6-9].*|11.[2-9][0-9].*|1[2-9].*) echo "npm $V has allowScripts" ;; + *) echo "::error::npm $V lacks allowScripts (need >=11.16)"; exit 1 ;; + esac + # Run the structural lockfile scan BEFORE npm ci. A compromised # tarball runs its `prepare` / `postinstall` during `npm ci`, # so any catch has to fire upstream of that. The scanner is @@ -84,7 +97,9 @@ jobs: # covered by `allowScripts` in package.json (npm >=11.16, default in # npm 12). The pre-install lockfile audit above stays the first line # of defence -- it fires before any tarball can run code. - run: npm ci --no-fund --no-audit + # --strict-allow-scripts: any unreviewed install script hard-fails + # the job; the sync hook keeps the pins fresh after bumps. + run: npm ci --strict-allow-scripts --no-fund --no-audit - name: npm ci must not have modified the working tree working-directory: ${{ github.workspace }}