Skip to content

Commit

Permalink
Support lts/-n aliases
Browse files Browse the repository at this point in the history
  • Loading branch information
jablko committed May 2, 2022
1 parent 0bd0676 commit 2bb90ac
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 9 deletions.
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -39,7 +39,7 @@ The `node-version` input supports the following syntax:

major versions: `12`, `14`, `16`
more specific versions: `10.15`, `14.2.0`, `16.3.0`
nvm lts syntax: `lts/erbium`, `lts/fermium`, `lts/*`
nvm lts syntax: `lts/erbium`, `lts/fermium`, `lts/*`, `lts/-n`

## Caching global packages data

Expand Down
76 changes: 73 additions & 3 deletions __tests__/installer.test.ts
Expand Up @@ -77,9 +77,9 @@ describe('setup-node', () => {
authSpy.mockImplementation(() => {});

// gets
getManifestSpy.mockImplementation(
() => <tc.IToolRelease[]>nodeTestManifest
);
getManifestSpy.mockImplementation(() => [
...(<tc.IToolRelease[]>nodeTestManifest)
]);
getDistSpy.mockImplementation(() => <im.INodeVersion>nodeTestDist);

// writes
Expand Down Expand Up @@ -839,6 +839,76 @@ describe('setup-node', () => {
);
});

it('find latest LTS version and resolve it from local cache (lts/-2)', async () => {
// arrange
inputs['node-version'] = 'lts/-2';

const toolPath = path.normalize('/cache/node/12.16.2/x64');
findSpy.mockReturnValue(toolPath);

// act
await main.run();

// assert
expect(logSpy).toHaveBeenCalledWith(
'Attempt to resolve LTS alias from manifest...'
);
expect(dbgSpy).toHaveBeenCalledWith(
'Getting manifest from actions/node-versions@main'
);
expect(dbgSpy).not.toHaveBeenCalledWith('No manifest cached');
expect(dbgSpy).toHaveBeenCalledWith(
`LTS alias '-2' for Node version 'lts/-2'`
);
expect(dbgSpy).toHaveBeenCalledWith(
`Found LTS release '12.16.2' for Node version 'lts/-2'`
);
expect(logSpy).toHaveBeenCalledWith(`Found in cache @ ${toolPath}`);
expect(cnSpy).toHaveBeenCalledWith(
`::add-path::${path.join(toolPath, 'bin')}${osm.EOL}`
);
});

it('find latest LTS version and install it from manifest (lts/-2)', async () => {
// arrange
inputs['node-version'] = 'lts/-2';

const toolPath = path.normalize('/cache/node/12.16.2/x64');
findSpy.mockImplementation(() => '');
dlSpy.mockImplementation(async () => '/some/temp/path');
exSpy.mockImplementation(async () => '/some/other/temp/path');
cacheSpy.mockImplementation(async () => toolPath);
const expectedUrl =
'https://github.com/actions/node-versions/releases/download/12.16.2-20200423.28/node-12.16.2-linux-x64.tar.gz';

// act
await main.run();

// assert
expect(logSpy).toHaveBeenCalledWith(
'Attempt to resolve LTS alias from manifest...'
);
expect(dbgSpy).toHaveBeenCalledWith(
'Getting manifest from actions/node-versions@main'
);
expect(dbgSpy).not.toHaveBeenCalledWith('No manifest cached');
expect(dbgSpy).toHaveBeenCalledWith(
`LTS alias '-2' for Node version 'lts/-2'`
);
expect(dbgSpy).toHaveBeenCalledWith(
`Found LTS release '12.16.2' for Node version 'lts/-2'`
);
expect(logSpy).toHaveBeenCalledWith('Attempting to download 12...');
expect(logSpy).toHaveBeenCalledWith(
`Acquiring 12.16.2 - ${os.arch} from ${expectedUrl}`
);
expect(logSpy).toHaveBeenCalledWith('Extracting ...');
expect(logSpy).toHaveBeenCalledWith('Adding to the cache ...');
expect(cnSpy).toHaveBeenCalledWith(
`::add-path::${path.join(toolPath, 'bin')}${osm.EOL}`
);
});

it('fail with unable to parse LTS alias (lts/)', async () => {
// arrange
inputs['node-version'] = 'lts/';
Expand Down
18 changes: 13 additions & 5 deletions src/installer.ts
Expand Up @@ -45,6 +45,7 @@ export async function getNode(

// No try-catch since it's not possible to resolve LTS alias without manifest
manifest = await getManifest(auth);
manifest.reverse();

versionSpec = resolveLtsAliasFromManifest(versionSpec, stable, manifest);
}
Expand Down Expand Up @@ -216,13 +217,20 @@ function resolveLtsAliasFromManifest(

core.debug(`LTS alias '${alias}' for Node version '${versionSpec}'`);

// Supported formats are `lts/<alias>` and `lts/*`. Where asterisk means highest possible LTS.
// Supported formats are `lts/<alias>`, `lts/*`, and `lts/-n`. Where asterisk means highest possible LTS and -n means the nth-highest.
const n = Number(alias);
const aliases = Object.fromEntries(
manifest
.filter(x => x.stable === stable)
.map(x => [x.lts?.toLowerCase(), x])
);
const numbered = Object.values(aliases);
const release =
alias === '*'
? manifest.find(x => !!x.lts && x.stable === stable)
: manifest.find(
x => x.lts?.toLowerCase() === alias && x.stable === stable
);
? numbered[numbered.length - 1]
: n < 0
? numbered[numbered.length - 1 + n]
: aliases[alias];

if (!release) {
throw new Error(
Expand Down

0 comments on commit 2bb90ac

Please sign in to comment.