Skip to content

Commit d00b893

Browse files
committed
Support lts/-n aliases
1 parent 0bd0676 commit d00b893

File tree

4 files changed

+100
-12
lines changed

4 files changed

+100
-12
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ The `node-version` input supports the following syntax:
3939

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

4444
## Caching global packages data
4545

__tests__/installer.test.ts

Lines changed: 73 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,9 @@ describe('setup-node', () => {
7777
authSpy.mockImplementation(() => {});
7878

7979
// gets
80-
getManifestSpy.mockImplementation(
81-
() => <tc.IToolRelease[]>nodeTestManifest
82-
);
80+
getManifestSpy.mockImplementation(() => [
81+
...(<tc.IToolRelease[]>nodeTestManifest)
82+
]);
8383
getDistSpy.mockImplementation(() => <im.INodeVersion>nodeTestDist);
8484

8585
// writes
@@ -839,6 +839,76 @@ describe('setup-node', () => {
839839
);
840840
});
841841

842+
it('find latest LTS version and resolve it from local cache (lts/-2)', async () => {
843+
// arrange
844+
inputs['node-version'] = 'lts/-2';
845+
846+
const toolPath = path.normalize('/cache/node/12.16.2/x64');
847+
findSpy.mockReturnValue(toolPath);
848+
849+
// act
850+
await main.run();
851+
852+
// assert
853+
expect(logSpy).toHaveBeenCalledWith(
854+
'Attempt to resolve LTS alias from manifest...'
855+
);
856+
expect(dbgSpy).toHaveBeenCalledWith(
857+
'Getting manifest from actions/node-versions@main'
858+
);
859+
expect(dbgSpy).not.toHaveBeenCalledWith('No manifest cached');
860+
expect(dbgSpy).toHaveBeenCalledWith(
861+
`LTS alias '-2' for Node version 'lts/-2'`
862+
);
863+
expect(dbgSpy).toHaveBeenCalledWith(
864+
`Found LTS release '12.16.2' for Node version 'lts/-2'`
865+
);
866+
expect(logSpy).toHaveBeenCalledWith(`Found in cache @ ${toolPath}`);
867+
expect(cnSpy).toHaveBeenCalledWith(
868+
`::add-path::${path.join(toolPath, 'bin')}${osm.EOL}`
869+
);
870+
});
871+
872+
it('find latest LTS version and install it from manifest (lts/-2)', async () => {
873+
// arrange
874+
inputs['node-version'] = 'lts/-2';
875+
876+
const toolPath = path.normalize('/cache/node/12.16.2/x64');
877+
findSpy.mockImplementation(() => '');
878+
dlSpy.mockImplementation(async () => '/some/temp/path');
879+
exSpy.mockImplementation(async () => '/some/other/temp/path');
880+
cacheSpy.mockImplementation(async () => toolPath);
881+
const expectedUrl =
882+
'https://github.com/actions/node-versions/releases/download/12.16.2-20200423.28/node-12.16.2-linux-x64.tar.gz';
883+
884+
// act
885+
await main.run();
886+
887+
// assert
888+
expect(logSpy).toHaveBeenCalledWith(
889+
'Attempt to resolve LTS alias from manifest...'
890+
);
891+
expect(dbgSpy).toHaveBeenCalledWith(
892+
'Getting manifest from actions/node-versions@main'
893+
);
894+
expect(dbgSpy).not.toHaveBeenCalledWith('No manifest cached');
895+
expect(dbgSpy).toHaveBeenCalledWith(
896+
`LTS alias '-2' for Node version 'lts/-2'`
897+
);
898+
expect(dbgSpy).toHaveBeenCalledWith(
899+
`Found LTS release '12.16.2' for Node version 'lts/-2'`
900+
);
901+
expect(logSpy).toHaveBeenCalledWith('Attempting to download 12...');
902+
expect(logSpy).toHaveBeenCalledWith(
903+
`Acquiring 12.16.2 - ${os.arch} from ${expectedUrl}`
904+
);
905+
expect(logSpy).toHaveBeenCalledWith('Extracting ...');
906+
expect(logSpy).toHaveBeenCalledWith('Adding to the cache ...');
907+
expect(cnSpy).toHaveBeenCalledWith(
908+
`::add-path::${path.join(toolPath, 'bin')}${osm.EOL}`
909+
);
910+
});
911+
842912
it('fail with unable to parse LTS alias (lts/)', async () => {
843913
// arrange
844914
inputs['node-version'] = 'lts/';

dist/setup/index.js

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62349,6 +62349,8 @@ function getNode(versionSpec, stable, checkLatest, auth, arch = os.arch()) {
6234962349
core.info('Attempt to resolve LTS alias from manifest...');
6235062350
// No try-catch since it's not possible to resolve LTS alias without manifest
6235162351
manifest = yield getManifest(auth);
62352+
// Reverse it so later Object.fromEntries() gets the latest version of each LTS
62353+
manifest.reverse();
6235262354
versionSpec = resolveLtsAliasFromManifest(versionSpec, stable, manifest);
6235362355
}
6235462356
if (checkLatest) {
@@ -62474,10 +62476,17 @@ function resolveLtsAliasFromManifest(versionSpec, stable, manifest) {
6247462476
throw new Error(`Unable to parse LTS alias for Node version '${versionSpec}'`);
6247562477
}
6247662478
core.debug(`LTS alias '${alias}' for Node version '${versionSpec}'`);
62477-
// Supported formats are `lts/<alias>` and `lts/*`. Where asterisk means highest possible LTS.
62479+
// Supported formats are `lts/<alias>`, `lts/*`, and `lts/-n`. Where asterisk means highest possible LTS and -n means the nth-highest.
62480+
const n = Number(alias);
62481+
const aliases = Object.fromEntries(manifest
62482+
.filter(x => x.stable === stable)
62483+
.map(x => { var _a; return [(_a = x.lts) === null || _a === void 0 ? void 0 : _a.toLowerCase(), x]; }));
62484+
const numbered = Object.values(aliases);
6247862485
const release = alias === '*'
62479-
? manifest.find(x => !!x.lts && x.stable === stable)
62480-
: manifest.find(x => { var _a; return ((_a = x.lts) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === alias && x.stable === stable; });
62486+
? numbered[numbered.length - 1]
62487+
: n < 0
62488+
? numbered[numbered.length - 1 + n]
62489+
: aliases[alias];
6248162490
if (!release) {
6248262491
throw new Error(`Unable to find LTS release '${alias}' for Node version '${versionSpec}'.`);
6248362492
}

src/installer.ts

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ export async function getNode(
4545

4646
// No try-catch since it's not possible to resolve LTS alias without manifest
4747
manifest = await getManifest(auth);
48+
// Reverse it so later Object.fromEntries() gets the latest version of each LTS
49+
manifest.reverse();
4850

4951
versionSpec = resolveLtsAliasFromManifest(versionSpec, stable, manifest);
5052
}
@@ -216,13 +218,20 @@ function resolveLtsAliasFromManifest(
216218

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

219-
// Supported formats are `lts/<alias>` and `lts/*`. Where asterisk means highest possible LTS.
221+
// Supported formats are `lts/<alias>`, `lts/*`, and `lts/-n`. Where asterisk means highest possible LTS and -n means the nth-highest.
222+
const n = Number(alias);
223+
const aliases = Object.fromEntries(
224+
manifest
225+
.filter(x => x.stable === stable)
226+
.map(x => [x.lts?.toLowerCase(), x])
227+
);
228+
const numbered = Object.values(aliases);
220229
const release =
221230
alias === '*'
222-
? manifest.find(x => !!x.lts && x.stable === stable)
223-
: manifest.find(
224-
x => x.lts?.toLowerCase() === alias && x.stable === stable
225-
);
231+
? numbered[numbered.length - 1]
232+
: n < 0
233+
? numbered[numbered.length - 1 + n]
234+
: aliases[alias];
226235

227236
if (!release) {
228237
throw new Error(

0 commit comments

Comments
 (0)