diff --git a/.github/actions/setup-frontend/action.yml b/.github/actions/setup-frontend/action.yml index 58ea6427..d1abe160 100644 --- a/.github/actions/setup-frontend/action.yml +++ b/.github/actions/setup-frontend/action.yml @@ -3,6 +3,7 @@ description: >- Install pnpm at the version package.json's packageManager names, then Node, then the packages at their locked versions. pnpm runs a dependency's install script only if pnpm-workspace.yaml allows it, and stops on one it doesn't list. + It also stops on a locked version newer than the minimumReleaseAge set there. runs: using: composite diff --git a/docs/development.md b/docs/development.md index 78508f2f..aa5abb1e 100644 --- a/docs/development.md +++ b/docs/development.md @@ -8,8 +8,13 @@ together, see [architecture.md](architecture.md). For cutting a release, see - [Rust](https://rustup.rs) 1.90 or later, from the stable channel - [Node.js](https://nodejs.org) 24, or 22.22.1 or a later 22.x release -- [pnpm](https://pnpm.io/installation). With Node 24, `corepack enable pnpm` sets it - up. pnpm 10 or later switches itself to the version that `package.json` names. +- [pnpm](https://pnpm.io/installation), at the version that `packageManager` in + `package.json` names. Run `corepack enable pnpm`, and Corepack then runs that + version. Node 24.12 or later, or 22.22.1 or later on 22.x, comes with a Corepack + that can start pnpm 12. On an older Node 24, run `npm i -g corepack@latest` first. + `pmOnFail` in `pnpm-workspace.yaml` turns off pnpm's own version switching, so a + pnpm 11 or later installed another way runs as its own version and doesn't warn. + Use Corepack. - The platform dependencies below The desktop app builds on macOS (Apple Silicon) and Linux (x86_64). Windows isn't @@ -91,6 +96,19 @@ the Rust backend won't work there, but it's quick for layout work. the install stops until the package is listed under `allowBuilds` in `pnpm-workspace.yaml`, with `true` to run its script or `false` to skip it. +pnpm only installs versions that have been on the registry for at least three days, +as `minimumReleaseAge` in `pnpm-workspace.yaml` sets. `pnpm add` and `pnpm update` +pick the newest version that's old enough. When none fits the range, they stop with +an error, or in a terminal ask whether to take the newer version anyway. The check +also covers every version already in `pnpm-lock.yaml`, so a lockfile that names a +newer one fails `pnpm install`, in CI as well. A version is let through once it's +listed as `name@version` under `minimumReleaseAgeExclude`, which is what approving +it in the terminal does. Dependabot's security pull requests skip the seven-day +`cooldown` in `.github/dependabot.yml`. When one brings a version under three days +old, its CI install fails. Re-run the job once that version is three days old, or add +each version the error names, as `name@version`, to `minimumReleaseAgeExclude` on +that pull request's branch. + If you installed the packages with npm before the switch to pnpm, delete `node_modules` and `apps/desktop/node_modules` before the first `pnpm install`. pnpm doesn't remove the packages that npm put at the top level of diff --git a/package.json b/package.json index c15ceb49..4f6b9fec 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "private": true, "license": "GPL-3.0-only", "description": "IPTV player for desktop and iOS, built with Tauri and mpv", - "packageManager": "pnpm@10.34.6+sha512.7e1ae66a83a9143c118cc1944f37cc4f2b8acddeda4b001cfa78908f6e46e45e15292739ca6c9d026426cc757e9318cc98c5551d6a16c165097b0028ba87b4e6", + "packageManager": "pnpm@12.8.1+sha512.f64ba907507f5ceafe06c8d38e6052d0179444580ec1279ddd5bfc11cb48aa8a2644b66598e07e761da84872a9fc57d5f902b87fa49d024198d558612aabbe45", "scripts": { "prepare": "husky", "format": "prettier --write \"apps/**/*.{ts,tsx,js,jsx,json,css,md}\"", diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 2afa6e8a..5db2c85a 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -13,6 +13,46 @@ catalog: # the install until it's listed under allowBuilds. strictDepBuilds: true +# pnpm only installs versions that have been on the registry for at least three +# days, given here in minutes. A bad release is usually found and pulled by +# then. pnpm's own default is one day. The check covers every entry already in +# pnpm-lock.yaml too, so a frozen install in CI fails on a version that's too +# new. Since the age is set here, pnpm doesn't quietly take a newer version +# when nothing old enough fits a range. It stops, or asks in a terminal. +minimumReleaseAge: 4320 + +# These exact versions were already locked before the age check was turned on. +# The list can go after 2026-10-15 17:12 UTC, when the last of them passes it. +minimumReleaseAgeExclude: + - "@tanstack/react-virtual@3.14.17" + - "@tanstack/virtual-core@3.19.2" + - "@typescript-eslint/eslint-plugin@8.71.2" + - "@typescript-eslint/parser@8.71.2" + - "@typescript-eslint/project-service@8.71.2" + - "@typescript-eslint/scope-manager@8.71.2" + - "@typescript-eslint/tsconfig-utils@8.71.2" + - "@typescript-eslint/type-utils@8.71.2" + - "@typescript-eslint/types@8.71.2" + - "@typescript-eslint/typescript-estree@8.71.2" + - "@typescript-eslint/utils@8.71.2" + - "@typescript-eslint/visitor-keys@8.71.2" + - "@vitest/coverage-v8@5.0.4" + - "@vitest/mocker@5.0.4" + - "@vitest/spy@5.0.4" + - prettier@3.9.10 + - tinybench@6.2.2 + - typescript-eslint@8.71.2 + - vitest@5.0.4 + +# pnpm 12 records its own version in a first document in pnpm-lock.yaml. +# GitHub's dependency graph reads only that document, so it would see no +# dependencies and close every Dependabot alert. See +# https://github.com/dependabot/dependabot-core/issues/15904. With ignore, the +# lockfile stays one document, and pnpm no longer checks or switches its own +# version. Corepack and pnpm/action-setup already run the version that +# packageManager in package.json names. +pmOnFail: ignore + # eslint-plugin-react 7.37.5 still lists ESLint 9 as its newest peer. It runs # on ESLint 10 once settings.react.version is set, since detecting the version # calls a context method that ESLint 10 removed.