diff --git a/.github/workflows/audit.yml b/.github/workflows/audit.yml index 466f2e10ee5..5f5bdc6f201 100644 --- a/.github/workflows/audit.yml +++ b/.github/workflows/audit.yml @@ -21,13 +21,13 @@ jobs: shell: bash steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Setup Git User run: | git config --global user.email "npm-cli+bot@github.com" git config --global user.name "npm CLI robot" - name: Setup Node - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 id: node with: node-version: 22.x diff --git a/.github/workflows/ci-cli.yml b/.github/workflows/ci-cli.yml index 5391b49e59a..ca6b4227770 100644 --- a/.github/workflows/ci-cli.yml +++ b/.github/workflows/ci-cli.yml @@ -29,13 +29,13 @@ jobs: shell: bash steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Setup Git User run: | git config --global user.email "npm-cli+bot@github.com" git config --global user.name "npm CLI robot" - name: Setup Node - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 id: node with: node-version: 22.x @@ -68,13 +68,13 @@ jobs: shell: ${{ matrix.platform.shell }} steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Setup Git User run: | git config --global user.email "npm-cli+bot@github.com" git config --global user.name "npm CLI robot" - name: Setup Node - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 id: node with: node-version: ${{ matrix.node-version }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dad0bc83f76..03e056fb8b9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,13 +29,13 @@ jobs: shell: bash steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Setup Git User run: | git config --global user.email "npm-cli+bot@github.com" git config --global user.name "npm CLI robot" - name: Setup Node - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 id: node with: node-version: 22.x @@ -68,13 +68,13 @@ jobs: shell: ${{ matrix.platform.shell }} steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Setup Git User run: | git config --global user.email "npm-cli+bot@github.com" git config --global user.name "npm CLI robot" - name: Setup Node - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 id: node with: node-version: ${{ matrix.node-version }} @@ -105,13 +105,13 @@ jobs: shell: ${{ matrix.platform.shell }} steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Setup Git User run: | git config --global user.email "npm-cli+bot@github.com" git config --global user.name "npm CLI robot" - name: Setup Node - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 id: node with: node-version: ${{ matrix.node-version }} diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index af848e17ada..8c4355655ad 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -26,7 +26,7 @@ jobs: security-events: write steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Setup Git User run: | git config --global user.email "npm-cli+bot@github.com" diff --git a/.github/workflows/post-dependabot.yml b/.github/workflows/post-dependabot.yml index b66465dd4f3..55828ef2e52 100644 --- a/.github/workflows/post-dependabot.yml +++ b/.github/workflows/post-dependabot.yml @@ -17,7 +17,7 @@ jobs: shell: bash steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: ref: ${{ github.event.pull_request.head.ref }} - name: Setup Git User @@ -25,7 +25,7 @@ jobs: git config --global user.email "npm-cli+bot@github.com" git config --global user.name "npm CLI robot" - name: Setup Node - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 id: node with: node-version: 22.x diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 3ba0a5089b5..7146c3ee02a 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -23,13 +23,13 @@ jobs: shell: bash steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Setup Git User run: | git config --global user.email "npm-cli+bot@github.com" git config --global user.name "npm CLI robot" - name: Setup Node - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 id: node with: node-version: 22.x diff --git a/.github/workflows/update-cli.yml b/.github/workflows/update-cli.yml index fb104baad7c..dd255e886ca 100644 --- a/.github/workflows/update-cli.yml +++ b/.github/workflows/update-cli.yml @@ -21,13 +21,13 @@ jobs: shell: bash steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Setup Git User run: | git config --global user.email "npm-cli+bot@github.com" git config --global user.name "npm CLI robot" - name: Setup Node - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 id: node with: node-version: 22.x diff --git a/cli/package.json b/cli/package.json index efc9767e2b5..b07f82fea93 100644 --- a/cli/package.json +++ b/cli/package.json @@ -40,7 +40,7 @@ }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "4.30.0", + "version": "5.0.0", "content": "./scripts/template-oss" }, "files": [ diff --git a/cli/test/_helpers.js b/cli/test/_helpers.js new file mode 100644 index 00000000000..dfa16ed8fc3 --- /dev/null +++ b/cli/test/_helpers.js @@ -0,0 +1,69 @@ +const fs = require('node:fs') +const os = require('node:os') +const path = require('node:path') + +const writeTree = (dir, spec) => { + fs.mkdirSync(dir, {recursive: true}) + for (const [name, value] of Object.entries(spec)) { + const p = path.join(dir, name) + if (value === null || value === undefined) { + continue + } + if (typeof value === 'string' || Buffer.isBuffer(value)) { + fs.writeFileSync(p, value) + } else if (typeof value === 'object') { + writeTree(p, value) + } else { + throw new TypeError(`testdir: unsupported value at ${p}: ${typeof value}`) + } + } +} + +const testdir = (t, spec = {}) => { + const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'cli-test-')) + writeTree(dir, spec) + t.after(() => fs.rmSync(dir, {recursive: true, force: true})) + return dir +} + +const mockRequire = (t, requestPath, mocks = {}) => { + const sutPath = require.resolve(requestPath, {paths: [__dirname]}) + const sutDir = path.dirname(sutPath) + + const overridden = [] + for (const [spec, value] of Object.entries(mocks)) { + const resolved = require.resolve(spec, {paths: [sutDir]}) + overridden.push([resolved, require.cache[resolved]]) + require.cache[resolved] = { + id: resolved, + filename: resolved, + loaded: true, + exports: value, + children: [], + paths: [], + parent: null, + } + } + + const previousSut = require.cache[sutPath] + delete require.cache[sutPath] + const exported = require(sutPath) + + t.after(() => { + delete require.cache[sutPath] + if (previousSut) { + require.cache[sutPath] = previousSut + } + for (const [resolved, prev] of overridden) { + if (prev) { + require.cache[resolved] = prev + } else { + delete require.cache[resolved] + } + } + }) + + return exported +} + +module.exports = {testdir, mockRequire} diff --git a/package-lock.json b/package-lock.json index 0dc9432ee58..aa11eb9b4b1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -50,7 +50,7 @@ "@babel/plugin-proposal-private-property-in-object": "^7.21.11", "@github/prettier-config": "^0.0.6", "@npmcli/eslint-config": "^6.0.0", - "@npmcli/template-oss": "4.30.0", + "@npmcli/template-oss": "5.0.0", "@testing-library/dom": "^10.4.0", "@testing-library/jest-dom": "^6.2.0", "@testing-library/react": "^16.0.0", @@ -133,6 +133,72 @@ "node": "^20.17.0 || >=22.9.0" } }, + "cli/node_modules/@npmcli/template-oss": { + "version": "4.30.0", + "resolved": "https://registry.npmjs.org/@npmcli/template-oss/-/template-oss-4.30.0.tgz", + "integrity": "sha512-GNp1qp/GeIeYn2A+CjPhdWX3IzySHiafzpLy3KVNg7Qmx84/0oXMQVyeAJ4N44Nm3eIk6OL5VOaExGh2+F+mdg==", + "dev": true, + "hasInstallScript": true, + "license": "ISC", + "workspaces": [ + "workspace/test-workspace" + ], + "dependencies": { + "@actions/core": "^2.0.0", + "@commitlint/cli": "^20.1.0", + "@commitlint/config-conventional": "^20.0.0", + "@isaacs/string-locale-compare": "^1.1.0", + "@npmcli/arborist": "^9.1.2", + "@npmcli/git": "^7.0.0", + "@npmcli/map-workspaces": "^5.0.0", + "@npmcli/package-json": "^7.0.0", + "@octokit/rest": "^22.0.0", + "dedent": "^1.5.1", + "diff": "^8.0.2", + "glob": "^13.0.0", + "handlebars": "^4.7.7", + "hosted-git-info": "^9.0.0", + "ini": "^6.0.0", + "json-parse-even-better-errors": "^5.0.0", + "just-deep-map-values": "^1.1.1", + "just-diff": "^6.0.0", + "just-omit": "^2.2.0", + "lodash": "^4.17.21", + "minimatch": "^10.0.3", + "npm-package-arg": "^13.0.0", + "proc-log": "^6.0.0", + "release-please": "^17.1.1", + "semver": "^7.3.5", + "yaml": "^2.1.1" + }, + "bin": { + "template-oss-apply": "bin/apply.js", + "template-oss-check": "bin/check.js", + "template-oss-release-manager": "bin/release-manager.js", + "template-oss-release-please": "bin/release-please.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "cli/node_modules/glob": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", + "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "minimatch": "^10.2.2", + "minipass": "^7.1.3", + "path-scurry": "^2.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "cli/node_modules/hosted-git-info": { "version": "9.0.2", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-9.0.2.tgz", @@ -163,6 +229,16 @@ "node": ">=20" } }, + "cli/node_modules/json-parse-even-better-errors": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-5.0.0.tgz", + "integrity": "sha512-ZF1nxZ28VhQouRWhUcVlUIN3qwSgPuswK05s/HIaoetAoE/9tngVmCHjSxmSQPav1nd+lPtTL0YZ/2AFdR/iYQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, "cli/node_modules/lru-cache": { "version": "11.2.6", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz", @@ -254,6 +330,23 @@ "node": "^20.17.0 || >=22.9.0" } }, + "cli/node_modules/path-scurry": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", + "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "cli/node_modules/tar": { "version": "7.5.13", "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.13.tgz", @@ -7010,9 +7103,9 @@ } }, "node_modules/@npmcli/template-oss": { - "version": "4.30.0", - "resolved": "https://registry.npmjs.org/@npmcli/template-oss/-/template-oss-4.30.0.tgz", - "integrity": "sha512-GNp1qp/GeIeYn2A+CjPhdWX3IzySHiafzpLy3KVNg7Qmx84/0oXMQVyeAJ4N44Nm3eIk6OL5VOaExGh2+F+mdg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/template-oss/-/template-oss-5.0.0.tgz", + "integrity": "sha512-yORdW7L85x7gzGdvP0KcfCQiLKEBgnBob/zyQ/ImJ/XkW3hgV0yIQSwy2JsKD5SWDHYD1+TUsQbcpgDED5+HCw==", "dev": true, "hasInstallScript": true, "license": "ISC", @@ -7054,7 +7147,7 @@ "template-oss-release-please": "bin/release-please.js" }, "engines": { - "node": "^20.17.0 || >=22.9.0" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, "node_modules/@npmcli/template-oss/node_modules/@npmcli/git": { @@ -12968,6 +13061,89 @@ "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", "license": "MIT" }, + "node_modules/body-parser": { + "version": "1.20.5", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.5.tgz", + "integrity": "sha512-3grm+/2tUOvu2cjJkvsIxrv/wVpfXQW4PsQHYm7yk4vfpu7Ekl6nEsYBoJUL6qDwZUx8wUhQ8tR2qz+ad9c9OA==", + "license": "MIT", + "dependencies": { + "bytes": "~3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "~1.2.0", + "http-errors": "~2.0.1", + "iconv-lite": "~0.4.24", + "on-finished": "~2.4.1", + "qs": "~6.15.1", + "raw-body": "~2.5.3", + "type-is": "~1.6.18", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", + "license": "MIT", + "dependencies": { + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/body-parser/node_modules/qs": { + "version": "6.15.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.1.tgz", + "integrity": "sha512-6YHEFRL9mfgcAvql/XhwTvf5jKcOiiupt2FiJxHkiX1z4j7WL8J/jRHYLluORvc1XxB5rV20KoeK00gVJamspg==", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/body-parser/node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", @@ -19180,45 +19356,6 @@ "ms": "^2.1.1" } }, - "node_modules/express/node_modules/body-parser": { - "version": "1.20.3", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", - "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", - "license": "MIT", - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.5", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.13.0", - "raw-body": "2.5.2", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/express/node_modules/body-parser/node_modules/qs": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", - "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.0.6" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/express/node_modules/cookie": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", @@ -19243,21 +19380,6 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "license": "MIT" }, - "node_modules/express/node_modules/raw-body": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", - "license": "MIT", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/ext": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", diff --git a/package.json b/package.json index e4bcdb118d2..e0113b204a0 100644 --- a/package.json +++ b/package.json @@ -69,7 +69,7 @@ "@babel/plugin-proposal-private-property-in-object": "^7.21.11", "@github/prettier-config": "^0.0.6", "@npmcli/eslint-config": "^6.0.0", - "@npmcli/template-oss": "4.30.0", + "@npmcli/template-oss": "5.0.0", "@testing-library/dom": "^10.4.0", "@testing-library/jest-dom": "^6.2.0", "@testing-library/react": "^16.0.0", @@ -107,7 +107,7 @@ "content": "./scripts/template-oss", "dependabotInterval": "weekly", "updateNpm": false, - "version": "4.30.0" + "version": "5.0.0" }, "overrides": { "gatsby@^5.16.0": {