From d68bee0cc23f5861287e6805d82eedd7ac39582c Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Wed, 5 Aug 2026 11:39:34 +0200 Subject: [PATCH] chore: upgrade to NPM v12 Require npm >=12.0.2 <13, enforced via check-node-version on npm install and npm ci. CI installs the version from engines.npm via the new .github/actions/install-npm composite action. The motivation is that npm v12 turns three code-execution paths off by default, most notably the unauthorized execution of install scripts: - allowScripts now defaults to off, so npm install no longer executes preinstall, install or postinstall scripts from dependencies unless they are explicitly allowed in package.json. This also covers prepare scripts from git, file and link dependencies. - --allow-git now defaults to none, which closes a code-execution path where a git dependency's .npmrc could override the git executable, even with --ignore-scripts. - --allow-remote now defaults to none, blocking dependencies from remote URLs such as HTTPS tarballs. See https://github.blog/changelog/2026-06-09-upcoming-breaking-changes-for-npm-v12/ The Node.js requirement is left unchanged. --- .github/actions/install-npm/action.yml | 14 ++++ .github/workflows/build.yml | 2 + .github/workflows/test.yml | 2 + README.md | 7 +- package-lock.json | 112 ++++++++++++++++++++++++- package.json | 6 +- 6 files changed, 139 insertions(+), 4 deletions(-) create mode 100644 .github/actions/install-npm/action.yml diff --git a/.github/actions/install-npm/action.yml b/.github/actions/install-npm/action.yml new file mode 100644 index 0000000..e2631ad --- /dev/null +++ b/.github/actions/install-npm/action.yml @@ -0,0 +1,14 @@ +name: Install NPM +description: > + Installs the NPM version required by the `engines.npm` directive in + package.json, which is required for the project to build correctly. + +runs: + using: composite + steps: + - name: Install NPM + shell: bash + run: | + npmVersion="$(node -p 'require(`${process.env.GITHUB_WORKSPACE}/package.json`).engines.npm')" + echo "Installing npm@${npmVersion}" + npm install -g "npm@${npmVersion}" diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 447d7c9..34d4542 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -15,6 +15,8 @@ jobs: - uses: actions/setup-node@v1 with: node-version: 16 + - name: Install NPM version specified in package.json + uses: ./.github/actions/install-npm - name: Install Dependencies run: npm install - name: Run Build diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3b717ce..5587b68 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -15,6 +15,8 @@ jobs: - uses: actions/setup-node@v1 with: node-version: 16 + - name: Install NPM version specified in package.json + uses: ./.github/actions/install-npm - name: Install Dependencies run: npm install - name: Run Tests diff --git a/README.md b/README.md index 273e27f..78433f3 100644 --- a/README.md +++ b/README.md @@ -70,4 +70,9 @@ Messages that do not conform to the schemas are still processed and stored. Howe - A successful AGPS response does not have an entry in the `deviceToCloud` directory because it returns a raw binary response (not JSON). In event of an error, AGPS will return JSON, which is documented. - ts should be used instead of time. The time property is included to be backwards compatible with certain versions of asset tracker version 2 firmware. Future versions will use the ts property instead. - The Location Service `deviceToCloud` endpoints (AGPS, PGPS, CELL_POS, SCELL, and WIFI) will return a standardized JSON response in event of an error, all include an `err` property with an error code, which are documented in the [REST API error code docs](https://api.nrfcloud.com/v1#section/Error-Codes). -- All GNSS `deviceToCloud` examples also work with the `appId = GPS`. Although the `GPS` appId is deprecated. \ No newline at end of file +- All GNSS `deviceToCloud` examples also work with the `appId = GPS`. Although the `GPS` appId is deprecated. + +## Node & NPM + +This project requires Node.js `>=16.20.0` and npm `>=12.0.2 <13` (enforced via +`check-node-version` from the `prepare` script). diff --git a/package-lock.json b/package-lock.json index b839829..23662ed 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,6 +23,7 @@ "@types/glob": "^7.1.3", "@types/jest": "^27.0.2", "@types/node": "^16.0.0", + "check-node-version": "4.2.1", "glob": "^7.1.7", "husky": "^7.0.0", "jest": "^27.0.6", @@ -35,7 +36,7 @@ }, "engines": { "node": ">=16.20.0", - "npm": ">=8.19.4", + "npm": ">=12.0.2 <13", "yarn": "use npm" } }, @@ -2203,6 +2204,41 @@ "node": ">=10" } }, + "node_modules/check-node-version": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/check-node-version/-/check-node-version-4.2.1.tgz", + "integrity": "sha512-YYmFYHV/X7kSJhuN/QYHUu998n/TRuDe8UenM3+m5NrkiH670lb9ILqHIvBencvJc4SDh+XcbXMR4b+TtubJiw==", + "dev": true, + "license": "Unlicense", + "dependencies": { + "chalk": "^3.0.0", + "map-values": "^1.0.1", + "minimist": "^1.2.0", + "object-filter": "^1.0.2", + "run-parallel": "^1.1.4", + "semver": "^6.3.0" + }, + "bin": { + "check-node-version": "bin.js" + }, + "engines": { + "node": ">=8.3.0" + } + }, + "node_modules/check-node-version/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/ci-info": { "version": "3.8.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", @@ -2864,6 +2900,21 @@ "dev": true, "license": "ISC" }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -4473,6 +4524,13 @@ "node": ">=0.10.0" } }, + "node_modules/map-values": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-values/-/map-values-1.0.1.tgz", + "integrity": "sha512-BbShUnr5OartXJe1GeccAWtfro11hhgNJg6G9/UtWKjVGvV5U4C09cg5nk8JUevhXODaXY+hQ3xxMUKSs62ONQ==", + "dev": true, + "license": "Public Domain" + }, "node_modules/meow": { "version": "8.1.2", "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz", @@ -4717,6 +4775,13 @@ "dev": true, "license": "MIT" }, + "node_modules/object-filter": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/object-filter/-/object-filter-1.0.2.tgz", + "integrity": "sha512-NahvP2vZcy1ZiiYah30CEPw0FpDcSkSePJBMpzl5EQgCmISijiGuJm3SPYp7U+Lf2TljyaIw3E5EgkEx/TNEVA==", + "dev": true, + "license": "MIT" + }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -5030,6 +5095,27 @@ "dev": true, "license": "MIT" }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, "node_modules/quick-lru": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", @@ -5292,6 +5378,30 @@ "@rollup/plugin-inject": "^4.0.0" } }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", diff --git a/package.json b/package.json index 3ef1617..e41f8a3 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,8 @@ "tslint": "tslint --project ./tsconfig.json", "prettier:fix": "prettier \"./__tests__/**/*.ts\" --write", "prettier:lint": "prettier --list-different \"./__tests__/**/*.ts\"", - "build": "rollup -c rollup.config.js" + "build": "rollup -c rollup.config.js", + "prepare": "check-node-version --package" }, "repository": { "type": "git", @@ -45,6 +46,7 @@ "@types/glob": "^7.1.3", "@types/jest": "^27.0.2", "@types/node": "^16.0.0", + "check-node-version": "4.2.1", "glob": "^7.1.7", "husky": "^7.0.0", "jest": "^27.0.6", @@ -89,7 +91,7 @@ } }, "engines": { - "npm": ">=8.19.4", + "npm": ">=12.0.2 <13", "yarn": "use npm", "node": ">=16.20.0" }