diff --git a/.github/workflows/static-checks.yml b/.github/workflows/static-checks.yml index b453770de504b6..2b2b8e49790cc3 100644 --- a/.github/workflows/static-checks.yml +++ b/.github/workflows/static-checks.yml @@ -73,6 +73,9 @@ jobs: - name: Lint package.json files run: npm run lint:pkg-json + - name: Lint dependency versions across workspaces + run: npm run lint:deps + - name: Lint package-lock.json file run: npm run lint:lockfile diff --git a/package-lock.json b/package-lock.json index d317cf3076eafd..aad2865f62753d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -43,6 +43,7 @@ "react-scanner": "^1.2.0", "rimraf": "^5.0.10", "stylelint-plugin-logical-css": "^1.2.3", + "syncpack": "^15.3.1", "typescript": "^6.0.2", "wait-on": "^8.0.1" }, @@ -43881,6 +43882,168 @@ "url": "https://opencollective.com/synckit" } }, + "node_modules/syncpack": { + "version": "15.3.1", + "resolved": "https://registry.npmjs.org/syncpack/-/syncpack-15.3.1.tgz", + "integrity": "sha512-0Z+/rwbskj+m5qW8caVbd59OwwXBcxRiDFk82Cb4tKGLPXmZn7Vjo7BnfxHwZqS51Ff+5TFgH5/iyXd24+G6YA==", + "dev": true, + "license": "MIT", + "bin": { + "syncpack": "index.cjs" + }, + "engines": { + "node": ">=14.17.0" + }, + "funding": { + "url": "https://github.com/sponsors/JamieMason" + }, + "optionalDependencies": { + "syncpack-darwin-arm64": "15.3.1", + "syncpack-darwin-x64": "15.3.1", + "syncpack-linux-arm64": "15.3.1", + "syncpack-linux-arm64-musl": "15.3.1", + "syncpack-linux-x64": "15.3.1", + "syncpack-linux-x64-musl": "15.3.1", + "syncpack-windows-arm64": "15.3.1", + "syncpack-windows-x64": "15.3.1" + } + }, + "node_modules/syncpack-darwin-arm64": { + "version": "15.3.1", + "resolved": "https://registry.npmjs.org/syncpack-darwin-arm64/-/syncpack-darwin-arm64-15.3.1.tgz", + "integrity": "sha512-XvbaowC/fw+B7diOtoYjEtSWJVMEbJ7ZH72/TZIe73NwYwY7KFRMVefwxcJE29G+my4vaPmttf2Lbnri8pD6Jw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://github.com/sponsors/JamieMason" + } + }, + "node_modules/syncpack-darwin-x64": { + "version": "15.3.1", + "resolved": "https://registry.npmjs.org/syncpack-darwin-x64/-/syncpack-darwin-x64-15.3.1.tgz", + "integrity": "sha512-KX5+fcHzaGugppyPV3se8iKoFYE5Jde3ZxN80dJKNejluP29rGmOQ1JNaVjy40nZInPNLKQ8LS0TMRtxIgh8ew==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://github.com/sponsors/JamieMason" + } + }, + "node_modules/syncpack-linux-arm64": { + "version": "15.3.1", + "resolved": "https://registry.npmjs.org/syncpack-linux-arm64/-/syncpack-linux-arm64-15.3.1.tgz", + "integrity": "sha512-5saJ4LnizTppqVLt49MKagTixDpuR+5MFweGCkoEAm4SikLqNfzkiEnHqVsjY3+BkCVtXf6DcR1OX6hwswNJ0A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://github.com/sponsors/JamieMason" + } + }, + "node_modules/syncpack-linux-arm64-musl": { + "version": "15.3.1", + "resolved": "https://registry.npmjs.org/syncpack-linux-arm64-musl/-/syncpack-linux-arm64-musl-15.3.1.tgz", + "integrity": "sha512-YslfJ1UndTwL000p0JTP/r8uwXJ4LfYeFBqAfRhLuWoJz8CO+yWyUl4VNdFNitSR1OOB/J7gc4q3jOsxh7kTOg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://github.com/sponsors/JamieMason" + } + }, + "node_modules/syncpack-linux-x64": { + "version": "15.3.1", + "resolved": "https://registry.npmjs.org/syncpack-linux-x64/-/syncpack-linux-x64-15.3.1.tgz", + "integrity": "sha512-bk8keNTteQxXpKDc+Y3r3fE7IZn4cU61gq7ka4gPcBNvvMHOk8Pg71/qQEwN3zBtzAj6yF1Fyzb0NYK9Wo6EPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://github.com/sponsors/JamieMason" + } + }, + "node_modules/syncpack-linux-x64-musl": { + "version": "15.3.1", + "resolved": "https://registry.npmjs.org/syncpack-linux-x64-musl/-/syncpack-linux-x64-musl-15.3.1.tgz", + "integrity": "sha512-/mnWa3FmzJRsDLuqx6rzQIawV5ly1MFyUPxcZlaLX3FbxBryrVXJZZXGd0yJ9UTEKgE5UfRRQlS+ayeXvJbNew==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://github.com/sponsors/JamieMason" + } + }, + "node_modules/syncpack-windows-arm64": { + "version": "15.3.1", + "resolved": "https://registry.npmjs.org/syncpack-windows-arm64/-/syncpack-windows-arm64-15.3.1.tgz", + "integrity": "sha512-GIKQtpNl1Ox2gwBDlEXgL1rneMwUMG0E3eB+EjDKdh4kOJtO0DYduTgg10dmFk/i1ynKGvFtgvhN3VZAr75jgA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "funding": { + "url": "https://github.com/sponsors/JamieMason" + } + }, + "node_modules/syncpack-windows-x64": { + "version": "15.3.1", + "resolved": "https://registry.npmjs.org/syncpack-windows-x64/-/syncpack-windows-x64-15.3.1.tgz", + "integrity": "sha512-4Kl7gCFzaEF7IoHa3vcEHRPx1um8pnzEqidRyQProIJBROG4srgkyQkmwJUXbWzWJhAq2Ic0vtDUvzIXF2U/Dg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "funding": { + "url": "https://github.com/sponsors/JamieMason" + } + }, "node_modules/tabbable": { "version": "6.4.0", "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.4.0.tgz", diff --git a/package.json b/package.json index 3342ceebdadde5..35383fccc8c62c 100644 --- a/package.json +++ b/package.json @@ -83,6 +83,7 @@ "react-scanner": "^1.2.0", "rimraf": "^5.0.10", "stylelint-plugin-logical-css": "^1.2.3", + "syncpack": "^15.3.1", "typescript": "^6.0.2", "wait-on": "^8.0.1" }, @@ -114,9 +115,11 @@ "preformat:php": "npm run other:update-packages:php", "format:php": "wp-env run --env-cwd='wp-content/plugins/gutenberg' cli composer run-script format", "prelint:js": "npm run --if-present --workspaces prelint:js", - "lint": "concurrently \"npm run lint:lockfile\" \"npm run lint:tsconfig\" \"npm run lint:js\" \"npm run lint:pkg-json\" \"npm run lint:css\"", + "lint": "concurrently \"npm run lint:lockfile\" \"npm run lint:tsconfig\" \"npm run lint:js\" \"npm run lint:pkg-json\" \"npm run lint:deps\" \"npm run lint:css\"", "lint:css": "wp-scripts lint-style \"**/*.scss\" \"**/*.module.css\"", "lint:css:fix": "npm run lint:css -- --fix", + "lint:deps": "syncpack lint", + "lint:deps:fix": "syncpack fix", "lint:js": "node ./tools/eslint/lint-js.cjs --concurrency=auto", "lint:js:fix": "npm run lint:js -- --fix", "lint:js:prune-suppressions": "npm run lint:js -- --prune-suppressions", diff --git a/syncpack.config.mjs b/syncpack.config.mjs new file mode 100644 index 00000000000000..a86dd9824a9974 --- /dev/null +++ b/syncpack.config.mjs @@ -0,0 +1,37 @@ +/** @type {import('syncpack').RcFile} */ +export default { + versionGroups: [ + { + label: 'Internal @wordpress/* workspace packages: ignore (workspaces are the source of truth).', + dependencies: [ '@wordpress/**' ], + packages: [ '**' ], + isIgnored: true, + }, + { + label: 'peerDependencies use intentionally wide ranges; only enforce that the ranges are mutually satisfiable.', + dependencyTypes: [ 'peer' ], + policy: 'sameRange', + }, + { + label: '`react` and `react-dom` must use the same version across the repo.', + dependencies: [ 'react', 'react-dom' ], + dependencyTypes: [ 'prod', 'dev' ], + // Bump this literal when upgrading React. + pinVersion: '^18.3.1', + }, + { + label: 'All dependencies must use the same version across the repo.', + dependencies: [ '**' ], + packages: [ '**' ], + dependencyTypes: [ 'prod', 'dev' ], + }, + ], + semverGroups: [ + { + label: 'All dependencies must use caret ranges.', + packages: [ '**' ], + dependencyTypes: [ 'prod', 'dev' ], + range: '^', + }, + ], +};