From a2a3837c2b70d9eadd926555f8c7654a851f52d8 Mon Sep 17 00:00:00 2001 From: Derek Lewis Date: Sat, 15 Aug 2026 19:11:08 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=8B=F0=9F=94=A7=EF=BC=9Ainstall=20pnpm?= =?UTF-8?q?=20without=20corepack?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Node is unbundling corepack, and pnpm no longer needs it: since pnpm 11 the `pmOnFail` setting defaults to `download`, which reads `packageManager` and fetches that version itself. Verified in the container -- the feature installs 11.17.0, and running it here reports 11.20.0. The container loses two lines and gains nothing: the pnpm feature already installs a real pnpm, into a directory not tied to a node version, so `nvm use` cannot lose it the way it could lose a corepack shim. The workflows install the version `packageManager` names rather than the newest, which saves fetching pnpm twice. One consequence had to be dealt with: corepack kept its copy of pnpm outside the project, and self-management writes one into `.pnpm-store/`, where four checks then read someone else's changelog. The store is excluded now -- in the glob helper, and in the three tools that find their own files rather than being handed a list. Signed-off-by: Derek Lewis Assisted-by: Claude-Code:claude-opus-5 --- .devcontainer/post-create.sh | 8 ++++---- .github/workflows/deploy.yml | 9 +++++---- .github/workflows/lint-and-test.yml | 9 +++++---- .markdownlint-cli2.jsonc | 3 +++ .remarkignore | 4 ++++ build/utils.mts | 15 +++++++++++---- cspell.json | 7 ++++++- 7 files changed, 38 insertions(+), 17 deletions(-) diff --git a/.devcontainer/post-create.sh b/.devcontainer/post-create.sh index 950a0c527..8917be9fe 100755 --- a/.devcontainer/post-create.sh +++ b/.devcontainer/post-create.sh @@ -84,10 +84,10 @@ fi echo "==> Dependencies" -# Corepack prompts before fetching the pinned pnpm, which fails where there is -# no terminal to answer it. -export COREPACK_ENABLE_DOWNLOAD_PROMPT=0 -corepack enable +# No corepack: node is unbundling it, and pnpm does the job it was here for. +# The pnpm feature installs whatever is current, and pnpm reads +# `packageManager` and fetches that version itself -- which since pnpm 11 is +# what `pmOnFail: download` does by default. pnpm install # ------------------------------------------------------------------------------ diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 56b19d99e..6400155e4 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -31,10 +31,11 @@ jobs: node-version-file: 'package.json' - name: Install run: | - # Corepack prompts before fetching the pinned pnpm, and there is - # no terminal here to answer it. packageManager names the version. - export COREPACK_ENABLE_DOWNLOAD_PROMPT=0 - corepack enable + # No corepack: node is unbundling it, and pnpm reads + # `packageManager` and fetches that version itself. Installing the + # named one rather than the newest saves fetching pnpm twice. + npm install --global "pnpm@$(node -p "require('./package.json').packageManager.replace('pnpm@','').split('+')[0]")" + pnpm --version pnpm install echo "$(pwd)/node_modules/.bin" >> $GITHUB_PATH - name: Build diff --git a/.github/workflows/lint-and-test.yml b/.github/workflows/lint-and-test.yml index 6035cdb6b..4bb6bcffe 100644 --- a/.github/workflows/lint-and-test.yml +++ b/.github/workflows/lint-and-test.yml @@ -20,10 +20,11 @@ jobs: node-version-file: 'package.json' - name: Install run: | - # Corepack prompts before fetching the pinned pnpm, and there is - # no terminal here to answer it. packageManager names the version. - export COREPACK_ENABLE_DOWNLOAD_PROMPT=0 - corepack enable + # No corepack: node is unbundling it, and pnpm reads + # `packageManager` and fetches that version itself. Installing the + # named one rather than the newest saves fetching pnpm twice. + npm install --global "pnpm@$(node -p "require('./package.json').packageManager.replace('pnpm@','').split('+')[0]")" + pnpm --version pnpm install echo "$(pwd)/node_modules/.bin" >> $GITHUB_PATH - name: Build diff --git a/.markdownlint-cli2.jsonc b/.markdownlint-cli2.jsonc index fb1ede38a..25ac8112a 100644 --- a/.markdownlint-cli2.jsonc +++ b/.markdownlint-cli2.jsonc @@ -9,6 +9,9 @@ "ignores": [ "_site/", "node_modules/", + // The package store, which lives in the project because hard links + // cannot cross a filesystem. It holds other people's files. + ".pnpm-store/", "**/COPYING.md", // Generated by compile.siteifyHealthFiles from OpenINF/.github; // fixes here are overwritten on the next build. diff --git a/.remarkignore b/.remarkignore index b05f24825..2765093f1 100644 --- a/.remarkignore +++ b/.remarkignore @@ -14,3 +14,7 @@ collections/_pages/vision.md # Placeholder posts. The prose is Latin filler, so the natural-language # rules have nothing useful to say about it. collections/_posts/*lorem-ipsum*.md + +# The package store, which lives in the project because hard links cannot +# cross a filesystem. It holds other people's files. +.pnpm-store/ diff --git a/build/utils.mts b/build/utils.mts index 481c41db7..d8dc117ce 100644 --- a/build/utils.mts +++ b/build/utils.mts @@ -76,10 +76,17 @@ const expandDotPattern = (pattern: string) => { */ export async function glob(patterns: string | string[]) { const include = []; - // Matching dot names is what puts `.git/` in reach of a plain `**`, and no - // task has any business reading it. Excluded directories are pruned whole, - // dot entries included, so callers need not widen their own exclusions. - const exclude = ['.git/**']; + // Matching dot names is what puts these in reach of a plain `**`, and no + // task has any business reading either. Excluded directories are pruned + // whole, dot entries included, so callers need not widen their own + // exclusions. + // + // `.pnpm-store/` is the package store, which lives in the project because + // the home directory is on another filesystem and hard links cannot cross + // one. It holds other people's files, including the copy of pnpm that + // `packageManager` asks for, so a check that reads it is checking the + // registry rather than this repository. + const exclude = ['.git/**', '.pnpm-store/**']; for (const pattern of [patterns].flat()) { if (pattern.startsWith('!')) { diff --git a/cspell.json b/cspell.json index 0b2ef0055..c22c4a251 100644 --- a/cspell.json +++ b/cspell.json @@ -8,5 +8,10 @@ "path": "./project-terms.txt" } ], - "ignorePaths": ["_site/**", "node_modules/**", "**/COPYING.md"] + "ignorePaths": [ + "_site/**", + "node_modules/**", + ".pnpm-store/**", + "**/COPYING.md" + ] }