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-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; } 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 diff --git a/.npmrc b/.npmrc index 790a49a6eb..8843fd9abf 100644 --- a/.npmrc +++ b/.npmrc @@ -1,3 +1,12 @@ +# 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. +# 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 update-notifier=false @@ -5,3 +14,4 @@ save-exact=true auto-install-peers=true dedupe-peer-dependents=false enable-pre-post-scripts=true +min-release-age=14 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..7b7ca38d49 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.16.0 is required. RUN apk --no-cache add \ build-base \ git \ nodejs \ npm \ - && npm install -g pnpm@10 \ + && 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 315bb77b86..86a6915159 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.16.0 is required. RUN apk --no-cache add \ build-base \ git \ nodejs \ npm \ - && npm install -g pnpm@10 \ + && 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 53b94753aa..0f6c54dca1 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.16.0 is required. RUN apk --no-cache add \ build-base \ git \ nodejs \ npm \ - && npm install -g pnpm@10 \ + && 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 30ea274458..544c5e6056 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"