fix: support comments in .nvmrc files

This commit is contained in:
BM Cho 2026-07-17 17:07:36 +08:00
parent 1b7c366466
commit 914052aadc
4 changed files with 73 additions and 6 deletions

View File

@ -216,6 +216,35 @@ describe('main tests', () => {
expect(util.getNodeVersionFromFile('file')).toBe(expected);
});
each`
name | contents | expected
${'ignores blank lines and comments'} | ${'# use the version below\n\n 20.16.0 # maintenance release\n'} | ${'20.16.0'}
${'strips an inline comment'} | ${'v20.16.0 # maintenance release'} | ${'20.16.0'}
${'preserves an alias before a comment'} | ${'lts/* # use the latest LTS'} | ${'lts/*'}
${'rejects a comment-only file'} | ${'# comment only'} | ${null}
${'rejects comments and whitespace only'} | ${'#\r\n # another comment\r\n'} | ${null}
`.it('$name', ({contents, expected}: any) => {
const existsSpy = jest.spyOn(fs, 'existsSync');
existsSpy.mockImplementation(() => true);
const readFileSpy = jest.spyOn(fs, 'readFileSync');
readFileSpy.mockImplementation(() => contents);
expect(util.getNodeVersionFromFile('.nvmrc')).toBe(expected);
});
it('preserves .tool-versions parsing', () => {
const existsSpy = jest.spyOn(fs, 'existsSync');
existsSpy.mockImplementation(() => true);
const readFileSpy = jest.spyOn(fs, 'readFileSync');
readFileSpy.mockImplementation(
() => 'ruby 3.3.0\nnodejs 20.16.0\npython 3.12.0'
);
expect(util.getNodeVersionFromFile('.tool-versions')).toBe('20.16.0');
});
});
describe('printEnvDetailsAndSetOutput', () => {

View File

@ -92709,8 +92709,19 @@ function getNodeVersionFromFile(versionFilePath) {
catch {
core.info('Node version file is not JSON file');
}
const found = contents.match(/^(?:node(js)?\s+)?v?(?<version>[^\s]+)$/m);
return found?.groups?.version ?? contents.trim();
let versionFileContents = contents;
if (path.basename(versionFilePath) === '.nvmrc') {
versionFileContents = contents
.split(/\r?\n/)
.map(line => line.replace(/#.*/, '').trim())
.filter(Boolean)
.join('\n');
if (!versionFileContents) {
return null;
}
}
const found = versionFileContents.match(/^(?:node(js)?\s+)?v?(?<version>[^\s]+)$/m);
return found?.groups?.version ?? versionFileContents.trim();
}
async function printEnvDetailsAndSetOutput() {
core.startGroup('Environment details');

15
dist/setup/index.js vendored
View File

@ -98103,8 +98103,19 @@ function getNodeVersionFromFile(versionFilePath) {
catch {
core_info('Node version file is not JSON file');
}
const found = contents.match(/^(?:node(js)?\s+)?v?(?<version>[^\s]+)$/m);
return found?.groups?.version ?? contents.trim();
let versionFileContents = contents;
if (external_path_default().basename(versionFilePath) === '.nvmrc') {
versionFileContents = contents
.split(/\r?\n/)
.map(line => line.replace(/#.*/, '').trim())
.filter(Boolean)
.join('\n');
if (!versionFileContents) {
return null;
}
}
const found = versionFileContents.match(/^(?:node(js)?\s+)?v?(?<version>[^\s]+)$/m);
return found?.groups?.version ?? versionFileContents.trim();
}
async function printEnvDetailsAndSetOutput() {
startGroup('Environment details');

View File

@ -68,8 +68,24 @@ export function getNodeVersionFromFile(versionFilePath: string): string | null {
core.info('Node version file is not JSON file');
}
const found = contents.match(/^(?:node(js)?\s+)?v?(?<version>[^\s]+)$/m);
return found?.groups?.version ?? contents.trim();
let versionFileContents = contents;
if (path.basename(versionFilePath) === '.nvmrc') {
versionFileContents = contents
.split(/\r?\n/)
.map(line => line.replace(/#.*/, '').trim())
.filter(Boolean)
.join('\n');
if (!versionFileContents) {
return null;
}
}
const found = versionFileContents.match(
/^(?:node(js)?\s+)?v?(?<version>[^\s]+)$/m
);
return found?.groups?.version ?? versionFileContents.trim();
}
export async function printEnvDetailsAndSetOutput() {