feat(repo): migrate to pnpm 10 (#31427)

- Added .pnpmrc for pnpm 10 configuration, enabling peer dependencies
and lifecycle scripts.
- Updated package.json to reflect pnpm version change to 10.11.1 and
added onlyBuiltDependencies.
- Update pipelines to reflect pnpm version update to 10.11.1

## Upgrading your pnpm version
Now to upgrade your `pnpm` version you can run `pnpm
migrate-to-pnpm-version 10`. Which would upgrade your `pnpm` and it will
run the upgrade script.

Later on if you want to upgrade to pnpm v11 you can run `pnpm
migrate-to-pnpm-version 11`.
Additionally, if you just want to upgrade to the version that is inside
of `package.json` you would run
`pnpm migrate-to-pnpm-version` without passing in a major version.
This commit is contained in:
Nicholas Cunningham 2025-06-09 08:29:16 -06:00 committed by GitHub
parent 4fa95c21c7
commit a5544e371b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 452 additions and 498 deletions

View File

@ -59,7 +59,7 @@ jobs:
- uses: pnpm/action-setup@v4 - uses: pnpm/action-setup@v4
name: Install pnpm name: Install pnpm
with: with:
version: 9.8.0 version: 10.11.1
run_install: false run_install: false
- uses: actions/setup-node@v4 - uses: actions/setup-node@v4
@ -272,7 +272,7 @@ jobs:
- uses: pnpm/action-setup@v4 - uses: pnpm/action-setup@v4
name: Install pnpm name: Install pnpm
with: with:
version: 9.8.0 version: 10.11.1
run_install: false run_install: false
- uses: actions/setup-node@v4 - uses: actions/setup-node@v4

View File

@ -45,7 +45,7 @@ jobs:
- uses: pnpm/action-setup@v4 - uses: pnpm/action-setup@v4
name: Install pnpm name: Install pnpm
with: with:
version: 9.8.0 version: 10.11.1
run_install: false run_install: false
- uses: actions/setup-node@v4 - uses: actions/setup-node@v4

View File

@ -53,7 +53,7 @@ jobs:
- uses: pnpm/action-setup@v4 - uses: pnpm/action-setup@v4
name: Install pnpm name: Install pnpm
with: with:
version: 9.8.0 version: 10.11.1
run_install: false run_install: false
- name: Set node - name: Set node
@ -155,7 +155,7 @@ jobs:
- uses: pnpm/action-setup@v4 - uses: pnpm/action-setup@v4
name: Install pnpm name: Install pnpm
with: with:
version: 9.8.0 version: 10.11.1
run_install: false run_install: false
- name: Use Node.js ${{ matrix.node_version }} - name: Use Node.js ${{ matrix.node_version }}

View File

@ -25,7 +25,7 @@ jobs:
uses: pnpm/action-setup@v4 uses: pnpm/action-setup@v4
id: pnpm-install id: pnpm-install
with: with:
version: 9.8.0 version: 10.11.1
run_install: false run_install: false
- name: Get pnpm store directory - name: Get pnpm store directory

View File

@ -20,7 +20,7 @@ jobs:
- uses: pnpm/action-setup@v4 - uses: pnpm/action-setup@v4
with: with:
version: 9.8.0 version: 10.11.1
- name: Use Node.js ${{ matrix.node_version }} - name: Use Node.js ${{ matrix.node_version }}
uses: actions/setup-node@v3 uses: actions/setup-node@v3

View File

@ -18,7 +18,7 @@ jobs:
- uses: pnpm/action-setup@v4 - uses: pnpm/action-setup@v4
with: with:
version: 9.8.0 # Aligned with root package.json (pnpm/action-setup will helpfully error if out of sync) version: 10.11.1 # Aligned with root package.json (pnpm/action-setup will helpfully error if out of sync)
- name: Run a security audit - name: Run a security audit
run: pnpm dlx audit-ci --critical --report-type summary run: pnpm dlx audit-ci --critical --report-type summary

View File

@ -22,7 +22,7 @@ env:
NX_RUN_GROUP: ${{ github.run_id }}-${{ github.run_attempt }} NX_RUN_GROUP: ${{ github.run_id }}-${{ github.run_attempt }}
CYPRESS_INSTALL_BINARY: 0 CYPRESS_INSTALL_BINARY: 0
NODE_VERSION: 20.19.0 NODE_VERSION: 20.19.0
PNPM_VERSION: 9.8.0 # Aligned with root package.json (pnpm/action-setup will helpfully error if out of sync) PNPM_VERSION: 10.11.1 # Aligned with root package.json (pnpm/action-setup will helpfully error if out of sync)
jobs: jobs:
# We first need to determine the version we are releasing, and if we need a custom repo or ref to use for the git checkout in subsequent steps. # We first need to determine the version we are releasing, and if we need a custom repo or ref to use for the git checkout in subsequent steps.
@ -142,7 +142,7 @@ jobs:
docker: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-debian docker: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-debian
build: |- build: |-
set -e && set -e &&
npm i -g pnpm@9.8.0 --force && npm i -g pnpm@10.11.1 --force &&
pnpm --version && pnpm --version &&
pnpm install --frozen-lockfile && pnpm install --frozen-lockfile &&
rustup target add aarch64-unknown-linux-gnu && rustup target add aarch64-unknown-linux-gnu &&
@ -152,7 +152,7 @@ jobs:
docker: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-alpine docker: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-alpine
build: |- build: |-
set -e && set -e &&
npm i -g pnpm@9.8.0 --force && npm i -g pnpm@10.11.1 --force &&
pnpm --version && pnpm --version &&
pnpm install --frozen-lockfile && pnpm install --frozen-lockfile &&
rustup target add x86_64-unknown-linux-musl && rustup target add x86_64-unknown-linux-musl &&
@ -173,7 +173,7 @@ jobs:
docker: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-debian-aarch64 docker: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-debian-aarch64
build: |- build: |-
set -e && set -e &&
npm i -g pnpm@9.8.0 --force && npm i -g pnpm@10.11.1 --force &&
pnpm --version && pnpm --version &&
pnpm install --frozen-lockfile && pnpm install --frozen-lockfile &&
rustup target add aarch64-unknown-linux-gnu && rustup target add aarch64-unknown-linux-gnu &&
@ -201,7 +201,7 @@ jobs:
build: |- build: |-
set -e && set -e &&
rustup target add aarch64-unknown-linux-musl && rustup target add aarch64-unknown-linux-musl &&
npm i -g pnpm@9.8.0 --force && npm i -g pnpm@10.11.1 --force &&
pnpm --version && pnpm --version &&
pnpm install --frozen-lockfile && pnpm install --frozen-lockfile &&
pnpm nx run-many --verbose --target=build-native -- --target=aarch64-unknown-linux-musl pnpm nx run-many --verbose --target=build-native -- --target=aarch64-unknown-linux-musl
@ -328,7 +328,7 @@ jobs:
env env
whoami whoami
sudo pkg install -y -f node libnghttp2 www/npm git sudo pkg install -y -f node libnghttp2 www/npm git
sudo npm install --location=global --ignore-scripts pnpm@9.8.0 sudo npm install --location=global --ignore-scripts pnpm@10.11.1
curl https://sh.rustup.rs -sSf --output rustup.sh curl https://sh.rustup.rs -sSf --output rustup.sh
sh rustup.sh -y --profile minimal --default-toolchain stable sh rustup.sh -y --profile minimal --default-toolchain stable
source "$HOME/.cargo/env" source "$HOME/.cargo/env"

13
.pnpmrc Normal file
View File

@ -0,0 +1,13 @@
# Enable pre/post-install which are disabled by default. Installing peer deps which is also disabled by default
auto-install-peers=true
enable-pre-post-scripts=true
# Enable lifecycle scripts for specific packages that require them (like post-install)
enable-scripts=@napi-rs/canvas,sharp,@swc/core,@swc/cli,@swc-node/register,esbuild
# Compatibility
strict-peer-dependencies=false
lockfile-version-strict=false
# Consistency across environments
use-node-version=20.19.0

View File

@ -24,7 +24,8 @@
"test": "nx run-many -t test", "test": "nx run-many -t test",
"e2e": "nx run-many -t e2e --projects ./e2e/*", "e2e": "nx run-many -t e2e --projects ./e2e/*",
"build:wasm": "rustup override set nightly-2025-05-09 && rustup target add wasm32-wasip1-threads && WASI_SDK_PATH=\"$(pwd)/wasi-sdk-23.0-x86_64-linux\" CMAKE_BUILD_PARALLEL_LEVEL=2 LIBSQLITE3_FLAGS=\"-DLONGDOUBLE_TYPE=double\" pnpm exec nx run-many -t build-native-wasm && rustup override unset", "build:wasm": "rustup override set nightly-2025-05-09 && rustup target add wasm32-wasip1-threads && WASI_SDK_PATH=\"$(pwd)/wasi-sdk-23.0-x86_64-linux\" CMAKE_BUILD_PARALLEL_LEVEL=2 LIBSQLITE3_FLAGS=\"-DLONGDOUBLE_TYPE=double\" pnpm exec nx run-many -t build-native-wasm && rustup override unset",
"lint-pnpm-lock": "eslint pnpm-lock.yaml" "lint-pnpm-lock": "eslint pnpm-lock.yaml",
"migrate-to-pnpm-version": "node ./scripts/migrate-to-pnpm-version.js"
}, },
"devDependencies": { "devDependencies": {
"@actions/core": "^1.10.0", "@actions/core": "^1.10.0",
@ -158,6 +159,7 @@
"@types/yargs": "17.0.10", "@types/yargs": "17.0.10",
"@types/yarnpkg__lockfile": "^1.1.5", "@types/yarnpkg__lockfile": "^1.1.5",
"@typescript-eslint/eslint-plugin": "^8.29.0", "@typescript-eslint/eslint-plugin": "^8.29.0",
"@typescript-eslint/parser": "^8.29.0",
"@typescript-eslint/rule-tester": "^8.29.0", "@typescript-eslint/rule-tester": "^8.29.0",
"@typescript-eslint/type-utils": "^8.29.0", "@typescript-eslint/type-utils": "^8.29.0",
"@typescript-eslint/utils": "^8.29.0", "@typescript-eslint/utils": "^8.29.0",
@ -410,10 +412,14 @@
"check-codeowners" "check-codeowners"
] ]
}, },
"packageManager": "pnpm@9.8.0", "packageManager": "pnpm@10.11.1",
"pnpm": { "pnpm": {
"patchedDependencies": { "patchedDependencies": {
"@tutorialkit/react": "patches/@tutorialkit__react.patch" "@tutorialkit/react": "patches/@tutorialkit__react.patch"
} },
"onlyBuiltDependencies": [
"@nestjs/core",
"nx"
]
} }
} }

744
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,127 @@
const { execSync } = require('child_process');
const fs = require('fs');
let desiredMajorVersion = process.argv[2];
// Fallback to package.json version if no argument provided
if (!desiredMajorVersion) {
try {
const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf8'));
const packageManager = packageJson.packageManager;
if (packageManager && packageManager.startsWith('pnpm@')) {
const version = packageManager.replace('pnpm@', '');
desiredMajorVersion = version.split('.')[0];
console.log(
`📖 Using version from package.json: pnpm ${desiredMajorVersion}`
);
} else {
console.error(
'❌ No version provided and no pnpm version found in package.json'
);
console.error('❌ Usage: pnpm migrate-to-pnpm-version <major-version>');
process.exit(1);
}
} catch (error) {
console.error('❌ Failed to read package.json:', error.message);
console.error('❌ Usage: pnpm migrate-to-pnpm-version <major-version>');
process.exit(1);
}
}
console.log(`🚀 Starting migration to pnpm ${desiredMajorVersion}...`);
let currentVersion;
let needsPnpmInstall = true;
try {
currentVersion = execSync('pnpm --version', { encoding: 'utf8' }).trim();
const currentMajorVersion = currentVersion.split('.')[0];
if (currentMajorVersion === desiredMajorVersion) {
console.log(
`✅ Already using pnpm ${desiredMajorVersion}.${currentVersion
.split('.')
.slice(1)
.join('.')}`
);
needsPnpmInstall = false;
if (fs.existsSync('node_modules') && fs.existsSync('pnpm-lock.yaml')) {
try {
execSync('pnpm list --depth=0', { stdio: 'pipe' });
console.log('📦 Packages already installed!');
process.exit(0);
} catch (error) {
console.log('🔄 Dependencies need reinstalling...');
}
} else {
console.log('📥 No dependencies installed. Installing...');
}
}
} catch (error) {
console.log('⚠️ pnpm not found, installing...');
}
// Install pnpm if needed
if (needsPnpmInstall) {
try {
execSync(`npm install -g pnpm@${desiredMajorVersion}`, {
stdio: 'inherit',
});
const installedVersion = execSync('pnpm --version', {
encoding: 'utf8',
}).trim();
console.log(`✅ Installed pnpm@${installedVersion}`);
// Update packageManager in package.json
const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf8'));
packageJson.packageManager = `pnpm@${installedVersion}`;
fs.writeFileSync(
'package.json',
JSON.stringify(packageJson, null, 2) + '\n'
);
} catch (error) {
console.error('❌ Failed to install pnpm:', error.message);
process.exit(1);
}
}
// Backup and install packages
if (fs.existsSync('pnpm-lock.yaml')) {
fs.copyFileSync('pnpm-lock.yaml', 'pnpm-lock.yaml.backup');
console.log('💾 Backup created');
}
if (needsPnpmInstall) {
try {
if (fs.existsSync('node_modules')) {
execSync('rm -rf node_modules', { stdio: 'inherit' });
}
execSync('pnpm store prune', { stdio: 'pipe' });
} catch (error) {
// Store prune can fail, but we can continue
}
}
console.log('📦 Installing dependencies...');
try {
execSync('pnpm install', { stdio: 'inherit' });
// Verify
execSync('pnpm build --help', { stdio: 'pipe' });
execSync('pnpm nx --version', { stdio: 'pipe' });
console.log('🎉 Migration completed successfully!');
if (fs.existsSync('pnpm-lock.yaml.backup')) {
console.log('🗑️ Removing backup file...');
fs.unlinkSync('pnpm-lock.yaml.backup');
}
} catch (error) {
console.error('❌ Installation failed:', error.message);
if (fs.existsSync('pnpm-lock.yaml.backup')) {
fs.copyFileSync('pnpm-lock.yaml.backup', 'pnpm-lock.yaml');
console.log('🔄 Backup restored');
}
process.exit(1);
}

View File

@ -1,7 +1,8 @@
/* /*
This pre-install script will check that the necessary dependencies are installed This pre-install script will check that the necessary dependencies are installed
Checks for: Checks for:
* Node 18+ * Node 20+
* pnpm 10+
* Rust * Rust
*/ */
@ -13,9 +14,28 @@ const childProcess = require('child_process');
const semverLessThan = require('semver/functions/lt'); const semverLessThan = require('semver/functions/lt');
// Check node version // Check node version
if (semverLessThan(process.version, '18.0.0')) { if (semverLessThan(process.version, '20.19.0')) {
console.error( console.error(
'Please make sure that your installed Node version is greater than v18' 'Please make sure that your installed Node version is greater than v20.19.0'
);
process.exit(1);
}
// Check for pnpm version
try {
let pnpmVersion = childProcess.execSync('pnpm --version', {
encoding: 'utf8',
});
const version = pnpmVersion.trim();
if (semverLessThan(version, '10.0.0')) {
console.error(
`Found pnpm ${version}. Please make sure that your installed pnpm version is 10.0.0 or greater. You can update with: npm install -g pnpm@10`
);
process.exit(1);
}
} catch {
console.error(
'Could not find pnpm on this system. Please make sure it is installed with: npm install -g pnpm@10'
); );
process.exit(1); process.exit(1);
} }