From b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 Mon Sep 17 00:00:00 2001 From: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com> Date: Thu, 14 Dec 2023 07:53:26 -0500 Subject: [PATCH] Fix node-version-file interprets entire package.json as a version (#865) --- __tests__/main.test.ts | 1 + dist/cache-save/index.js | 22 +++++++++++++++++++--- dist/setup/index.js | 30 ++++++++++++++++++++++++++---- src/main.ts | 12 +++++++++++- src/util.ts | 24 +++++++++++++++++++++--- 5 files changed, 78 insertions(+), 11 deletions(-) diff --git a/__tests__/main.test.ts b/__tests__/main.test.ts index b57248757..36024e650 100644 --- a/__tests__/main.test.ts +++ b/__tests__/main.test.ts @@ -101,6 +101,7 @@ describe('main tests', () => { ${' 14.1.0 '} | ${'14.1.0'} ${'{"volta": {"node": ">=14.0.0 <=17.0.0"}}'}| ${'>=14.0.0 <=17.0.0'} ${'{"engines": {"node": "17.0.0"}}'} | ${'17.0.0'} + ${'{}'} | ${null} `.it('parses "$contents"', ({contents, expected}) => { expect(util.parseNodeVersionFile(contents)).toBe(expected); }); diff --git a/dist/cache-save/index.js b/dist/cache-save/index.js index 67f22cd3c..ece5ae39a 100644 --- a/dist/cache-save/index.js +++ b/dist/cache-save/index.js @@ -83338,9 +83338,25 @@ function parseNodeVersionFile(contents) { let nodeVersion; // Try parsing the file as an NPM `package.json` file. try { - nodeVersion = (_a = JSON.parse(contents).volta) === null || _a === void 0 ? void 0 : _a.node; - if (!nodeVersion) - nodeVersion = (_b = JSON.parse(contents).engines) === null || _b === void 0 ? void 0 : _b.node; + const manifest = JSON.parse(contents); + // JSON can parse numbers, but that's handled later + if (typeof manifest === 'object') { + nodeVersion = (_a = manifest.volta) === null || _a === void 0 ? void 0 : _a.node; + if (!nodeVersion) + nodeVersion = (_b = manifest.engines) === null || _b === void 0 ? void 0 : _b.node; + // if contents are an object, we parsed JSON + // this can happen if node-version-file is a package.json + // yet contains no volta.node or engines.node + // + // if node-version file is _not_ json, control flow + // will not have reached these lines. + // + // And because we've reached here, we know the contents + // *are* JSON, so no further string parsing makes sense. + if (!nodeVersion) { + return null; + } + } } catch (_d) { core.info('Node version file is not JSON file'); diff --git a/dist/setup/index.js b/dist/setup/index.js index 0512f3a79..c4b448b1d 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -93728,7 +93728,13 @@ function resolveVersionInput() { if (!fs_1.default.existsSync(versionFilePath)) { throw new Error(`The specified node version file at: ${versionFilePath} does not exist`); } - version = (0, util_1.parseNodeVersionFile)(fs_1.default.readFileSync(versionFilePath, 'utf8')); + const parsedVersion = (0, util_1.parseNodeVersionFile)(fs_1.default.readFileSync(versionFilePath, 'utf8')); + if (parsedVersion) { + version = parsedVersion; + } + else { + core.warning(`Could not determine node version from ${versionFilePath}. Falling back`); + } core.info(`Resolved ${versionFileInput} as ${version}`); } return version; @@ -93783,9 +93789,25 @@ function parseNodeVersionFile(contents) { let nodeVersion; // Try parsing the file as an NPM `package.json` file. try { - nodeVersion = (_a = JSON.parse(contents).volta) === null || _a === void 0 ? void 0 : _a.node; - if (!nodeVersion) - nodeVersion = (_b = JSON.parse(contents).engines) === null || _b === void 0 ? void 0 : _b.node; + const manifest = JSON.parse(contents); + // JSON can parse numbers, but that's handled later + if (typeof manifest === 'object') { + nodeVersion = (_a = manifest.volta) === null || _a === void 0 ? void 0 : _a.node; + if (!nodeVersion) + nodeVersion = (_b = manifest.engines) === null || _b === void 0 ? void 0 : _b.node; + // if contents are an object, we parsed JSON + // this can happen if node-version-file is a package.json + // yet contains no volta.node or engines.node + // + // if node-version file is _not_ json, control flow + // will not have reached these lines. + // + // And because we've reached here, we know the contents + // *are* JSON, so no further string parsing makes sense. + if (!nodeVersion) { + return null; + } + } } catch (_d) { core.info('Node version file is not JSON file'); diff --git a/src/main.ts b/src/main.ts index ac0517665..34f943104 100644 --- a/src/main.ts +++ b/src/main.ts @@ -105,7 +105,17 @@ function resolveVersionInput(): string { ); } - version = parseNodeVersionFile(fs.readFileSync(versionFilePath, 'utf8')); + const parsedVersion = parseNodeVersionFile( + fs.readFileSync(versionFilePath, 'utf8') + ); + + if (parsedVersion) { + version = parsedVersion; + } else { + core.warning( + `Could not determine node version from ${versionFilePath}. Falling back` + ); + } core.info(`Resolved ${versionFileInput} as ${version}`); } diff --git a/src/util.ts b/src/util.ts index 3ae94a2dc..0b2b14906 100644 --- a/src/util.ts +++ b/src/util.ts @@ -1,13 +1,31 @@ import * as core from '@actions/core'; import * as exec from '@actions/exec'; -export function parseNodeVersionFile(contents: string): string { +export function parseNodeVersionFile(contents: string): string | null { let nodeVersion: string | undefined; // Try parsing the file as an NPM `package.json` file. try { - nodeVersion = JSON.parse(contents).volta?.node; - if (!nodeVersion) nodeVersion = JSON.parse(contents).engines?.node; + const manifest = JSON.parse(contents); + + // JSON can parse numbers, but that's handled later + if (typeof manifest === 'object') { + nodeVersion = manifest.volta?.node; + if (!nodeVersion) nodeVersion = manifest.engines?.node; + + // if contents are an object, we parsed JSON + // this can happen if node-version-file is a package.json + // yet contains no volta.node or engines.node + // + // if node-version file is _not_ json, control flow + // will not have reached these lines. + // + // And because we've reached here, we know the contents + // *are* JSON, so no further string parsing makes sense. + if (!nodeVersion) { + return null; + } + } } catch { core.info('Node version file is not JSON file'); }