Skip to content

Commit 563d6aa

Browse files
committed
fix(ci): pin scanner versions and disable install lifecycle scripts
SonarCloud's gate on main has been red since 2026-08-21 on new_security_rating (C, threshold A) from four MAJOR supply-chain findings that its new-code window sweeps in: - release.yml and scripts/release.sh ran `npm ci` with dependency lifecycle scripts enabled during a release build (S6505) - security.yml installed pip and semgrep unpinned (S8544) - security.yml resolved jscpd on demand through `npx --yes` (S6505) Add --ignore-scripts to both release installs, pin pip/semgrep to exact versions, and install jscpd at an exact version with lifecycle scripts disabled before invoking it with --no-install. Verified locally: the vite build produces identical output under npm ci --ignore-scripts, and the rewritten jscpd invocation reports the same 3 pre-existing clones and exits 0.
1 parent db7ac81 commit 563d6aa

3 files changed

Lines changed: 14 additions & 5 deletions

File tree

.github/workflows/release.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,9 @@ jobs:
8080
# goreleaser compiles. `npm run build` emits into internal/ui/dist.
8181
run: |
8282
cd ui
83-
npm ci
83+
# --ignore-scripts: no dependency lifecycle script runs during a
84+
# release install. Verified the vite build needs none.
85+
npm ci --ignore-scripts
8486
npm run build
8587
test -f ../internal/ui/dist/index.html
8688
# vite's emptyOutDir wipes internal/ui/dist on rebuild, deleting the

.github/workflows/security.yml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,9 @@ jobs:
9090
with:
9191
python-version: '3.12'
9292
- name: Install semgrep
93-
run: python -m pip install --quiet --upgrade pip semgrep
93+
# Pinned: a scanner that silently changes version changes the
94+
# merge gate under everyone without a commit saying so.
95+
run: python -m pip install --quiet "pip==26.2.1" "semgrep==1.174.0"
9496
- name: Run semgrep (security-audit + owasp-top-ten + golang)
9597
run: |
9698
semgrep scan \
@@ -151,7 +153,10 @@ jobs:
151153
# function body is ~40-80 tokens; 100 corresponds to a real
152154
# method body or a non-trivial code block, not import/struct
153155
# boilerplate that 200+ Go files share by convention.
154-
npx --yes jscpd@4 \
156+
# Installed with lifecycle scripts disabled and an exact version
157+
# rather than resolved on demand by npx.
158+
npm install --no-save --ignore-scripts jscpd@4.3.0
159+
npx --no-install jscpd \
155160
--threshold 3 \
156161
--min-tokens 100 \
157162
--reporters consoleFull \

scripts/release.sh

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,10 @@ cleanup() { git reset --hard --quiet "$base"; git clean -fdq -- internal/ui/dist
6262
trap cleanup EXIT
6363

6464
# --- Build the UI ------------------------------------------------------------
65-
echo "▸ building UI (npm ci && npm run build)…"
66-
( cd ui && npm ci && npm run build )
65+
echo "▸ building UI (npm ci --ignore-scripts && npm run build)…"
66+
# --ignore-scripts: no dependency lifecycle script runs during a release
67+
# install. Verified the vite build needs none.
68+
( cd ui && npm ci --ignore-scripts && npm run build )
6769
[ -f internal/ui/dist/index.html ] || { echo "error: UI build produced no dist/index.html" >&2; exit 1; }
6870
touch internal/ui/dist/.gitkeep # vite emptyOutDir wipes it; keep the placeholder
6971

0 commit comments

Comments
 (0)