From 21a7249b40d8f95e7721e450fd18764adb1648a7 Mon Sep 17 00:00:00 2001 From: Luke Karrys Date: Fri, 27 Oct 2023 20:51:20 -0700 Subject: [PATCH] chore: add check engines script to CI (#2922) --- .github/scripts/check-engines.js | 41 ++++++++++++++++++++++++++++++++ .github/workflows/tests.yml | 17 +++++++++++++ package.json | 2 +- 3 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 .github/scripts/check-engines.js diff --git a/.github/scripts/check-engines.js b/.github/scripts/check-engines.js new file mode 100644 index 0000000000..80da7a03ed --- /dev/null +++ b/.github/scripts/check-engines.js @@ -0,0 +1,41 @@ +const { join } = require('path') +const semver = require('semver') +const Arborist = require('@npmcli/arborist') + +const run = async (path, useEngines) => { + const pkgPath = join(path, 'package.json') + const pkg = require(pkgPath) + + const engines = useEngines || pkg.engines.node + + const arb = new Arborist({ path }) + const tree = await arb.loadActual({ forceActual: true }) + const deps = await tree.querySelectorAll(`#${pkg.name} > .prod:attr(engines, [node])`) + + const invalid = [] + for (const dep of deps) { + const depEngines = dep.target.package.engines.node + if (!semver.subset(engines, depEngines)) { + invalid.push({ + name: `${dep.name}@${dep.version}`, + location: dep.location, + engines: depEngines + }) + } + } + + if (invalid.length) { + const msg = 'The following production dependencies are not compatible with ' + +`\`engines.node: ${engines}\` found in \`${pkgPath}\`:\n` + invalid.map((dep) => [ + `${dep.name}:`, + ` engines.node: ${dep.engines}`, + ` location: ${dep.location}` + ].join('\n')).join('\n') + throw new Error(msg) + } +} + +run(process.cwd(), ...process.argv.slice(2)).then(() => console.log('Success')).catch((err) => { + console.error(err) + process.exitCode = 1 +}) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 310b4f06ea..29525b8a73 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -18,6 +18,23 @@ jobs: - uses: actions/checkout@v4 - run: pip install --user ruff - run: ruff --output-format=github --select="E,F,PLC,PLE,UP,W,YTT" --ignore="E721,PLC1901,S101,UP031" --target-version=py38 . + Engines: + runs-on: ubuntu-latest + steps: + - name: Checkout Repository + uses: actions/checkout@v3 + - name: Use Node.js 20.x + uses: actions/setup-node@v3 + with: + node-version: 20.x + - name: Install Dependencies + run: | + npm install --no-progress + - name: Check Engines + run: | + # TODO: move this to its own action + npm install @npmcli/arborist@7 semver@7 --no-save + node .github/scripts/check-engines.js Tests: needs: Lint_Python # Lint_Python takes ~5 seconds, so wait for it to pass before running the full matrix of tests. strategy: diff --git a/package.json b/package.json index d861261002..a8fd8a6fff 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ "standard": "^17.0.0" }, "scripts": { - "lint": "standard */*.js test/**/*.js", + "lint": "standard \"*/*.js\" \"test/**/*.js\" \".github/**/*.js\"", "test": "npm run lint && mocha --timeout 15000 --reporter=test/reporter.js test/test-download.js test/test-*" } }