Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions .github/workflows/validate-packages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -137,3 +137,31 @@ jobs:
exit 1
fi
echo "directory.json is in sync with the package manifests"

# The security overrides only work if pnpm actually reads them. pnpm 11
# ignores a `pnpm` field in package.json outright and SILENTLY, so an
# override block that drifts back there would leave the repo looking
# patched while shipping vulnerable transitive deps. Fail loudly instead.
- name: Check pnpm overrides are where pnpm reads them
shell: bash
run: |
set -euo pipefail
if node -e "process.exit(require('./package.json').pnpm ? 0 : 1)"; then
echo "::error::package.json has a 'pnpm' field. pnpm 11 ignores it silently — move these settings to pnpm-workspace.yaml."
exit 1
fi
if ! grep -q '^overrides:' pnpm-workspace.yaml; then
echo "::error::pnpm-workspace.yaml has no overrides block — the transitive security patches are missing."
exit 1
fi
# Every override must actually appear in the resolved lockfile.
missing=0
while read -r pkg; do
[ -z "$pkg" ] && continue
if ! grep -qE "^ '?${pkg}'?:" pnpm-lock.yaml; then
echo "::error::override '${pkg}' is not recorded in pnpm-lock.yaml — it is not taking effect."
missing=1
fi
done < <(sed -n '/^overrides:/,$p' pnpm-workspace.yaml | tail -n +2 | sed -n 's/^ "\{0,1\}\([^":]*\)"\{0,1\}:.*/\1/p')
[ "$missing" -eq 0 ] || exit 1
echo "pnpm overrides live in pnpm-workspace.yaml and are all present in the lockfile"
17 changes: 1 addition & 16 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,20 +55,5 @@
"node": ">=24",
"pnpm": ">=10"
},
"packageManager": "pnpm@10.33.0",
"//pnpm-overrides": "Security patches for transitive dependencies. Each range is pinned to the SAME major as the version Astro's tree already resolves \u2014 a bare '>=' pulls in the next major (js-yaml 5, undici 8, fast-uri 4, svgo 4) and breaks the build. esbuild is deliberately NOT overridden: the only open advisory (GHSA, low) is an arbitrary file read in esbuild's dev server on Windows, which this repo never runs \u2014 it builds a static site in CI \u2014 and forcing >=0.28.1 breaks @astrojs/vue. Revisit all of these when Astro is upgraded; several may become unnecessary.",
"pnpm": {
"overrides": {
"@babel/core": "^7.29.6",
"fast-uri": "~3.1.4",
"js-yaml": "^4.3.0",
"postcss": "^8.5.18",
"sharp": "^0.35.3",
"svgo": "^3.3.4",
"tar": "^7.5.18",
"undici": "^7.28.0",
"vite": "^6.4.3",
"yaml": "^2.8.3"
}
}
"packageManager": "pnpm@10.33.0"
}
28 changes: 28 additions & 0 deletions pnpm-workspace.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# pnpm reads its settings from THIS file, not from a `pnpm` field in
# package.json. Since pnpm 11 the package.json field is ignored outright — and
# silently, with no warning — so overrides defined there become inert while the
# repo still looks patched. These are security patches for transitive
# dependencies, so they live here where both pnpm 10 and 11 honour them.
#
# Each range is pinned to the SAME major the tree already resolves: a bare
# ">=" pulls the next major (js-yaml 5, undici 8, fast-uri 4, svgo 4) and
# breaks the build. esbuild is deliberately absent — its only advisory is a low
# severity dev-server file read on Windows, which this repo never runs, and
# forcing >=0.28.1 breaks @astrojs/vue.
#
# Revisit when Astro is upgraded; several may become unnecessary.

packages:
- .

overrides:
"@babel/core": "^7.29.6"
fast-uri: "~3.1.4"
js-yaml: "^4.3.0"
postcss: "^8.5.18"
sharp: "^0.35.3"
svgo: "^3.3.4"
tar: "^7.5.18"
undici: "^7.28.0"
vite: "^6.4.3"
yaml: "^2.8.3"
Loading