diff --git a/__tests__/data/package.json b/__tests__/data/package.json new file mode 100644 index 00000000..e537e200 --- /dev/null +++ b/__tests__/data/package.json @@ -0,0 +1,5 @@ +{ + "engines": { + "node": ">=14.0.0" + } +} diff --git a/__tests__/installer.test.ts b/__tests__/installer.test.ts index cd536192..d04eb582 100644 --- a/__tests__/installer.test.ts +++ b/__tests__/installer.test.ts @@ -591,6 +591,35 @@ describe('setup-node', () => { ); }); + it('reads package.json as node-version-file if provided', async () => { + // Arrange + const versionSpec = `{ + \"engines\": { + \"node\": \">=14.0.0\" + } +} +`; + const versionFile = 'package.json'; + const expectedVersionSpec = '14'; + process.env['GITHUB_WORKSPACE'] = path.join(__dirname, 'data'); + inputs['node-version-file'] = versionFile; + + parseNodeVersionSpy.mockImplementation(() => expectedVersionSpec); + existsSpy.mockImplementationOnce( + input => input === path.join(__dirname, 'data', versionFile) + ); + // Act + await main.run(); + + // Assert + expect(existsSpy).toHaveBeenCalledTimes(1); + expect(existsSpy).toHaveReturnedWith(true); + expect(parseNodeVersionSpy).toHaveBeenCalledWith(versionSpec); + expect(logSpy).toHaveBeenCalledWith( + `Resolved ${versionFile} as ${expectedVersionSpec}` + ); + }); + it('both node-version-file and node-version are provided', async () => { inputs['node-version'] = '12'; const versionSpec = 'v14'; diff --git a/src/installer.ts b/src/installer.ts index 019f2eda..8fa44b01 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -495,16 +495,24 @@ function translateArchToDistUrl(arch: string): string { } export function parseNodeVersionFile(contents: string): string { - const found = contents.match(/^(?:nodejs\s+)?v?(?[^\s]+)$/m); - const nodeVersion = found?.groups?.version; - - if (nodeVersion) { - return nodeVersion; - } - // In the case of an unknown format, // return as is and evaluate the version separately. - return contents.trim(); + let nodeVersion = contents.trim(); + + try { + // Assume all content parseable as JSON is a valid, + // NPM `package.json` file + const packageJson = JSON.parse(contents); + nodeVersion = packageJson.engines.node || nodeVersion; + + if (!nodeVersion) throw + } catch (err) { + // If not, assume it is a node version file + const found = nodeVersion.match(/^(?:nodejs\s+)?v?(?[^\s]+)$/m); + nodeVersion = found?.groups?.version || nodeVersion; + } + + return nodeVersion; } function isLatestSyntax(versionSpec): boolean {