From 3d5712b822cbefd4b5331a4111fc9e2dd4c439a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20Gaud=C3=AAncio?= Date: Thu, 23 Jul 2026 18:31:34 +0200 Subject: [PATCH 01/10] deps: pin pnpm to 10.34.3 for minimumReleaseAge enforcement * update pnpm@10 to pnpm@10.34.3 in Dockerfiles to match packageManager * bump documented pnpm requirement in AGENTS.md to 10.16.0+ (minimum for minimumReleaseAge) --- AGENTS.md | 2 +- Dockerfile | 2 +- Dockerfile.rootless | 2 +- docker/forkana/Dockerfile | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 8838e97858..8fcf26dd6d 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -10,7 +10,7 @@ Forkana is a fork of Gitea (self-hosted git service) that's been repurposed to a - **Go**: 1.25.1+ (see https://go.dev/doc/manage-install) - **Node.js**: 22.6.0+ -- **pnpm**: 10.0.0+ +- **pnpm**: 10.16.0+ (required for `minimumReleaseAge` dependency age gating) - **git-lfs**: Required for binary assets - **Make**: Build system diff --git a/Dockerfile b/Dockerfile index 5df346f02b..0e18fa0dda 100644 --- a/Dockerfile +++ b/Dockerfile @@ -19,7 +19,7 @@ RUN apk --no-cache add \ git \ nodejs \ npm \ - && npm install -g pnpm@10 \ + && npm install -g pnpm@10.34.3 \ && rm -rf /var/cache/apk/* # Setup repo diff --git a/Dockerfile.rootless b/Dockerfile.rootless index 315bb77b86..d9bf14b4ab 100644 --- a/Dockerfile.rootless +++ b/Dockerfile.rootless @@ -19,7 +19,7 @@ RUN apk --no-cache add \ git \ nodejs \ npm \ - && npm install -g pnpm@10 \ + && npm install -g pnpm@10.34.3 \ && rm -rf /var/cache/apk/* # Setup repo diff --git a/docker/forkana/Dockerfile b/docker/forkana/Dockerfile index 53b94753aa..7ca1d956d0 100644 --- a/docker/forkana/Dockerfile +++ b/docker/forkana/Dockerfile @@ -18,7 +18,7 @@ RUN apk --no-cache add \ git \ nodejs \ npm \ - && npm install -g pnpm@10 \ + && npm install -g pnpm@10.34.3 \ && rm -rf /var/cache/apk/* # Setup repo From 62a8e074cef87265d9a32467194d11f6957613cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20Gaud=C3=AAncio?= Date: Fri, 24 Jul 2026 20:54:57 +0200 Subject: [PATCH 02/10] docker: use corepack-managed pnpm in build images * remove duplicated hardcoded pnpm version from 3 Dockerfiles * keep package.json as the single pnpm version source * preserve npm in Alpine build deps for Corepack bootstrap --- Dockerfile | 2 +- Dockerfile.rootless | 2 +- docker/forkana/Dockerfile | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index 0e18fa0dda..9cc86f31dc 100644 --- a/Dockerfile +++ b/Dockerfile @@ -19,7 +19,7 @@ RUN apk --no-cache add \ git \ nodejs \ npm \ - && npm install -g pnpm@10.34.3 \ + && corepack enable \ && rm -rf /var/cache/apk/* # Setup repo diff --git a/Dockerfile.rootless b/Dockerfile.rootless index d9bf14b4ab..2e2f3ed852 100644 --- a/Dockerfile.rootless +++ b/Dockerfile.rootless @@ -19,7 +19,7 @@ RUN apk --no-cache add \ git \ nodejs \ npm \ - && npm install -g pnpm@10.34.3 \ + && corepack enable \ && rm -rf /var/cache/apk/* # Setup repo diff --git a/docker/forkana/Dockerfile b/docker/forkana/Dockerfile index 7ca1d956d0..9c260d5fda 100644 --- a/docker/forkana/Dockerfile +++ b/docker/forkana/Dockerfile @@ -18,7 +18,7 @@ RUN apk --no-cache add \ git \ nodejs \ npm \ - && npm install -g pnpm@10.34.3 \ + && corepack enable \ && rm -rf /var/cache/apk/* # Setup repo From ecb93744703362075d413c54cee7bf40064b6d31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20Gaud=C3=AAncio?= Date: Fri, 24 Jul 2026 22:32:04 +0200 Subject: [PATCH 03/10] docker: undo corepack pnpm usage from build images --- Dockerfile | 2 +- Dockerfile.rootless | 2 +- docker/forkana/Dockerfile | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index 9cc86f31dc..0e18fa0dda 100644 --- a/Dockerfile +++ b/Dockerfile @@ -19,7 +19,7 @@ RUN apk --no-cache add \ git \ nodejs \ npm \ - && corepack enable \ + && npm install -g pnpm@10.34.3 \ && rm -rf /var/cache/apk/* # Setup repo diff --git a/Dockerfile.rootless b/Dockerfile.rootless index 2e2f3ed852..d9bf14b4ab 100644 --- a/Dockerfile.rootless +++ b/Dockerfile.rootless @@ -19,7 +19,7 @@ RUN apk --no-cache add \ git \ nodejs \ npm \ - && corepack enable \ + && npm install -g pnpm@10.34.3 \ && rm -rf /var/cache/apk/* # Setup repo diff --git a/docker/forkana/Dockerfile b/docker/forkana/Dockerfile index 9c260d5fda..7ca1d956d0 100644 --- a/docker/forkana/Dockerfile +++ b/docker/forkana/Dockerfile @@ -18,7 +18,7 @@ RUN apk --no-cache add \ git \ nodejs \ npm \ - && corepack enable \ + && npm install -g pnpm@10.34.3 \ && rm -rf /var/cache/apk/* # Setup repo From c1cab3a9552b54cd09b4fa26ae34f9b50d0650bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20Gaud=C3=AAncio?= Date: Sun, 26 Jul 2026 19:59:54 +0200 Subject: [PATCH 04/10] deps: align .npmrc with pnpm usage and security policy * added header comment clarifying that pnpm manages project dependencies. * added minimum-release-age=20160 to enforce 14-day delay for new releases --- .npmrc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.npmrc b/.npmrc index 790a49a6eb..a2bad74090 100644 --- a/.npmrc +++ b/.npmrc @@ -1,3 +1,10 @@ +# NOTE: npm is NOT used to manage project dependencies. +# All project dependencies must be installed via pnpm (e.g. `make node_modules`). +# npm is used only for: +# - Bootstrapping pnpm itself (e.g. `npm install -g pnpm@10.34.3` in the Dockerfile) +# - Installing specific standalone CLI tools in CI workflows +# (e.g. `@charmland/crush` in .github/workflows/pull-review-crush.yml) + audit=false fund=false update-notifier=false @@ -5,3 +12,4 @@ save-exact=true auto-install-peers=true dedupe-peer-dependents=false enable-pre-post-scripts=true +minimum-release-age=20160 From 9e1cd653912b818d928a5b900dfc17060d421f25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20Gaud=C3=AAncio?= Date: Mon, 27 Jul 2026 11:47:55 +0200 Subject: [PATCH 05/10] docker: bump build stage to golang:1.25-alpine3.23 for npm >= 11.10.0 --- Dockerfile | 8 ++++++-- Dockerfile.rootless | 8 ++++++-- docker/forkana/Dockerfile | 8 ++++++-- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/Dockerfile b/Dockerfile index 0e18fa0dda..1e952eca87 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,6 @@ # Build stage -FROM docker.io/library/golang:1.25-alpine3.22 AS build-env +# Alpine 3.23 ships npm >= 11.10.0, required for the min-release-age age gate below. +FROM docker.io/library/golang:1.25-alpine3.23 AS build-env # Default was "direct", but gitea.com blocks CI/datacenter traffic with 403s # (e.g. when fetching the gitea.com/gitea/go-xsd-duration replace module), @@ -14,12 +15,15 @@ ENV TAGS="bindata timetzdata $TAGS" ARG CGO_EXTRA_CFLAGS # Build deps +# pnpm bootstrap is age-gated with --min-release-age to match the 14-day +# minimumReleaseAge policy in pnpm-workspace.yaml (repo .npmrc is not yet +# copied at this point). pnpm >= 10.34.3 is required. RUN apk --no-cache add \ build-base \ git \ nodejs \ npm \ - && npm install -g pnpm@10.34.3 \ + && npm install -g --min-release-age=14 "pnpm@^10.34.3" \ && rm -rf /var/cache/apk/* # Setup repo diff --git a/Dockerfile.rootless b/Dockerfile.rootless index d9bf14b4ab..e94cca3e87 100644 --- a/Dockerfile.rootless +++ b/Dockerfile.rootless @@ -1,5 +1,6 @@ # Build stage -FROM docker.io/library/golang:1.25-alpine3.22 AS build-env +# Alpine 3.23 ships npm >= 11.10.0, required for the min-release-age age gate below. +FROM docker.io/library/golang:1.25-alpine3.23 AS build-env # Default was "direct", but gitea.com blocks CI/datacenter traffic with 403s # (e.g. when fetching the gitea.com/gitea/go-xsd-duration replace module), @@ -14,12 +15,15 @@ ENV TAGS="bindata timetzdata $TAGS" ARG CGO_EXTRA_CFLAGS #Build deps +# pnpm bootstrap is age-gated with --min-release-age to match the 14-day +# minimumReleaseAge policy in pnpm-workspace.yaml (repo .npmrc is not yet +# copied at this point). pnpm >= 10.34.3 is required. RUN apk --no-cache add \ build-base \ git \ nodejs \ npm \ - && npm install -g pnpm@10.34.3 \ + && npm install -g --min-release-age=14 "pnpm@^10.34.3" \ && rm -rf /var/cache/apk/* # Setup repo diff --git a/docker/forkana/Dockerfile b/docker/forkana/Dockerfile index 7ca1d956d0..83b1a042ac 100644 --- a/docker/forkana/Dockerfile +++ b/docker/forkana/Dockerfile @@ -2,7 +2,8 @@ # Based on Dockerfile.rootless with Forkana-specific modifications # Build stage -FROM docker.io/library/golang:1.25-alpine3.22 AS build-env +# Alpine 3.23 ships npm >= 11.10.0, required for the min-release-age age gate below. +FROM docker.io/library/golang:1.25-alpine3.23 AS build-env ARG GOPROXY ENV GOPROXY=${GOPROXY:-direct} @@ -13,12 +14,15 @@ ENV TAGS="bindata timetzdata $TAGS" ARG CGO_EXTRA_CFLAGS # Build deps +# pnpm bootstrap is age-gated with --min-release-age to match the 14-day +# minimumReleaseAge policy in pnpm-workspace.yaml (repo .npmrc is not yet +# copied at this point). pnpm >= 10.34.3 is required. RUN apk --no-cache add \ build-base \ git \ nodejs \ npm \ - && npm install -g pnpm@10.34.3 \ + && npm install -g --min-release-age=14 "pnpm@^10.34.3" \ && rm -rf /var/cache/apk/* # Setup repo From 5c39999024ff1f936f5905e555e8ff141531213b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20Gaud=C3=AAncio?= Date: Mon, 27 Jul 2026 11:53:31 +0200 Subject: [PATCH 06/10] deps: age-gate pnpm bootstrap with min-release-age * install pnpm@^10.34.3 with --min-release-age=14 --- .npmrc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.npmrc b/.npmrc index a2bad74090..2af4d88a4f 100644 --- a/.npmrc +++ b/.npmrc @@ -1,7 +1,7 @@ # NOTE: npm is NOT used to manage project dependencies. # All project dependencies must be installed via pnpm (e.g. `make node_modules`). # npm is used only for: -# - Bootstrapping pnpm itself (e.g. `npm install -g pnpm@10.34.3` in the Dockerfile) +# - Bootstrapping pnpm itself (e.g. `npm install -g --min-release-age=14 "pnpm@^10.34.3"` in the Dockerfile) # - Installing specific standalone CLI tools in CI workflows # (e.g. `@charmland/crush` in .github/workflows/pull-review-crush.yml) @@ -12,4 +12,4 @@ save-exact=true auto-install-peers=true dedupe-peer-dependents=false enable-pre-post-scripts=true -minimum-release-age=20160 +min-release-age=14 From 083749902ae619499f51a7c60e53c118228e3063 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20Gaud=C3=AAncio?= Date: Mon, 27 Jul 2026 18:08:51 +0200 Subject: [PATCH 07/10] deps: set pnpm requirement to >= 10.16.0 * lower pnpm bootstrap version from ^10.34.3 to ^10.16.0 in all three Dockerfiles, keeping the 14-day --min-release-age gate * remove the packageManager pin (pnpm@10.34.3) from package.json, relying on the existing engines constraint (>= 10.16.0) --- .npmrc | 7 ++++--- Dockerfile | 4 ++-- Dockerfile.rootless | 4 ++-- docker/forkana/Dockerfile | 4 ++-- package.json | 1 - 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.npmrc b/.npmrc index 2af4d88a4f..753bfcdf96 100644 --- a/.npmrc +++ b/.npmrc @@ -1,7 +1,8 @@ -# NOTE: npm is NOT used to manage project dependencies. +# npm is not used to install project dependencies; project dependencies are +# installed with pnpm. This file contains npm settings used for standalone npm +# installs and legacy pnpm-compatible settings. # All project dependencies must be installed via pnpm (e.g. `make node_modules`). -# npm is used only for: -# - Bootstrapping pnpm itself (e.g. `npm install -g --min-release-age=14 "pnpm@^10.34.3"` in the Dockerfile) +# - Bootstrapping pnpm itself (e.g. `npm install -g --min-release-age=14 "pnpm@^10.16.0"` in the Dockerfile) # - Installing specific standalone CLI tools in CI workflows # (e.g. `@charmland/crush` in .github/workflows/pull-review-crush.yml) diff --git a/Dockerfile b/Dockerfile index 1e952eca87..7b7ca38d49 100644 --- a/Dockerfile +++ b/Dockerfile @@ -17,13 +17,13 @@ ARG CGO_EXTRA_CFLAGS # Build deps # pnpm bootstrap is age-gated with --min-release-age to match the 14-day # minimumReleaseAge policy in pnpm-workspace.yaml (repo .npmrc is not yet -# copied at this point). pnpm >= 10.34.3 is required. +# copied at this point). pnpm >= 10.16.0 is required. RUN apk --no-cache add \ build-base \ git \ nodejs \ npm \ - && npm install -g --min-release-age=14 "pnpm@^10.34.3" \ + && npm install -g --min-release-age=14 "pnpm@^10.16.0" \ && rm -rf /var/cache/apk/* # Setup repo diff --git a/Dockerfile.rootless b/Dockerfile.rootless index e94cca3e87..86a6915159 100644 --- a/Dockerfile.rootless +++ b/Dockerfile.rootless @@ -17,13 +17,13 @@ ARG CGO_EXTRA_CFLAGS #Build deps # pnpm bootstrap is age-gated with --min-release-age to match the 14-day # minimumReleaseAge policy in pnpm-workspace.yaml (repo .npmrc is not yet -# copied at this point). pnpm >= 10.34.3 is required. +# copied at this point). pnpm >= 10.16.0 is required. RUN apk --no-cache add \ build-base \ git \ nodejs \ npm \ - && npm install -g --min-release-age=14 "pnpm@^10.34.3" \ + && npm install -g --min-release-age=14 "pnpm@^10.16.0" \ && rm -rf /var/cache/apk/* # Setup repo diff --git a/docker/forkana/Dockerfile b/docker/forkana/Dockerfile index 83b1a042ac..0f6c54dca1 100644 --- a/docker/forkana/Dockerfile +++ b/docker/forkana/Dockerfile @@ -16,13 +16,13 @@ ARG CGO_EXTRA_CFLAGS # Build deps # pnpm bootstrap is age-gated with --min-release-age to match the 14-day # minimumReleaseAge policy in pnpm-workspace.yaml (repo .npmrc is not yet -# copied at this point). pnpm >= 10.34.3 is required. +# copied at this point). pnpm >= 10.16.0 is required. RUN apk --no-cache add \ build-base \ git \ nodejs \ npm \ - && npm install -g --min-release-age=14 "pnpm@^10.34.3" \ + && npm install -g --min-release-age=14 "pnpm@^10.16.0" \ && rm -rf /var/cache/apk/* # Setup repo diff --git a/package.json b/package.json index a2d504e0ca..fc47e454dc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,5 @@ { "type": "module", - "packageManager": "pnpm@10.34.3", "engines": { "node": ">= 22.6.0", "pnpm": ">= 10.16.0" From 7727539b1c1e9bb9688c60cf5492116f33078baf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20Gaud=C3=AAncio?= Date: Mon, 27 Jul 2026 20:18:20 +0200 Subject: [PATCH 08/10] ci: pin pnpm version range for pnpm/action-setup * add version "^10.16.0" to all 9 pnpm/action-setup@v4 steps * required after packageManager removal from package.json * keeps CI aligned with Dockerfile bootstrap and engines.pnpm constraint --- .github/workflows/pull-compliance.yml | 8 ++++++++ .github/workflows/pull-e2e-tests.yml | 2 ++ .github/workflows/pull-tests.yml | 2 ++ .github/workflows/release-nightly.yml | 2 ++ .github/workflows/release-tag-rc.yml | 2 ++ .github/workflows/release-tag-version.yml | 2 ++ 6 files changed, 18 insertions(+) diff --git a/.github/workflows/pull-compliance.yml b/.github/workflows/pull-compliance.yml index 7908ff775e..25f26b4ecc 100644 --- a/.github/workflows/pull-compliance.yml +++ b/.github/workflows/pull-compliance.yml @@ -36,6 +36,8 @@ jobs: - uses: astral-sh/setup-uv@v6 - run: uv python install 3.12 - uses: pnpm/action-setup@v4 + with: + version: "^10.16.0" - uses: actions/setup-node@v5 with: node-version: 24 @@ -61,6 +63,8 @@ jobs: steps: - uses: actions/checkout@v4 - uses: pnpm/action-setup@v4 + with: + version: "^10.16.0" - uses: actions/setup-node@v5 with: node-version: 24 @@ -131,6 +135,8 @@ jobs: steps: - uses: actions/checkout@v4 - uses: pnpm/action-setup@v4 + with: + version: "^10.16.0" - uses: actions/setup-node@v5 with: node-version: 24 @@ -179,6 +185,8 @@ jobs: steps: - uses: actions/checkout@v4 - uses: pnpm/action-setup@v4 + with: + version: "^10.16.0" - uses: actions/setup-node@v5 with: node-version: 24 diff --git a/.github/workflows/pull-e2e-tests.yml b/.github/workflows/pull-e2e-tests.yml index 2a3d477173..84250df5a1 100644 --- a/.github/workflows/pull-e2e-tests.yml +++ b/.github/workflows/pull-e2e-tests.yml @@ -22,6 +22,8 @@ jobs: go-version-file: go.mod check-latest: true - uses: pnpm/action-setup@v4 + with: + version: "^10.16.0" - uses: actions/setup-node@v5 with: node-version: 24.15.0 diff --git a/.github/workflows/pull-tests.yml b/.github/workflows/pull-tests.yml index bd66a89e07..27eae1af7d 100644 --- a/.github/workflows/pull-tests.yml +++ b/.github/workflows/pull-tests.yml @@ -25,6 +25,8 @@ jobs: - name: Setup pnpm uses: pnpm/action-setup@v4 + with: + version: "^10.16.0" - name: Setup Node.js uses: actions/setup-node@v5 diff --git a/.github/workflows/release-nightly.yml b/.github/workflows/release-nightly.yml index 3d652e4ad8..e874780cc2 100644 --- a/.github/workflows/release-nightly.yml +++ b/.github/workflows/release-nightly.yml @@ -21,6 +21,8 @@ jobs: go-version-file: go.mod check-latest: true - uses: pnpm/action-setup@v4 + with: + version: "^10.16.0" - uses: actions/setup-node@v5 with: node-version: 24 diff --git a/.github/workflows/release-tag-rc.yml b/.github/workflows/release-tag-rc.yml index f4776a9ed8..41fdaaf7c2 100644 --- a/.github/workflows/release-tag-rc.yml +++ b/.github/workflows/release-tag-rc.yml @@ -22,6 +22,8 @@ jobs: go-version-file: go.mod check-latest: true - uses: pnpm/action-setup@v4 + with: + version: "^10.16.0" - uses: actions/setup-node@v5 with: node-version: 24 diff --git a/.github/workflows/release-tag-version.yml b/.github/workflows/release-tag-version.yml index ad0820f31f..36d4cd3071 100644 --- a/.github/workflows/release-tag-version.yml +++ b/.github/workflows/release-tag-version.yml @@ -26,6 +26,8 @@ jobs: go-version-file: go.mod check-latest: true - uses: pnpm/action-setup@v4 + with: + version: "^10.16.0" - uses: actions/setup-node@v5 with: node-version: 24 From 51df0e947dfcb689bad188fb4106b3386be167b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20Gaud=C3=AAncio?= Date: Mon, 27 Jul 2026 20:51:09 +0200 Subject: [PATCH 09/10] ci: suppress SC2016 false positive in crush sandbox pre-flight --- .github/workflows/pull-review-crush.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/pull-review-crush.yml b/.github/workflows/pull-review-crush.yml index 5c2df4c17e..c1a073e6e9 100644 --- a/.github/workflows/pull-review-crush.yml +++ b/.github/workflows/pull-review-crush.yml @@ -512,6 +512,10 @@ jobs: # the token or the runner credentials — better no review than an # unsandboxed one. The runner agent dirs are passed as positional # arguments so the check probes the exact paths that were masked. + # The single quotes are intentional (SC2016): the variables must + # be expanded by the inner shell inside the sandbox, not by the + # outer shell, or the secret values would leak into the command. + # shellcheck disable=SC2016 "${BWRAP[@]}" sh -c ' fail=0 [ -z "$GH_TOKEN" ] || { echo "GH_TOKEN visible inside sandbox"; fail=1; } From 26761a6ea1dca6de2b170e5cfc46e33c399b1a6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20Gaud=C3=AAncio?= Date: Tue, 28 Jul 2026 10:50:58 +0200 Subject: [PATCH 10/10] deps: update .npmrc comment --- .npmrc | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.npmrc b/.npmrc index 753bfcdf96..8843fd9abf 100644 --- a/.npmrc +++ b/.npmrc @@ -1,10 +1,11 @@ # npm is not used to install project dependencies; project dependencies are # installed with pnpm. This file contains npm settings used for standalone npm # installs and legacy pnpm-compatible settings. -# All project dependencies must be installed via pnpm (e.g. `make node_modules`). -# - Bootstrapping pnpm itself (e.g. `npm install -g --min-release-age=14 "pnpm@^10.16.0"` in the Dockerfile) -# - Installing specific standalone CLI tools in CI workflows -# (e.g. `@charmland/crush` in .github/workflows/pull-review-crush.yml) +# Project dependencies are installed with pnpm (e.g. `make node_modules`), not +# npm. This file configures the standalone npm invocations that remain: +# - bootstrapping pnpm itself (Dockerfiles pass --min-release-age explicitly, +# since project .npmrc files are not read by `npm install -g`) +# - one-off `npm install` runs inside the repo audit=false fund=false