From 88d5bfde3141931c4d6926ff20c837c589f97662 Mon Sep 17 00:00:00 2001 From: Gordey Doronin Date: Thu, 17 Jun 2021 17:51:02 +0200 Subject: [PATCH 01/18] Support LTS aliases --- __tests__/data/versions-manifest.json | 5 +++ __tests__/installer.test.ts | 64 +++++++++++++++++++++++++++ src/installer.ts | 38 ++++++++++++++++ 3 files changed, 107 insertions(+) diff --git a/__tests__/data/versions-manifest.json b/__tests__/data/versions-manifest.json index d313b16..4cf2cce 100644 --- a/__tests__/data/versions-manifest.json +++ b/__tests__/data/versions-manifest.json @@ -2,6 +2,7 @@ { "version": "14.0.0", "stable": true, + "lts": "Fermium", "release_url": "https://github.com/actions/node-versions/releases/tag/14.0.0-20200423.30", "files": [ { @@ -52,6 +53,7 @@ { "version": "12.16.2", "stable": true, + "lts": "Erbium", "release_url": "https://github.com/actions/node-versions/releases/tag/12.16.2-20200423.28", "files": [ { @@ -77,6 +79,7 @@ { "version": "10.20.1", "stable": true, + "lts": "Dubnium", "release_url": "https://github.com/actions/node-versions/releases/tag/10.20.1-20200423.27", "files": [ { @@ -102,6 +105,7 @@ { "version": "8.17.0", "stable": true, + "lts": "Carbon", "release_url": "https://github.com/actions/node-versions/releases/tag/8.17.0-20200423.26", "files": [ { @@ -127,6 +131,7 @@ { "version": "6.17.1", "stable": true, + "lts": "Boron", "release_url": "https://github.com/actions/node-versions/releases/tag/6.17.1-20200423.25", "files": [ { diff --git a/__tests__/installer.test.ts b/__tests__/installer.test.ts index 4fe7577..3bcaf58 100644 --- a/__tests__/installer.test.ts +++ b/__tests__/installer.test.ts @@ -134,6 +134,7 @@ describe('setup-node', () => { let match = await tc.findFromManifest('12.16.2', true, versions); expect(match).toBeDefined(); expect(match?.version).toBe('12.16.2'); + expect((match as any).lts).toBe('Erbium') }); it('can find 12 from manifest on linux', async () => { @@ -148,6 +149,7 @@ describe('setup-node', () => { let match = await tc.findFromManifest('12.16.2', true, versions); expect(match).toBeDefined(); expect(match?.version).toBe('12.16.2'); + expect((match as any).lts).toBe('Erbium') }); it('can find 10 from manifest on windows', async () => { @@ -162,6 +164,7 @@ describe('setup-node', () => { let match = await tc.findFromManifest('10', true, versions); expect(match).toBeDefined(); expect(match?.version).toBe('10.20.1'); + expect((match as any).lts).toBe('Dubnium') }); //-------------------------------------------------- @@ -217,6 +220,10 @@ describe('setup-node', () => { expect(cnSpy).toHaveBeenCalledWith('::error::' + errMsg + osm.EOL); }); + //-------------------------------------------------- + // Manifest tests + //-------------------------------------------------- + it('downloads a version from a manifest match', async () => { os.platform = 'linux'; os.arch = 'x64'; @@ -525,4 +532,61 @@ describe('setup-node', () => { expect(cnSpy).toHaveBeenCalledWith(`::add-path::${expPath}${osm.EOL}`); }); }); + + describe('LTS version', () => { + it('find latest LTS version and resolve it from local cache (lts/erbium)', async () => { + // arrange + os.platform = 'linux'; + os.arch = 'x64'; + + inputs['node-version'] = 'lts/erbium'; + inputs.stable = 'true'; + + const toolPath = path.normalize('/cache/node/12.16.2/x64'); + findSpy.mockReturnValue(toolPath); + + // act + await main.run(); + + // assert + expect(logSpy).toHaveBeenCalledWith('Attempt to resolve the latest version from manifest...'); + expect(warningSpy).toHaveBeenCalledWith('LTS version is provided. For LTS versions `check-latest` will be automatically set to true') + expect(dbgSpy).toHaveBeenCalledWith(`LTS alias 'erbium' for Node version 'lts/erbium'`) + expect(dbgSpy).toHaveBeenCalledWith(`Found LTS release 'erbium' for Node version 'lts/erbium'`) + expect(logSpy).toHaveBeenCalledWith("Resolved as '12.16.2'"); + expect(logSpy).toHaveBeenCalledWith(`Found in cache @ ${toolPath}`); + expect(cnSpy).toHaveBeenCalledWith(`::add-path::${toolPath}/bin${osm.EOL}`); + }); + + it('find latest LTS version and install it from manifest (lts/erbium)', async () => { + // arrange + os.platform = 'linux'; + os.arch = 'x64'; + + inputs['node-version'] = 'lts/erbium'; + inputs.stable = 'true'; + + 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 the latest version from manifest...'); + expect(warningSpy).toHaveBeenCalledWith('LTS version is provided. For LTS versions `check-latest` will be automatically set to true') + expect(dbgSpy).toHaveBeenCalledWith(`LTS alias 'erbium' for Node version 'lts/erbium'`) + expect(dbgSpy).toHaveBeenCalledWith(`Found LTS release 'erbium' for Node version 'lts/erbium'`) + expect(logSpy).toHaveBeenCalledWith("Resolved as '12.16.2'"); + expect(logSpy).toHaveBeenCalledWith("Attempting to download 12.16.2..."); + 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::${toolPath}/bin${osm.EOL}`); + }) + }) }); diff --git a/src/installer.ts b/src/installer.ts index cc45e22..2351883 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -34,6 +34,11 @@ export async function getNode( let osPlat: string = os.platform(); let osArch: string = translateArchToDistUrl(arch); + if (isLts(versionSpec)) { + core.warning('LTS version is provided. For LTS versions `check-latest` will be automatically set to true'); + checkLatest = true; + } + if (checkLatest) { core.info('Attempt to resolve the latest version from manifest...'); const resolvedVersion = await resolveVersionFromManifest( @@ -170,6 +175,34 @@ export async function getNode( core.addPath(toolPath); } +function isLts(versionSpec: string): boolean { + return versionSpec.startsWith('lts') +} + +function findLtsVersionFromManifest( + versionSpec: string, + stable: boolean, + candidates: Array +): string { + const alias = versionSpec.split('lts/')[1]?.toLowerCase(); + + if (!alias) { + throw new Error(`Unexpected LTS alias '${alias}' for Node version '${versionSpec}'`); + } + + core.debug(`LTS alias '${alias}' for Node version '${versionSpec}'`); + + const release = candidates.find(x => x.lts?.toLowerCase() === alias && x.stable === stable); + + if (!release) { + throw new Error(`Unable to find LTS release '${alias}' for Node version '${versionSpec}'.`); + } + + core.debug(`Found LTS release '${alias}' for Node version '${versionSpec}'`); + + return release.version.split('.')[0]; +} + async function getInfoFromManifest( versionSpec: string, stable: boolean, @@ -183,6 +216,11 @@ async function getInfoFromManifest( auth, 'main' ); + + if (isLts(versionSpec)) { + versionSpec = findLtsVersionFromManifest(versionSpec, stable, releases); + } + const rel = await tc.findFromManifest(versionSpec, stable, releases, osArch); if (rel && rel.files.length > 0) { From c8889b24a3681f12ac9befb673b9b5b6aef41b33 Mon Sep 17 00:00:00 2001 From: Gordey Doronin Date: Thu, 17 Jun 2021 18:34:09 +0200 Subject: [PATCH 02/18] Support lts/* alias --- __tests__/installer.test.ts | 59 +++++++++++++++++++++++++++++++++++-- src/installer.ts | 6 ++-- 2 files changed, 61 insertions(+), 4 deletions(-) diff --git a/__tests__/installer.test.ts b/__tests__/installer.test.ts index 3bcaf58..6c7559d 100644 --- a/__tests__/installer.test.ts +++ b/__tests__/installer.test.ts @@ -552,7 +552,7 @@ describe('setup-node', () => { expect(logSpy).toHaveBeenCalledWith('Attempt to resolve the latest version from manifest...'); expect(warningSpy).toHaveBeenCalledWith('LTS version is provided. For LTS versions `check-latest` will be automatically set to true') expect(dbgSpy).toHaveBeenCalledWith(`LTS alias 'erbium' for Node version 'lts/erbium'`) - expect(dbgSpy).toHaveBeenCalledWith(`Found LTS release 'erbium' for Node version 'lts/erbium'`) + expect(dbgSpy).toHaveBeenCalledWith(`Found LTS release '12.16.2' for Node version 'lts/erbium'`) expect(logSpy).toHaveBeenCalledWith("Resolved as '12.16.2'"); expect(logSpy).toHaveBeenCalledWith(`Found in cache @ ${toolPath}`); expect(cnSpy).toHaveBeenCalledWith(`::add-path::${toolPath}/bin${osm.EOL}`); @@ -580,7 +580,7 @@ describe('setup-node', () => { expect(logSpy).toHaveBeenCalledWith('Attempt to resolve the latest version from manifest...'); expect(warningSpy).toHaveBeenCalledWith('LTS version is provided. For LTS versions `check-latest` will be automatically set to true') expect(dbgSpy).toHaveBeenCalledWith(`LTS alias 'erbium' for Node version 'lts/erbium'`) - expect(dbgSpy).toHaveBeenCalledWith(`Found LTS release 'erbium' for Node version 'lts/erbium'`) + expect(dbgSpy).toHaveBeenCalledWith(`Found LTS release '12.16.2' for Node version 'lts/erbium'`) expect(logSpy).toHaveBeenCalledWith("Resolved as '12.16.2'"); expect(logSpy).toHaveBeenCalledWith("Attempting to download 12.16.2..."); expect(logSpy).toHaveBeenCalledWith(`Acquiring 12.16.2 - ${os.arch} from ${expectedUrl}`); @@ -588,5 +588,60 @@ describe('setup-node', () => { expect(logSpy).toHaveBeenCalledWith('Adding to the cache ...'); expect(cnSpy).toHaveBeenCalledWith(`::add-path::${toolPath}/bin${osm.EOL}`); }) + + it('find latest LTS version and resolve it from local cache (lts/*)', async () => { + // arrange + os.platform = 'linux'; + os.arch = 'x64'; + + inputs['node-version'] = 'lts/*'; + inputs.stable = 'true'; + + const toolPath = path.normalize('/cache/node/14.0.0/x64'); + findSpy.mockReturnValue(toolPath); + + // act + await main.run(); + + // assert + expect(logSpy).toHaveBeenCalledWith('Attempt to resolve the latest version from manifest...'); + expect(warningSpy).toHaveBeenCalledWith('LTS version is provided. For LTS versions `check-latest` will be automatically set to true') + expect(dbgSpy).toHaveBeenCalledWith(`LTS alias '*' for Node version 'lts/*'`) + expect(dbgSpy).toHaveBeenCalledWith(`Found LTS release '14.0.0' for Node version 'lts/*'`) + expect(logSpy).toHaveBeenCalledWith("Resolved as '14.0.0'"); + expect(logSpy).toHaveBeenCalledWith(`Found in cache @ ${toolPath}`); + expect(cnSpy).toHaveBeenCalledWith(`::add-path::${toolPath}/bin${osm.EOL}`); + }); + + it('find latest LTS version and install it from manifest (lts/*)', async () => { + // arrange + os.platform = 'linux'; + os.arch = 'x64'; + + inputs['node-version'] = 'lts/*'; + inputs.stable = 'true'; + + const toolPath = path.normalize('/cache/node/14.0.0/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/14.0.0-20200423.30/node-14.0.0-linux-x64.tar.gz'; + + // act + await main.run(); + + // assert + expect(logSpy).toHaveBeenCalledWith('Attempt to resolve the latest version from manifest...'); + expect(warningSpy).toHaveBeenCalledWith('LTS version is provided. For LTS versions `check-latest` will be automatically set to true') + expect(dbgSpy).toHaveBeenCalledWith(`LTS alias '*' for Node version 'lts/*'`) + expect(dbgSpy).toHaveBeenCalledWith(`Found LTS release '14.0.0' for Node version 'lts/*'`) + expect(logSpy).toHaveBeenCalledWith("Resolved as '14.0.0'"); + expect(logSpy).toHaveBeenCalledWith("Attempting to download 14.0.0..."); + expect(logSpy).toHaveBeenCalledWith(`Acquiring 14.0.0 - ${os.arch} from ${expectedUrl}`); + expect(logSpy).toHaveBeenCalledWith('Extracting ...'); + expect(logSpy).toHaveBeenCalledWith('Adding to the cache ...'); + expect(cnSpy).toHaveBeenCalledWith(`::add-path::${toolPath}/bin${osm.EOL}`); + }) }) }); diff --git a/src/installer.ts b/src/installer.ts index 2351883..84c57c0 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -192,13 +192,15 @@ function findLtsVersionFromManifest( core.debug(`LTS alias '${alias}' for Node version '${versionSpec}'`); - const release = candidates.find(x => x.lts?.toLowerCase() === alias && x.stable === stable); + const release = alias === '*' + ? candidates.find(x => !!x.lts && x.stable === stable) + : candidates.find(x => x.lts?.toLowerCase() === alias && x.stable === stable); if (!release) { throw new Error(`Unable to find LTS release '${alias}' for Node version '${versionSpec}'.`); } - core.debug(`Found LTS release '${alias}' for Node version '${versionSpec}'`); + core.debug(`Found LTS release '${release.version}' for Node version '${versionSpec}'`); return release.version.split('.')[0]; } From fa68745dc062afab6c154b4b956c74b5f450ee50 Mon Sep 17 00:00:00 2001 From: Gordey Doronin Date: Thu, 17 Jun 2021 18:53:38 +0200 Subject: [PATCH 03/18] Test coverage for uknown and malformed aliases --- __tests__/installer.test.ts | 53 ++++++++++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 4 deletions(-) diff --git a/__tests__/installer.test.ts b/__tests__/installer.test.ts index 6c7559d..13a1c55 100644 --- a/__tests__/installer.test.ts +++ b/__tests__/installer.test.ts @@ -549,8 +549,8 @@ describe('setup-node', () => { await main.run(); // assert - expect(logSpy).toHaveBeenCalledWith('Attempt to resolve the latest version from manifest...'); expect(warningSpy).toHaveBeenCalledWith('LTS version is provided. For LTS versions `check-latest` will be automatically set to true') + expect(logSpy).toHaveBeenCalledWith('Attempt to resolve the latest version from manifest...'); expect(dbgSpy).toHaveBeenCalledWith(`LTS alias 'erbium' for Node version 'lts/erbium'`) expect(dbgSpy).toHaveBeenCalledWith(`Found LTS release '12.16.2' for Node version 'lts/erbium'`) expect(logSpy).toHaveBeenCalledWith("Resolved as '12.16.2'"); @@ -577,8 +577,8 @@ describe('setup-node', () => { await main.run(); // assert - expect(logSpy).toHaveBeenCalledWith('Attempt to resolve the latest version from manifest...'); expect(warningSpy).toHaveBeenCalledWith('LTS version is provided. For LTS versions `check-latest` will be automatically set to true') + expect(logSpy).toHaveBeenCalledWith('Attempt to resolve the latest version from manifest...'); expect(dbgSpy).toHaveBeenCalledWith(`LTS alias 'erbium' for Node version 'lts/erbium'`) expect(dbgSpy).toHaveBeenCalledWith(`Found LTS release '12.16.2' for Node version 'lts/erbium'`) expect(logSpy).toHaveBeenCalledWith("Resolved as '12.16.2'"); @@ -604,8 +604,8 @@ describe('setup-node', () => { await main.run(); // assert - expect(logSpy).toHaveBeenCalledWith('Attempt to resolve the latest version from manifest...'); expect(warningSpy).toHaveBeenCalledWith('LTS version is provided. For LTS versions `check-latest` will be automatically set to true') + expect(logSpy).toHaveBeenCalledWith('Attempt to resolve the latest version from manifest...'); expect(dbgSpy).toHaveBeenCalledWith(`LTS alias '*' for Node version 'lts/*'`) expect(dbgSpy).toHaveBeenCalledWith(`Found LTS release '14.0.0' for Node version 'lts/*'`) expect(logSpy).toHaveBeenCalledWith("Resolved as '14.0.0'"); @@ -632,8 +632,8 @@ describe('setup-node', () => { await main.run(); // assert - expect(logSpy).toHaveBeenCalledWith('Attempt to resolve the latest version from manifest...'); expect(warningSpy).toHaveBeenCalledWith('LTS version is provided. For LTS versions `check-latest` will be automatically set to true') + expect(logSpy).toHaveBeenCalledWith('Attempt to resolve the latest version from manifest...'); expect(dbgSpy).toHaveBeenCalledWith(`LTS alias '*' for Node version 'lts/*'`) expect(dbgSpy).toHaveBeenCalledWith(`Found LTS release '14.0.0' for Node version 'lts/*'`) expect(logSpy).toHaveBeenCalledWith("Resolved as '14.0.0'"); @@ -643,5 +643,50 @@ describe('setup-node', () => { expect(logSpy).toHaveBeenCalledWith('Adding to the cache ...'); expect(cnSpy).toHaveBeenCalledWith(`::add-path::${toolPath}/bin${osm.EOL}`); }) + + it('fail with unexpected LTS alias (lts/)', async () => { + // arrange + os.platform = 'linux'; + os.arch = 'x64'; + + inputs['node-version'] = 'lts/'; + inputs.stable = 'true'; + + findSpy.mockImplementation(() => ''); + + // act + await main.run(); + + // assert + expect(warningSpy).toHaveBeenCalledWith('LTS version is provided. For LTS versions `check-latest` will be automatically set to true') + expect(logSpy).toHaveBeenCalledWith('Attempt to resolve the latest version from manifest...'); + expect(logSpy).toHaveBeenCalledWith('Unable to resolve version from manifest...'); + expect(dbgSpy).toHaveBeenCalledWith(`Unexpected LTS alias '' for Node version 'lts/'`) + expect(logSpy).toHaveBeenCalledWith('Failed to resolve version lts/ from manifest'); + expect(cnSpy).toHaveBeenCalledWith(`::error::Unable to find Node version 'lts/' for platform linux and architecture x64.${osm.EOL}`); + }); + + it('fail to find LTS version (lts/unknown)', async () => { + // arrange + os.platform = 'linux'; + os.arch = 'x64'; + + inputs['node-version'] = 'lts/unknown'; + inputs.stable = 'true'; + + findSpy.mockImplementation(() => ''); + + // act + await main.run(); + + // assert + expect(warningSpy).toHaveBeenCalledWith('LTS version is provided. For LTS versions `check-latest` will be automatically set to true') + expect(logSpy).toHaveBeenCalledWith('Attempt to resolve the latest version from manifest...'); + expect(dbgSpy).toHaveBeenCalledWith(`LTS alias 'unknown' for Node version 'lts/unknown'`) + expect(logSpy).toHaveBeenCalledWith('Unable to resolve version from manifest...'); + expect(dbgSpy).toHaveBeenCalledWith(`Unable to find LTS release 'unknown' for Node version 'lts/unknown'.`) + expect(logSpy).toHaveBeenCalledWith('Failed to resolve version lts/unknown from manifest'); + expect(cnSpy).toHaveBeenCalledWith(`::error::Unable to find Node version 'lts/unknown' for platform linux and architecture x64.${osm.EOL}`); + }); }) }); From c8c6442c742d26063afab708954f283b3998acd7 Mon Sep 17 00:00:00 2001 From: Gordey Doronin Date: Mon, 21 Jun 2021 11:37:06 +0200 Subject: [PATCH 04/18] Add brief comment about supported formats --- src/installer.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/installer.ts b/src/installer.ts index 84c57c0..bc2f99f 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -192,6 +192,7 @@ function findLtsVersionFromManifest( core.debug(`LTS alias '${alias}' for Node version '${versionSpec}'`); + // Supported formats are `lts/` and `lts/*`. Where asterisk means highest possible LTS. const release = alias === '*' ? candidates.find(x => !!x.lts && x.stable === stable) : candidates.find(x => x.lts?.toLowerCase() === alias && x.stable === stable); From e761a7024e7c9202ccf7e64cfe33cbc8d4190bee Mon Sep 17 00:00:00 2001 From: Gordey Doronin Date: Mon, 21 Jun 2021 11:37:50 +0200 Subject: [PATCH 05/18] Interface extraction --- src/installer.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/installer.ts b/src/installer.ts index bc2f99f..0afcaa6 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -24,6 +24,10 @@ interface INodeVersionInfo { fileName: string; } +interface INodeRelease extends tc.IToolRelease { + lts?: string; +} + export async function getNode( versionSpec: string, stable: boolean, @@ -182,7 +186,7 @@ function isLts(versionSpec: string): boolean { function findLtsVersionFromManifest( versionSpec: string, stable: boolean, - candidates: Array + candidates: INodeRelease[] ): string { const alias = versionSpec.split('lts/')[1]?.toLowerCase(); From 0ec4841e4b4a8aef0c86a18ed294669513661cdd Mon Sep 17 00:00:00 2001 From: Gordey Doronin Date: Mon, 21 Jun 2021 11:39:00 +0200 Subject: [PATCH 06/18] Function renaming --- src/installer.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/installer.ts b/src/installer.ts index 0afcaa6..2df2e13 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -38,7 +38,7 @@ export async function getNode( let osPlat: string = os.platform(); let osArch: string = translateArchToDistUrl(arch); - if (isLts(versionSpec)) { + if (isLtsVersion(versionSpec)) { core.warning('LTS version is provided. For LTS versions `check-latest` will be automatically set to true'); checkLatest = true; } @@ -179,7 +179,7 @@ export async function getNode( core.addPath(toolPath); } -function isLts(versionSpec: string): boolean { +function isLtsVersion(versionSpec: string): boolean { return versionSpec.startsWith('lts') } @@ -224,7 +224,7 @@ async function getInfoFromManifest( 'main' ); - if (isLts(versionSpec)) { + if (isLtsVersion(versionSpec)) { versionSpec = findLtsVersionFromManifest(versionSpec, stable, releases); } From bcdcde00c0fc83717dcc05a8e0d9ea352513fe05 Mon Sep 17 00:00:00 2001 From: Gordey Doronin Date: Mon, 21 Jun 2021 11:40:55 +0200 Subject: [PATCH 07/18] Stage dist files --- dist/index.js | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/dist/index.js b/dist/index.js index 800d35a..d2c35be 100644 --- a/dist/index.js +++ b/dist/index.js @@ -13107,6 +13107,10 @@ function getNode(versionSpec, stable, checkLatest, auth, arch = os.arch()) { return __awaiter(this, void 0, void 0, function* () { let osPlat = os.platform(); let osArch = translateArchToDistUrl(arch); + if (isLtsVersion(versionSpec)) { + core.warning('LTS version is provided. For LTS versions `check-latest` will be automatically set to true'); + checkLatest = true; + } if (checkLatest) { core.info('Attempt to resolve the latest version from manifest...'); const resolvedVersion = yield resolveVersionFromManifest(versionSpec, stable, auth, osArch); @@ -13216,10 +13220,33 @@ function getNode(versionSpec, stable, checkLatest, auth, arch = os.arch()) { }); } exports.getNode = getNode; +function isLtsVersion(versionSpec) { + return versionSpec.startsWith('lts'); +} +function findLtsVersionFromManifest(versionSpec, stable, candidates) { + var _a; + const alias = (_a = versionSpec.split('lts/')[1]) === null || _a === void 0 ? void 0 : _a.toLowerCase(); + if (!alias) { + throw new Error(`Unexpected LTS alias '${alias}' for Node version '${versionSpec}'`); + } + core.debug(`LTS alias '${alias}' for Node version '${versionSpec}'`); + // Supported formats are `lts/` and `lts/*`. Where asterisk means highest possible LTS. + const release = alias === '*' + ? candidates.find(x => !!x.lts && x.stable === stable) + : candidates.find(x => { var _a; return ((_a = x.lts) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === alias && x.stable === stable; }); + if (!release) { + throw new Error(`Unable to find LTS release '${alias}' for Node version '${versionSpec}'.`); + } + core.debug(`Found LTS release '${release.version}' for Node version '${versionSpec}'`); + return release.version.split('.')[0]; +} function getInfoFromManifest(versionSpec, stable, auth, osArch = translateArchToDistUrl(os.arch())) { return __awaiter(this, void 0, void 0, function* () { let info = null; const releases = yield tc.getManifestFromRepo('actions', 'node-versions', auth, 'main'); + if (isLtsVersion(versionSpec)) { + versionSpec = findLtsVersionFromManifest(versionSpec, stable, releases); + } const rel = yield tc.findFromManifest(versionSpec, stable, releases, osArch); if (rel && rel.files.length > 0) { info = {}; From 36d2ce149ef6fea8601c6ee9636d1a3dcbf09ad6 Mon Sep 17 00:00:00 2001 From: Gordey Doronin Date: Mon, 21 Jun 2021 14:33:27 +0200 Subject: [PATCH 08/18] Switch warning to info logging --- __tests__/installer.test.ts | 12 ++++++------ dist/index.js | 2 +- src/installer.ts | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/__tests__/installer.test.ts b/__tests__/installer.test.ts index 13a1c55..1280597 100644 --- a/__tests__/installer.test.ts +++ b/__tests__/installer.test.ts @@ -549,7 +549,7 @@ describe('setup-node', () => { await main.run(); // assert - expect(warningSpy).toHaveBeenCalledWith('LTS version is provided. For LTS versions `check-latest` will be automatically set to true') + expect(logSpy).toHaveBeenCalledWith('LTS version is provided. For LTS versions `check-latest` will be automatically set to true') expect(logSpy).toHaveBeenCalledWith('Attempt to resolve the latest version from manifest...'); expect(dbgSpy).toHaveBeenCalledWith(`LTS alias 'erbium' for Node version 'lts/erbium'`) expect(dbgSpy).toHaveBeenCalledWith(`Found LTS release '12.16.2' for Node version 'lts/erbium'`) @@ -577,7 +577,7 @@ describe('setup-node', () => { await main.run(); // assert - expect(warningSpy).toHaveBeenCalledWith('LTS version is provided. For LTS versions `check-latest` will be automatically set to true') + expect(logSpy).toHaveBeenCalledWith('LTS version is provided. For LTS versions `check-latest` will be automatically set to true') expect(logSpy).toHaveBeenCalledWith('Attempt to resolve the latest version from manifest...'); expect(dbgSpy).toHaveBeenCalledWith(`LTS alias 'erbium' for Node version 'lts/erbium'`) expect(dbgSpy).toHaveBeenCalledWith(`Found LTS release '12.16.2' for Node version 'lts/erbium'`) @@ -604,7 +604,7 @@ describe('setup-node', () => { await main.run(); // assert - expect(warningSpy).toHaveBeenCalledWith('LTS version is provided. For LTS versions `check-latest` will be automatically set to true') + expect(logSpy).toHaveBeenCalledWith('LTS version is provided. For LTS versions `check-latest` will be automatically set to true') expect(logSpy).toHaveBeenCalledWith('Attempt to resolve the latest version from manifest...'); expect(dbgSpy).toHaveBeenCalledWith(`LTS alias '*' for Node version 'lts/*'`) expect(dbgSpy).toHaveBeenCalledWith(`Found LTS release '14.0.0' for Node version 'lts/*'`) @@ -632,7 +632,7 @@ describe('setup-node', () => { await main.run(); // assert - expect(warningSpy).toHaveBeenCalledWith('LTS version is provided. For LTS versions `check-latest` will be automatically set to true') + expect(logSpy).toHaveBeenCalledWith('LTS version is provided. For LTS versions `check-latest` will be automatically set to true') expect(logSpy).toHaveBeenCalledWith('Attempt to resolve the latest version from manifest...'); expect(dbgSpy).toHaveBeenCalledWith(`LTS alias '*' for Node version 'lts/*'`) expect(dbgSpy).toHaveBeenCalledWith(`Found LTS release '14.0.0' for Node version 'lts/*'`) @@ -658,7 +658,7 @@ describe('setup-node', () => { await main.run(); // assert - expect(warningSpy).toHaveBeenCalledWith('LTS version is provided. For LTS versions `check-latest` will be automatically set to true') + expect(logSpy).toHaveBeenCalledWith('LTS version is provided. For LTS versions `check-latest` will be automatically set to true') expect(logSpy).toHaveBeenCalledWith('Attempt to resolve the latest version from manifest...'); expect(logSpy).toHaveBeenCalledWith('Unable to resolve version from manifest...'); expect(dbgSpy).toHaveBeenCalledWith(`Unexpected LTS alias '' for Node version 'lts/'`) @@ -680,7 +680,7 @@ describe('setup-node', () => { await main.run(); // assert - expect(warningSpy).toHaveBeenCalledWith('LTS version is provided. For LTS versions `check-latest` will be automatically set to true') + expect(logSpy).toHaveBeenCalledWith('LTS version is provided. For LTS versions `check-latest` will be automatically set to true') expect(logSpy).toHaveBeenCalledWith('Attempt to resolve the latest version from manifest...'); expect(dbgSpy).toHaveBeenCalledWith(`LTS alias 'unknown' for Node version 'lts/unknown'`) expect(logSpy).toHaveBeenCalledWith('Unable to resolve version from manifest...'); diff --git a/dist/index.js b/dist/index.js index d2c35be..915200f 100644 --- a/dist/index.js +++ b/dist/index.js @@ -13108,7 +13108,7 @@ function getNode(versionSpec, stable, checkLatest, auth, arch = os.arch()) { let osPlat = os.platform(); let osArch = translateArchToDistUrl(arch); if (isLtsVersion(versionSpec)) { - core.warning('LTS version is provided. For LTS versions `check-latest` will be automatically set to true'); + core.info('LTS version is provided. For LTS versions `check-latest` will be automatically set to true'); checkLatest = true; } if (checkLatest) { diff --git a/src/installer.ts b/src/installer.ts index 2df2e13..284b8b5 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -39,7 +39,7 @@ export async function getNode( let osArch: string = translateArchToDistUrl(arch); if (isLtsVersion(versionSpec)) { - core.warning('LTS version is provided. For LTS versions `check-latest` will be automatically set to true'); + core.info('LTS version is provided. For LTS versions `check-latest` will be automatically set to true'); checkLatest = true; } From c62861c1e7c9af33f6d2343356f2c691c4eb4cbf Mon Sep 17 00:00:00 2001 From: Gordey Doronin Date: Tue, 22 Jun 2021 13:10:16 +0200 Subject: [PATCH 09/18] Rename --- dist/index.js | 14 +++++++------- src/installer.ts | 16 ++++++++-------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/dist/index.js b/dist/index.js index 915200f..dcbb152 100644 --- a/dist/index.js +++ b/dist/index.js @@ -13107,7 +13107,7 @@ function getNode(versionSpec, stable, checkLatest, auth, arch = os.arch()) { return __awaiter(this, void 0, void 0, function* () { let osPlat = os.platform(); let osArch = translateArchToDistUrl(arch); - if (isLtsVersion(versionSpec)) { + if (isLtsAlias(versionSpec)) { core.info('LTS version is provided. For LTS versions `check-latest` will be automatically set to true'); checkLatest = true; } @@ -13220,10 +13220,10 @@ function getNode(versionSpec, stable, checkLatest, auth, arch = os.arch()) { }); } exports.getNode = getNode; -function isLtsVersion(versionSpec) { +function isLtsAlias(versionSpec) { return versionSpec.startsWith('lts'); } -function findLtsVersionFromManifest(versionSpec, stable, candidates) { +function resolveLtsAliasFromManifest(versionSpec, stable, manifest) { var _a; const alias = (_a = versionSpec.split('lts/')[1]) === null || _a === void 0 ? void 0 : _a.toLowerCase(); if (!alias) { @@ -13232,8 +13232,8 @@ function findLtsVersionFromManifest(versionSpec, stable, candidates) { core.debug(`LTS alias '${alias}' for Node version '${versionSpec}'`); // Supported formats are `lts/` and `lts/*`. Where asterisk means highest possible LTS. const release = alias === '*' - ? candidates.find(x => !!x.lts && x.stable === stable) - : candidates.find(x => { var _a; return ((_a = x.lts) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === alias && x.stable === stable; }); + ? manifest.find(x => !!x.lts && x.stable === stable) + : manifest.find(x => { var _a; return ((_a = x.lts) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === alias && x.stable === stable; }); if (!release) { throw new Error(`Unable to find LTS release '${alias}' for Node version '${versionSpec}'.`); } @@ -13244,8 +13244,8 @@ function getInfoFromManifest(versionSpec, stable, auth, osArch = translateArchTo return __awaiter(this, void 0, void 0, function* () { let info = null; const releases = yield tc.getManifestFromRepo('actions', 'node-versions', auth, 'main'); - if (isLtsVersion(versionSpec)) { - versionSpec = findLtsVersionFromManifest(versionSpec, stable, releases); + if (isLtsAlias(versionSpec)) { + versionSpec = resolveLtsAliasFromManifest(versionSpec, stable, releases); } const rel = yield tc.findFromManifest(versionSpec, stable, releases, osArch); if (rel && rel.files.length > 0) { diff --git a/src/installer.ts b/src/installer.ts index 284b8b5..7a19a25 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -38,7 +38,7 @@ export async function getNode( let osPlat: string = os.platform(); let osArch: string = translateArchToDistUrl(arch); - if (isLtsVersion(versionSpec)) { + if (isLtsAlias(versionSpec)) { core.info('LTS version is provided. For LTS versions `check-latest` will be automatically set to true'); checkLatest = true; } @@ -179,14 +179,14 @@ export async function getNode( core.addPath(toolPath); } -function isLtsVersion(versionSpec: string): boolean { +function isLtsAlias(versionSpec: string): boolean { return versionSpec.startsWith('lts') } -function findLtsVersionFromManifest( +function resolveLtsAliasFromManifest( versionSpec: string, stable: boolean, - candidates: INodeRelease[] + manifest: INodeRelease[] ): string { const alias = versionSpec.split('lts/')[1]?.toLowerCase(); @@ -198,8 +198,8 @@ function findLtsVersionFromManifest( // Supported formats are `lts/` and `lts/*`. Where asterisk means highest possible LTS. const release = alias === '*' - ? candidates.find(x => !!x.lts && x.stable === stable) - : candidates.find(x => x.lts?.toLowerCase() === alias && x.stable === stable); + ? manifest.find(x => !!x.lts && x.stable === stable) + : manifest.find(x => x.lts?.toLowerCase() === alias && x.stable === stable); if (!release) { throw new Error(`Unable to find LTS release '${alias}' for Node version '${versionSpec}'.`); @@ -224,8 +224,8 @@ async function getInfoFromManifest( 'main' ); - if (isLtsVersion(versionSpec)) { - versionSpec = findLtsVersionFromManifest(versionSpec, stable, releases); + if (isLtsAlias(versionSpec)) { + versionSpec = resolveLtsAliasFromManifest(versionSpec, stable, releases); } const rel = await tc.findFromManifest(versionSpec, stable, releases, osArch); From 92722aec8cf5360a51b6b050870d1c9344b95798 Mon Sep 17 00:00:00 2001 From: Gordey Doronin Date: Tue, 22 Jun 2021 15:45:25 +0200 Subject: [PATCH 10/18] Logic remastered to not force check-latest --- __tests__/installer.test.ts | 74 ++++++++++++++++++++++++------------- dist/index.js | 27 ++++++++------ src/installer.ts | 40 ++++++++++++-------- 3 files changed, 88 insertions(+), 53 deletions(-) diff --git a/__tests__/installer.test.ts b/__tests__/installer.test.ts index 1280597..6a77c21 100644 --- a/__tests__/installer.test.ts +++ b/__tests__/installer.test.ts @@ -399,6 +399,7 @@ describe('setup-node', () => { expect(logSpy).not.toHaveBeenCalledWith( 'Attempt to resolve the latest version from manifest...' ); + expect(dbgSpy).not.toHaveBeenCalledWith('No manifest cached, getting manifest from actions/node-versions@main') }); it('check latest version and resolve it from local cache', async () => { @@ -419,6 +420,7 @@ describe('setup-node', () => { expect(logSpy).toHaveBeenCalledWith( 'Attempt to resolve the latest version from manifest...' ); + expect(dbgSpy).toHaveBeenCalledWith('No manifest cached, getting manifest from actions/node-versions@main') expect(logSpy).toHaveBeenCalledWith("Resolved as '12.16.2'"); expect(logSpy).toHaveBeenCalledWith(`Found in cache @ ${toolPath}`); }); @@ -443,6 +445,7 @@ describe('setup-node', () => { expect(logSpy).toHaveBeenCalledWith( 'Attempt to resolve the latest version from manifest...' ); + expect(dbgSpy).toHaveBeenCalledWith('No manifest cached, getting manifest from actions/node-versions@main') expect(logSpy).toHaveBeenCalledWith("Resolved as '12.16.2'"); expect(logSpy).toHaveBeenCalledWith( `Acquiring 12.16.2 - ${os.arch} from ${expectedUrl}` @@ -479,6 +482,7 @@ describe('setup-node', () => { expect(logSpy).toHaveBeenCalledWith( 'Attempt to resolve the latest version from manifest...' ); + expect(dbgSpy).toHaveBeenCalledWith('No manifest cached, getting manifest from actions/node-versions@main') expect(logSpy).toHaveBeenCalledWith( `Failed to resolve version ${versionSpec} from manifest` ); @@ -522,6 +526,7 @@ describe('setup-node', () => { ); expect(logSpy).toHaveBeenCalledWith( 'Unable to resolve version from manifest...' + // 'Unable to get manifest...' ); expect(logSpy).toHaveBeenCalledWith( `Failed to resolve version ${versionSpec} from manifest` @@ -549,11 +554,11 @@ describe('setup-node', () => { await main.run(); // assert - expect(logSpy).toHaveBeenCalledWith('LTS version is provided. For LTS versions `check-latest` will be automatically set to true') - expect(logSpy).toHaveBeenCalledWith('Attempt to resolve the latest version from manifest...'); + 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, getting manifest from actions/node-versions@main') expect(dbgSpy).toHaveBeenCalledWith(`LTS alias 'erbium' for Node version 'lts/erbium'`) expect(dbgSpy).toHaveBeenCalledWith(`Found LTS release '12.16.2' for Node version 'lts/erbium'`) - expect(logSpy).toHaveBeenCalledWith("Resolved as '12.16.2'"); expect(logSpy).toHaveBeenCalledWith(`Found in cache @ ${toolPath}`); expect(cnSpy).toHaveBeenCalledWith(`::add-path::${toolPath}/bin${osm.EOL}`); }); @@ -577,12 +582,12 @@ describe('setup-node', () => { await main.run(); // assert - expect(logSpy).toHaveBeenCalledWith('LTS version is provided. For LTS versions `check-latest` will be automatically set to true') - expect(logSpy).toHaveBeenCalledWith('Attempt to resolve the latest version from manifest...'); + 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, getting manifest from actions/node-versions@main') expect(dbgSpy).toHaveBeenCalledWith(`LTS alias 'erbium' for Node version 'lts/erbium'`) expect(dbgSpy).toHaveBeenCalledWith(`Found LTS release '12.16.2' for Node version 'lts/erbium'`) - expect(logSpy).toHaveBeenCalledWith("Resolved as '12.16.2'"); - expect(logSpy).toHaveBeenCalledWith("Attempting to download 12.16.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 ...'); @@ -604,11 +609,11 @@ describe('setup-node', () => { await main.run(); // assert - expect(logSpy).toHaveBeenCalledWith('LTS version is provided. For LTS versions `check-latest` will be automatically set to true') - expect(logSpy).toHaveBeenCalledWith('Attempt to resolve the latest version from manifest...'); + 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, getting manifest from actions/node-versions@main') expect(dbgSpy).toHaveBeenCalledWith(`LTS alias '*' for Node version 'lts/*'`) expect(dbgSpy).toHaveBeenCalledWith(`Found LTS release '14.0.0' for Node version 'lts/*'`) - expect(logSpy).toHaveBeenCalledWith("Resolved as '14.0.0'"); expect(logSpy).toHaveBeenCalledWith(`Found in cache @ ${toolPath}`); expect(cnSpy).toHaveBeenCalledWith(`::add-path::${toolPath}/bin${osm.EOL}`); }); @@ -632,12 +637,12 @@ describe('setup-node', () => { await main.run(); // assert - expect(logSpy).toHaveBeenCalledWith('LTS version is provided. For LTS versions `check-latest` will be automatically set to true') - expect(logSpy).toHaveBeenCalledWith('Attempt to resolve the latest version from manifest...'); + 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, getting manifest from actions/node-versions@main') expect(dbgSpy).toHaveBeenCalledWith(`LTS alias '*' for Node version 'lts/*'`) expect(dbgSpy).toHaveBeenCalledWith(`Found LTS release '14.0.0' for Node version 'lts/*'`) - expect(logSpy).toHaveBeenCalledWith("Resolved as '14.0.0'"); - expect(logSpy).toHaveBeenCalledWith("Attempting to download 14.0.0..."); + expect(logSpy).toHaveBeenCalledWith("Attempting to download 14..."); expect(logSpy).toHaveBeenCalledWith(`Acquiring 14.0.0 - ${os.arch} from ${expectedUrl}`); expect(logSpy).toHaveBeenCalledWith('Extracting ...'); expect(logSpy).toHaveBeenCalledWith('Adding to the cache ...'); @@ -658,12 +663,9 @@ describe('setup-node', () => { await main.run(); // assert - expect(logSpy).toHaveBeenCalledWith('LTS version is provided. For LTS versions `check-latest` will be automatically set to true') - expect(logSpy).toHaveBeenCalledWith('Attempt to resolve the latest version from manifest...'); - expect(logSpy).toHaveBeenCalledWith('Unable to resolve version from manifest...'); - expect(dbgSpy).toHaveBeenCalledWith(`Unexpected LTS alias '' for Node version 'lts/'`) - expect(logSpy).toHaveBeenCalledWith('Failed to resolve version lts/ from manifest'); - expect(cnSpy).toHaveBeenCalledWith(`::error::Unable to find Node version 'lts/' for platform linux and architecture x64.${osm.EOL}`); + expect(logSpy).toHaveBeenCalledWith('Attempt to resolve LTS alias from manifest...') + expect(dbgSpy).toHaveBeenCalledWith('Getting manifest from actions/node-versions@main') + expect(cnSpy).toHaveBeenCalledWith(`::error::Unexpected LTS alias '' for Node version 'lts/'${osm.EOL}`) }); it('fail to find LTS version (lts/unknown)', async () => { @@ -680,13 +682,33 @@ describe('setup-node', () => { await main.run(); // assert - expect(logSpy).toHaveBeenCalledWith('LTS version is provided. For LTS versions `check-latest` will be automatically set to true') - expect(logSpy).toHaveBeenCalledWith('Attempt to resolve the latest version from manifest...'); + expect(logSpy).toHaveBeenCalledWith('Attempt to resolve LTS alias from manifest...') + expect(dbgSpy).toHaveBeenCalledWith('Getting manifest from actions/node-versions@main') expect(dbgSpy).toHaveBeenCalledWith(`LTS alias 'unknown' for Node version 'lts/unknown'`) - expect(logSpy).toHaveBeenCalledWith('Unable to resolve version from manifest...'); - expect(dbgSpy).toHaveBeenCalledWith(`Unable to find LTS release 'unknown' for Node version 'lts/unknown'.`) - expect(logSpy).toHaveBeenCalledWith('Failed to resolve version lts/unknown from manifest'); - expect(cnSpy).toHaveBeenCalledWith(`::error::Unable to find Node version 'lts/unknown' for platform linux and architecture x64.${osm.EOL}`); + expect(cnSpy).toHaveBeenCalledWith(`::error::Unable to find LTS release 'unknown' for Node version 'lts/unknown'.${osm.EOL}`) }); + + it('fail if manifest is not available', async () => { + // arrange + os.platform = 'linux'; + os.arch = 'x64'; + + inputs['node-version'] = 'lts/erbium'; + inputs.stable = 'true'; + + // ... but not in the local cache + findSpy.mockImplementation(() => ''); + getManifestSpy.mockImplementation(() => { + throw new Error('Unable to download manifest'); + }); + + // 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(cnSpy).toHaveBeenCalledWith(`::error::Unable to download manifest${osm.EOL}`) + }) }) }); diff --git a/dist/index.js b/dist/index.js index dcbb152..a1f7f05 100644 --- a/dist/index.js +++ b/dist/index.js @@ -13105,15 +13105,20 @@ const semver = __importStar(__webpack_require__(280)); const fs = __webpack_require__(747); function getNode(versionSpec, stable, checkLatest, auth, arch = os.arch()) { return __awaiter(this, void 0, void 0, function* () { + // Store manifest data to avoid multiple calls + let manifest; let osPlat = os.platform(); let osArch = translateArchToDistUrl(arch); if (isLtsAlias(versionSpec)) { - core.info('LTS version is provided. For LTS versions `check-latest` will be automatically set to true'); - checkLatest = true; + core.info('Attempt to resolve LTS alias from manifest...'); + core.debug('Getting manifest from actions/node-versions@main'); + // No try-catch since it's not possible to resolve LTS alias without manifest + manifest = yield tc.getManifestFromRepo('actions', 'node-versions', auth, 'main'); + versionSpec = resolveLtsAliasFromManifest(versionSpec, stable, manifest); } if (checkLatest) { core.info('Attempt to resolve the latest version from manifest...'); - const resolvedVersion = yield resolveVersionFromManifest(versionSpec, stable, auth, osArch); + const resolvedVersion = yield resolveVersionFromManifest(versionSpec, stable, auth, osArch, manifest); if (resolvedVersion) { versionSpec = resolvedVersion; core.info(`Resolved as '${versionSpec}'`); @@ -13137,7 +13142,7 @@ function getNode(versionSpec, stable, checkLatest, auth, arch = os.arch()) { // Try download from internal distribution (popular versions only) // try { - info = yield getInfoFromManifest(versionSpec, stable, auth, osArch); + info = yield getInfoFromManifest(versionSpec, stable, auth, osArch, manifest); if (info) { core.info(`Acquiring ${info.resolvedVersion} - ${info.arch} from ${info.downloadUrl}`); downloadPath = yield tc.downloadTool(info.downloadUrl, undefined, auth); @@ -13240,14 +13245,14 @@ function resolveLtsAliasFromManifest(versionSpec, stable, manifest) { core.debug(`Found LTS release '${release.version}' for Node version '${versionSpec}'`); return release.version.split('.')[0]; } -function getInfoFromManifest(versionSpec, stable, auth, osArch = translateArchToDistUrl(os.arch())) { +function getInfoFromManifest(versionSpec, stable, auth, osArch = translateArchToDistUrl(os.arch()), manifest) { return __awaiter(this, void 0, void 0, function* () { let info = null; - const releases = yield tc.getManifestFromRepo('actions', 'node-versions', auth, 'main'); - if (isLtsAlias(versionSpec)) { - versionSpec = resolveLtsAliasFromManifest(versionSpec, stable, releases); + if (!manifest) { + core.debug('No manifest cached, getting manifest from actions/node-versions@main'); + manifest = yield tc.getManifestFromRepo('actions', 'node-versions', auth, 'main'); } - const rel = yield tc.findFromManifest(versionSpec, stable, releases, osArch); + const rel = yield tc.findFromManifest(versionSpec, stable, manifest, osArch); if (rel && rel.files.length > 0) { info = {}; info.resolvedVersion = rel.version; @@ -13284,10 +13289,10 @@ function getInfoFromDist(versionSpec, arch = os.arch()) { }; }); } -function resolveVersionFromManifest(versionSpec, stable, auth, osArch = translateArchToDistUrl(os.arch())) { +function resolveVersionFromManifest(versionSpec, stable, auth, osArch = translateArchToDistUrl(os.arch()), manifest) { return __awaiter(this, void 0, void 0, function* () { try { - const info = yield getInfoFromManifest(versionSpec, stable, auth, osArch); + const info = yield getInfoFromManifest(versionSpec, stable, auth, osArch, manifest); return info === null || info === void 0 ? void 0 : info.resolvedVersion; } catch (err) { diff --git a/src/installer.ts b/src/installer.ts index 7a19a25..ac7be1c 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -35,12 +35,17 @@ export async function getNode( auth: string | undefined, arch: string = os.arch() ) { + // Store manifest data to avoid multiple calls + let manifest: INodeRelease[] | undefined; let osPlat: string = os.platform(); let osArch: string = translateArchToDistUrl(arch); if (isLtsAlias(versionSpec)) { - core.info('LTS version is provided. For LTS versions `check-latest` will be automatically set to true'); - checkLatest = true; + core.info('Attempt to resolve LTS alias from manifest...'); + core.debug('Getting manifest from actions/node-versions@main') + // No try-catch since it's not possible to resolve LTS alias without manifest + manifest = await tc.getManifestFromRepo('actions', 'node-versions', auth, 'main'); + versionSpec = resolveLtsAliasFromManifest(versionSpec, stable, manifest); } if (checkLatest) { @@ -49,7 +54,8 @@ export async function getNode( versionSpec, stable, auth, - osArch + osArch, + manifest ); if (resolvedVersion) { versionSpec = resolvedVersion; @@ -75,7 +81,7 @@ export async function getNode( // Try download from internal distribution (popular versions only) // try { - info = await getInfoFromManifest(versionSpec, stable, auth, osArch); + info = await getInfoFromManifest(versionSpec, stable, auth, osArch, manifest); if (info) { core.info( `Acquiring ${info.resolvedVersion} - ${info.arch} from ${info.downloadUrl}` @@ -214,21 +220,22 @@ async function getInfoFromManifest( versionSpec: string, stable: boolean, auth: string | undefined, - osArch: string = translateArchToDistUrl(os.arch()) + osArch: string = translateArchToDistUrl(os.arch()), + manifest: tc.IToolRelease[] | undefined ): Promise { let info: INodeVersionInfo | null = null; - const releases = await tc.getManifestFromRepo( - 'actions', - 'node-versions', - auth, - 'main' - ); + if (!manifest) { + core.debug('No manifest cached, getting manifest from actions/node-versions@main') - if (isLtsAlias(versionSpec)) { - versionSpec = resolveLtsAliasFromManifest(versionSpec, stable, releases); + manifest = await tc.getManifestFromRepo( + 'actions', + 'node-versions', + auth, + 'main' + ); } - const rel = await tc.findFromManifest(versionSpec, stable, releases, osArch); + const rel = await tc.findFromManifest(versionSpec, stable, manifest, osArch); if (rel && rel.files.length > 0) { info = {}; @@ -279,10 +286,11 @@ async function resolveVersionFromManifest( versionSpec: string, stable: boolean, auth: string | undefined, - osArch: string = translateArchToDistUrl(os.arch()) + osArch: string = translateArchToDistUrl(os.arch()), + manifest: tc.IToolRelease[] | undefined ): Promise { try { - const info = await getInfoFromManifest(versionSpec, stable, auth, osArch); + const info = await getInfoFromManifest(versionSpec, stable, auth, osArch, manifest); return info?.resolvedVersion; } catch (err) { core.info('Unable to resolve version from manifest...'); From 56c3db9ddab4bfd2b952bdfed6259e78a05c099a Mon Sep 17 00:00:00 2001 From: Gordey Doronin Date: Tue, 22 Jun 2021 15:51:57 +0200 Subject: [PATCH 11/18] Cleanup redundant leftover --- __tests__/installer.test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/__tests__/installer.test.ts b/__tests__/installer.test.ts index 6a77c21..100050c 100644 --- a/__tests__/installer.test.ts +++ b/__tests__/installer.test.ts @@ -526,7 +526,6 @@ describe('setup-node', () => { ); expect(logSpy).toHaveBeenCalledWith( 'Unable to resolve version from manifest...' - // 'Unable to get manifest...' ); expect(logSpy).toHaveBeenCalledWith( `Failed to resolve version ${versionSpec} from manifest` From d9ce83b637cfedc635fce2626d990276d3dc49bb Mon Sep 17 00:00:00 2001 From: Gordey Doronin Date: Tue, 22 Jun 2021 16:11:44 +0200 Subject: [PATCH 12/18] Formatter --- __tests__/installer.test.ts | 184 ++++++++++++++++++++++++++---------- src/installer.ts | 52 +++++++--- 2 files changed, 173 insertions(+), 63 deletions(-) diff --git a/__tests__/installer.test.ts b/__tests__/installer.test.ts index 100050c..2fc88d6 100644 --- a/__tests__/installer.test.ts +++ b/__tests__/installer.test.ts @@ -134,7 +134,7 @@ describe('setup-node', () => { let match = await tc.findFromManifest('12.16.2', true, versions); expect(match).toBeDefined(); expect(match?.version).toBe('12.16.2'); - expect((match as any).lts).toBe('Erbium') + expect((match as any).lts).toBe('Erbium'); }); it('can find 12 from manifest on linux', async () => { @@ -149,7 +149,7 @@ describe('setup-node', () => { let match = await tc.findFromManifest('12.16.2', true, versions); expect(match).toBeDefined(); expect(match?.version).toBe('12.16.2'); - expect((match as any).lts).toBe('Erbium') + expect((match as any).lts).toBe('Erbium'); }); it('can find 10 from manifest on windows', async () => { @@ -164,7 +164,7 @@ describe('setup-node', () => { let match = await tc.findFromManifest('10', true, versions); expect(match).toBeDefined(); expect(match?.version).toBe('10.20.1'); - expect((match as any).lts).toBe('Dubnium') + expect((match as any).lts).toBe('Dubnium'); }); //-------------------------------------------------- @@ -399,7 +399,9 @@ describe('setup-node', () => { expect(logSpy).not.toHaveBeenCalledWith( 'Attempt to resolve the latest version from manifest...' ); - expect(dbgSpy).not.toHaveBeenCalledWith('No manifest cached, getting manifest from actions/node-versions@main') + expect(dbgSpy).not.toHaveBeenCalledWith( + 'No manifest cached, getting manifest from actions/node-versions@main' + ); }); it('check latest version and resolve it from local cache', async () => { @@ -420,7 +422,9 @@ describe('setup-node', () => { expect(logSpy).toHaveBeenCalledWith( 'Attempt to resolve the latest version from manifest...' ); - expect(dbgSpy).toHaveBeenCalledWith('No manifest cached, getting manifest from actions/node-versions@main') + expect(dbgSpy).toHaveBeenCalledWith( + 'No manifest cached, getting manifest from actions/node-versions@main' + ); expect(logSpy).toHaveBeenCalledWith("Resolved as '12.16.2'"); expect(logSpy).toHaveBeenCalledWith(`Found in cache @ ${toolPath}`); }); @@ -445,7 +449,9 @@ describe('setup-node', () => { expect(logSpy).toHaveBeenCalledWith( 'Attempt to resolve the latest version from manifest...' ); - expect(dbgSpy).toHaveBeenCalledWith('No manifest cached, getting manifest from actions/node-versions@main') + expect(dbgSpy).toHaveBeenCalledWith( + 'No manifest cached, getting manifest from actions/node-versions@main' + ); expect(logSpy).toHaveBeenCalledWith("Resolved as '12.16.2'"); expect(logSpy).toHaveBeenCalledWith( `Acquiring 12.16.2 - ${os.arch} from ${expectedUrl}` @@ -482,7 +488,9 @@ describe('setup-node', () => { expect(logSpy).toHaveBeenCalledWith( 'Attempt to resolve the latest version from manifest...' ); - expect(dbgSpy).toHaveBeenCalledWith('No manifest cached, getting manifest from actions/node-versions@main') + expect(dbgSpy).toHaveBeenCalledWith( + 'No manifest cached, getting manifest from actions/node-versions@main' + ); expect(logSpy).toHaveBeenCalledWith( `Failed to resolve version ${versionSpec} from manifest` ); @@ -553,13 +561,25 @@ describe('setup-node', () => { 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, getting manifest from actions/node-versions@main') - expect(dbgSpy).toHaveBeenCalledWith(`LTS alias 'erbium' for Node version 'lts/erbium'`) - expect(dbgSpy).toHaveBeenCalledWith(`Found LTS release '12.16.2' for Node version 'lts/erbium'`) + 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, getting manifest from actions/node-versions@main' + ); + expect(dbgSpy).toHaveBeenCalledWith( + `LTS alias 'erbium' for Node version 'lts/erbium'` + ); + expect(dbgSpy).toHaveBeenCalledWith( + `Found LTS release '12.16.2' for Node version 'lts/erbium'` + ); expect(logSpy).toHaveBeenCalledWith(`Found in cache @ ${toolPath}`); - expect(cnSpy).toHaveBeenCalledWith(`::add-path::${toolPath}/bin${osm.EOL}`); + expect(cnSpy).toHaveBeenCalledWith( + `::add-path::${toolPath}/bin${osm.EOL}` + ); }); it('find latest LTS version and install it from manifest (lts/erbium)', async () => { @@ -575,23 +595,38 @@ describe('setup-node', () => { 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'; + 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, getting manifest from actions/node-versions@main') - expect(dbgSpy).toHaveBeenCalledWith(`LTS alias 'erbium' for Node version 'lts/erbium'`) - expect(dbgSpy).toHaveBeenCalledWith(`Found LTS release '12.16.2' for Node version 'lts/erbium'`) - expect(logSpy).toHaveBeenCalledWith("Attempting to download 12..."); - expect(logSpy).toHaveBeenCalledWith(`Acquiring 12.16.2 - ${os.arch} from ${expectedUrl}`); + 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, getting manifest from actions/node-versions@main' + ); + expect(dbgSpy).toHaveBeenCalledWith( + `LTS alias 'erbium' for Node version 'lts/erbium'` + ); + expect(dbgSpy).toHaveBeenCalledWith( + `Found LTS release '12.16.2' for Node version 'lts/erbium'` + ); + 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::${toolPath}/bin${osm.EOL}`); - }) + expect(cnSpy).toHaveBeenCalledWith( + `::add-path::${toolPath}/bin${osm.EOL}` + ); + }); it('find latest LTS version and resolve it from local cache (lts/*)', async () => { // arrange @@ -608,13 +643,25 @@ describe('setup-node', () => { 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, getting manifest from actions/node-versions@main') - expect(dbgSpy).toHaveBeenCalledWith(`LTS alias '*' for Node version 'lts/*'`) - expect(dbgSpy).toHaveBeenCalledWith(`Found LTS release '14.0.0' for Node version 'lts/*'`) + 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, getting manifest from actions/node-versions@main' + ); + expect(dbgSpy).toHaveBeenCalledWith( + `LTS alias '*' for Node version 'lts/*'` + ); + expect(dbgSpy).toHaveBeenCalledWith( + `Found LTS release '14.0.0' for Node version 'lts/*'` + ); expect(logSpy).toHaveBeenCalledWith(`Found in cache @ ${toolPath}`); - expect(cnSpy).toHaveBeenCalledWith(`::add-path::${toolPath}/bin${osm.EOL}`); + expect(cnSpy).toHaveBeenCalledWith( + `::add-path::${toolPath}/bin${osm.EOL}` + ); }); it('find latest LTS version and install it from manifest (lts/*)', async () => { @@ -630,23 +677,38 @@ describe('setup-node', () => { 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/14.0.0-20200423.30/node-14.0.0-linux-x64.tar.gz'; + const expectedUrl = + 'https://github.com/actions/node-versions/releases/download/14.0.0-20200423.30/node-14.0.0-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, getting manifest from actions/node-versions@main') - expect(dbgSpy).toHaveBeenCalledWith(`LTS alias '*' for Node version 'lts/*'`) - expect(dbgSpy).toHaveBeenCalledWith(`Found LTS release '14.0.0' for Node version 'lts/*'`) - expect(logSpy).toHaveBeenCalledWith("Attempting to download 14..."); - expect(logSpy).toHaveBeenCalledWith(`Acquiring 14.0.0 - ${os.arch} from ${expectedUrl}`); + 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, getting manifest from actions/node-versions@main' + ); + expect(dbgSpy).toHaveBeenCalledWith( + `LTS alias '*' for Node version 'lts/*'` + ); + expect(dbgSpy).toHaveBeenCalledWith( + `Found LTS release '14.0.0' for Node version 'lts/*'` + ); + expect(logSpy).toHaveBeenCalledWith('Attempting to download 14...'); + expect(logSpy).toHaveBeenCalledWith( + `Acquiring 14.0.0 - ${os.arch} from ${expectedUrl}` + ); expect(logSpy).toHaveBeenCalledWith('Extracting ...'); expect(logSpy).toHaveBeenCalledWith('Adding to the cache ...'); - expect(cnSpy).toHaveBeenCalledWith(`::add-path::${toolPath}/bin${osm.EOL}`); - }) + expect(cnSpy).toHaveBeenCalledWith( + `::add-path::${toolPath}/bin${osm.EOL}` + ); + }); it('fail with unexpected LTS alias (lts/)', async () => { // arrange @@ -662,9 +724,15 @@ describe('setup-node', () => { 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(cnSpy).toHaveBeenCalledWith(`::error::Unexpected LTS alias '' for Node version 'lts/'${osm.EOL}`) + expect(logSpy).toHaveBeenCalledWith( + 'Attempt to resolve LTS alias from manifest...' + ); + expect(dbgSpy).toHaveBeenCalledWith( + 'Getting manifest from actions/node-versions@main' + ); + expect(cnSpy).toHaveBeenCalledWith( + `::error::Unexpected LTS alias '' for Node version 'lts/'${osm.EOL}` + ); }); it('fail to find LTS version (lts/unknown)', async () => { @@ -681,10 +749,18 @@ describe('setup-node', () => { 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).toHaveBeenCalledWith(`LTS alias 'unknown' for Node version 'lts/unknown'`) - expect(cnSpy).toHaveBeenCalledWith(`::error::Unable to find LTS release 'unknown' for Node version 'lts/unknown'.${osm.EOL}`) + expect(logSpy).toHaveBeenCalledWith( + 'Attempt to resolve LTS alias from manifest...' + ); + expect(dbgSpy).toHaveBeenCalledWith( + 'Getting manifest from actions/node-versions@main' + ); + expect(dbgSpy).toHaveBeenCalledWith( + `LTS alias 'unknown' for Node version 'lts/unknown'` + ); + expect(cnSpy).toHaveBeenCalledWith( + `::error::Unable to find LTS release 'unknown' for Node version 'lts/unknown'.${osm.EOL}` + ); }); it('fail if manifest is not available', async () => { @@ -705,9 +781,15 @@ describe('setup-node', () => { 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(cnSpy).toHaveBeenCalledWith(`::error::Unable to download manifest${osm.EOL}`) - }) - }) + expect(logSpy).toHaveBeenCalledWith( + 'Attempt to resolve LTS alias from manifest...' + ); + expect(dbgSpy).toHaveBeenCalledWith( + 'Getting manifest from actions/node-versions@main' + ); + expect(cnSpy).toHaveBeenCalledWith( + `::error::Unable to download manifest${osm.EOL}` + ); + }); + }); }); diff --git a/src/installer.ts b/src/installer.ts index ac7be1c..2001f4d 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -42,9 +42,14 @@ export async function getNode( if (isLtsAlias(versionSpec)) { core.info('Attempt to resolve LTS alias from manifest...'); - core.debug('Getting manifest from actions/node-versions@main') + core.debug('Getting manifest from actions/node-versions@main'); // No try-catch since it's not possible to resolve LTS alias without manifest - manifest = await tc.getManifestFromRepo('actions', 'node-versions', auth, 'main'); + manifest = await tc.getManifestFromRepo( + 'actions', + 'node-versions', + auth, + 'main' + ); versionSpec = resolveLtsAliasFromManifest(versionSpec, stable, manifest); } @@ -81,7 +86,13 @@ export async function getNode( // Try download from internal distribution (popular versions only) // try { - info = await getInfoFromManifest(versionSpec, stable, auth, osArch, manifest); + info = await getInfoFromManifest( + versionSpec, + stable, + auth, + osArch, + manifest + ); if (info) { core.info( `Acquiring ${info.resolvedVersion} - ${info.arch} from ${info.downloadUrl}` @@ -186,7 +197,7 @@ export async function getNode( } function isLtsAlias(versionSpec: string): boolean { - return versionSpec.startsWith('lts') + return versionSpec.startsWith('lts'); } function resolveLtsAliasFromManifest( @@ -197,21 +208,30 @@ function resolveLtsAliasFromManifest( const alias = versionSpec.split('lts/')[1]?.toLowerCase(); if (!alias) { - throw new Error(`Unexpected LTS alias '${alias}' for Node version '${versionSpec}'`); + throw new Error( + `Unexpected LTS alias '${alias}' for Node version '${versionSpec}'` + ); } core.debug(`LTS alias '${alias}' for Node version '${versionSpec}'`); // Supported formats are `lts/` and `lts/*`. Where asterisk means highest possible LTS. - const release = alias === '*' - ? manifest.find(x => !!x.lts && x.stable === stable) - : manifest.find(x => x.lts?.toLowerCase() === alias && x.stable === stable); + const release = + alias === '*' + ? manifest.find(x => !!x.lts && x.stable === stable) + : manifest.find( + x => x.lts?.toLowerCase() === alias && x.stable === stable + ); if (!release) { - throw new Error(`Unable to find LTS release '${alias}' for Node version '${versionSpec}'.`); + throw new Error( + `Unable to find LTS release '${alias}' for Node version '${versionSpec}'.` + ); } - core.debug(`Found LTS release '${release.version}' for Node version '${versionSpec}'`); + core.debug( + `Found LTS release '${release.version}' for Node version '${versionSpec}'` + ); return release.version.split('.')[0]; } @@ -225,7 +245,9 @@ async function getInfoFromManifest( ): Promise { let info: INodeVersionInfo | null = null; if (!manifest) { - core.debug('No manifest cached, getting manifest from actions/node-versions@main') + core.debug( + 'No manifest cached, getting manifest from actions/node-versions@main' + ); manifest = await tc.getManifestFromRepo( 'actions', @@ -290,7 +312,13 @@ async function resolveVersionFromManifest( manifest: tc.IToolRelease[] | undefined ): Promise { try { - const info = await getInfoFromManifest(versionSpec, stable, auth, osArch, manifest); + const info = await getInfoFromManifest( + versionSpec, + stable, + auth, + osArch, + manifest + ); return info?.resolvedVersion; } catch (err) { core.info('Unable to resolve version from manifest...'); From c2dfe2df9884bf1033e0ee352d86309105ea6cf0 Mon Sep 17 00:00:00 2001 From: Gordey Doronin Date: Tue, 22 Jun 2021 17:52:06 +0200 Subject: [PATCH 13/18] Reuse manifest code --- __tests__/installer.test.ts | 28 ++++++++++++---------------- dist/index.js | 11 +++++++---- src/installer.ts | 27 ++++++++++----------------- 3 files changed, 29 insertions(+), 37 deletions(-) diff --git a/__tests__/installer.test.ts b/__tests__/installer.test.ts index 2fc88d6..a6907c4 100644 --- a/__tests__/installer.test.ts +++ b/__tests__/installer.test.ts @@ -399,8 +399,9 @@ describe('setup-node', () => { expect(logSpy).not.toHaveBeenCalledWith( 'Attempt to resolve the latest version from manifest...' ); + expect(dbgSpy).not.toHaveBeenCalledWith('No manifest cached'); expect(dbgSpy).not.toHaveBeenCalledWith( - 'No manifest cached, getting manifest from actions/node-versions@main' + 'Getting manifest from actions/node-versions@main' ); }); @@ -422,8 +423,9 @@ describe('setup-node', () => { expect(logSpy).toHaveBeenCalledWith( 'Attempt to resolve the latest version from manifest...' ); + expect(dbgSpy).toHaveBeenCalledWith('No manifest cached'); expect(dbgSpy).toHaveBeenCalledWith( - 'No manifest cached, getting manifest from actions/node-versions@main' + 'Getting manifest from actions/node-versions@main' ); expect(logSpy).toHaveBeenCalledWith("Resolved as '12.16.2'"); expect(logSpy).toHaveBeenCalledWith(`Found in cache @ ${toolPath}`); @@ -449,8 +451,9 @@ describe('setup-node', () => { expect(logSpy).toHaveBeenCalledWith( 'Attempt to resolve the latest version from manifest...' ); + expect(dbgSpy).toHaveBeenCalledWith('No manifest cached'); expect(dbgSpy).toHaveBeenCalledWith( - 'No manifest cached, getting manifest from actions/node-versions@main' + 'Getting manifest from actions/node-versions@main' ); expect(logSpy).toHaveBeenCalledWith("Resolved as '12.16.2'"); expect(logSpy).toHaveBeenCalledWith( @@ -488,8 +491,9 @@ describe('setup-node', () => { expect(logSpy).toHaveBeenCalledWith( 'Attempt to resolve the latest version from manifest...' ); + expect(dbgSpy).toHaveBeenCalledWith('No manifest cached'); expect(dbgSpy).toHaveBeenCalledWith( - 'No manifest cached, getting manifest from actions/node-versions@main' + 'Getting manifest from actions/node-versions@main' ); expect(logSpy).toHaveBeenCalledWith( `Failed to resolve version ${versionSpec} from manifest` @@ -567,9 +571,7 @@ describe('setup-node', () => { expect(dbgSpy).toHaveBeenCalledWith( 'Getting manifest from actions/node-versions@main' ); - expect(dbgSpy).not.toHaveBeenCalledWith( - 'No manifest cached, getting manifest from actions/node-versions@main' - ); + expect(dbgSpy).not.toHaveBeenCalledWith('No manifest cached'); expect(dbgSpy).toHaveBeenCalledWith( `LTS alias 'erbium' for Node version 'lts/erbium'` ); @@ -608,9 +610,7 @@ describe('setup-node', () => { expect(dbgSpy).toHaveBeenCalledWith( 'Getting manifest from actions/node-versions@main' ); - expect(dbgSpy).not.toHaveBeenCalledWith( - 'No manifest cached, getting manifest from actions/node-versions@main' - ); + expect(dbgSpy).not.toHaveBeenCalledWith('No manifest cached'); expect(dbgSpy).toHaveBeenCalledWith( `LTS alias 'erbium' for Node version 'lts/erbium'` ); @@ -649,9 +649,7 @@ describe('setup-node', () => { expect(dbgSpy).toHaveBeenCalledWith( 'Getting manifest from actions/node-versions@main' ); - expect(dbgSpy).not.toHaveBeenCalledWith( - 'No manifest cached, getting manifest from actions/node-versions@main' - ); + expect(dbgSpy).not.toHaveBeenCalledWith('No manifest cached'); expect(dbgSpy).toHaveBeenCalledWith( `LTS alias '*' for Node version 'lts/*'` ); @@ -690,9 +688,7 @@ describe('setup-node', () => { expect(dbgSpy).toHaveBeenCalledWith( 'Getting manifest from actions/node-versions@main' ); - expect(dbgSpy).not.toHaveBeenCalledWith( - 'No manifest cached, getting manifest from actions/node-versions@main' - ); + expect(dbgSpy).not.toHaveBeenCalledWith('No manifest cached'); expect(dbgSpy).toHaveBeenCalledWith( `LTS alias '*' for Node version 'lts/*'` ); diff --git a/dist/index.js b/dist/index.js index a1f7f05..170f827 100644 --- a/dist/index.js +++ b/dist/index.js @@ -13111,9 +13111,8 @@ function getNode(versionSpec, stable, checkLatest, auth, arch = os.arch()) { let osArch = translateArchToDistUrl(arch); if (isLtsAlias(versionSpec)) { core.info('Attempt to resolve LTS alias from manifest...'); - core.debug('Getting manifest from actions/node-versions@main'); // No try-catch since it's not possible to resolve LTS alias without manifest - manifest = yield tc.getManifestFromRepo('actions', 'node-versions', auth, 'main'); + manifest = yield getManifest(auth); versionSpec = resolveLtsAliasFromManifest(versionSpec, stable, manifest); } if (checkLatest) { @@ -13228,6 +13227,10 @@ exports.getNode = getNode; function isLtsAlias(versionSpec) { return versionSpec.startsWith('lts'); } +function getManifest(auth) { + core.debug('Getting manifest from actions/node-versions@main'); + return tc.getManifestFromRepo('actions', 'node-versions', auth, 'main'); +} function resolveLtsAliasFromManifest(versionSpec, stable, manifest) { var _a; const alias = (_a = versionSpec.split('lts/')[1]) === null || _a === void 0 ? void 0 : _a.toLowerCase(); @@ -13249,8 +13252,8 @@ function getInfoFromManifest(versionSpec, stable, auth, osArch = translateArchTo return __awaiter(this, void 0, void 0, function* () { let info = null; if (!manifest) { - core.debug('No manifest cached, getting manifest from actions/node-versions@main'); - manifest = yield tc.getManifestFromRepo('actions', 'node-versions', auth, 'main'); + core.debug('No manifest cached'); + manifest = yield getManifest(auth); } const rel = yield tc.findFromManifest(versionSpec, stable, manifest, osArch); if (rel && rel.files.length > 0) { diff --git a/src/installer.ts b/src/installer.ts index 2001f4d..47d24c9 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -42,14 +42,10 @@ export async function getNode( if (isLtsAlias(versionSpec)) { core.info('Attempt to resolve LTS alias from manifest...'); - core.debug('Getting manifest from actions/node-versions@main'); + // No try-catch since it's not possible to resolve LTS alias without manifest - manifest = await tc.getManifestFromRepo( - 'actions', - 'node-versions', - auth, - 'main' - ); + manifest = await getManifest(auth); + versionSpec = resolveLtsAliasFromManifest(versionSpec, stable, manifest); } @@ -200,6 +196,11 @@ function isLtsAlias(versionSpec: string): boolean { return versionSpec.startsWith('lts'); } +function getManifest(auth: string | undefined): Promise { + core.debug('Getting manifest from actions/node-versions@main'); + return tc.getManifestFromRepo('actions', 'node-versions', auth, 'main'); +} + function resolveLtsAliasFromManifest( versionSpec: string, stable: boolean, @@ -245,16 +246,8 @@ async function getInfoFromManifest( ): Promise { let info: INodeVersionInfo | null = null; if (!manifest) { - core.debug( - 'No manifest cached, getting manifest from actions/node-versions@main' - ); - - manifest = await tc.getManifestFromRepo( - 'actions', - 'node-versions', - auth, - 'main' - ); + core.debug('No manifest cached'); + manifest = await getManifest(auth); } const rel = await tc.findFromManifest(versionSpec, stable, manifest, osArch); From 9b447f0b81b0095ab8349f9ea321f6d07b174b0b Mon Sep 17 00:00:00 2001 From: Gordey Doronin Date: Fri, 25 Jun 2021 11:48:41 +0200 Subject: [PATCH 14/18] Fix paths for windows tests --- __tests__/installer.test.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/__tests__/installer.test.ts b/__tests__/installer.test.ts index a6907c4..0376761 100644 --- a/__tests__/installer.test.ts +++ b/__tests__/installer.test.ts @@ -580,7 +580,7 @@ describe('setup-node', () => { ); expect(logSpy).toHaveBeenCalledWith(`Found in cache @ ${toolPath}`); expect(cnSpy).toHaveBeenCalledWith( - `::add-path::${toolPath}/bin${osm.EOL}` + `::add-path::${path.join(toolPath, 'bin')}${osm.EOL}` ); }); @@ -624,7 +624,7 @@ describe('setup-node', () => { expect(logSpy).toHaveBeenCalledWith('Extracting ...'); expect(logSpy).toHaveBeenCalledWith('Adding to the cache ...'); expect(cnSpy).toHaveBeenCalledWith( - `::add-path::${toolPath}/bin${osm.EOL}` + `::add-path::${path.join(toolPath, 'bin')}${osm.EOL}` ); }); @@ -658,7 +658,7 @@ describe('setup-node', () => { ); expect(logSpy).toHaveBeenCalledWith(`Found in cache @ ${toolPath}`); expect(cnSpy).toHaveBeenCalledWith( - `::add-path::${toolPath}/bin${osm.EOL}` + `::add-path::${path.join(toolPath, 'bin')}${osm.EOL}` ); }); @@ -702,7 +702,7 @@ describe('setup-node', () => { expect(logSpy).toHaveBeenCalledWith('Extracting ...'); expect(logSpy).toHaveBeenCalledWith('Adding to the cache ...'); expect(cnSpy).toHaveBeenCalledWith( - `::add-path::${toolPath}/bin${osm.EOL}` + `::add-path::${path.join(toolPath, 'bin')}${osm.EOL}` ); }); From 4bef829942f19576d693e96c710bcfdc93352956 Mon Sep 17 00:00:00 2001 From: Gordey Doronin Date: Fri, 25 Jun 2021 11:56:15 +0200 Subject: [PATCH 15/18] Add e2e test for lts-syntax --- .github/workflows/versions.yml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/.github/workflows/versions.yml b/.github/workflows/versions.yml index 2058b02..6ea1e40 100644 --- a/.github/workflows/versions.yml +++ b/.github/workflows/versions.yml @@ -29,6 +29,23 @@ jobs: run: __tests__/verify-node.sh "${{ matrix.node-version }}" shell: bash + lts-syntax: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, windows-latest, macos-latest] + node-version: [lts/dubnium, lts/erbium, lts/fermium, lts/*] + steps: + - uses: actions/checkout@v2 + - name: Setup Node + uses: ./ + with: + node-version: ${{ matrix.node-version }} + - name: Verify node and npm + run: __tests__/verify-node.sh "${{ matrix.node-version }}" + shell: bash + manifest: runs-on: ${{ matrix.os }} strategy: From 57b9c8c424ced4e02e087acbad689bd982229567 Mon Sep 17 00:00:00 2001 From: Gordey Doronin Date: Fri, 25 Jun 2021 12:13:33 +0200 Subject: [PATCH 16/18] Don't run verify check on lts syntax --- .github/workflows/versions.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/versions.yml b/.github/workflows/versions.yml index 6ea1e40..4dc5c31 100644 --- a/.github/workflows/versions.yml +++ b/.github/workflows/versions.yml @@ -42,9 +42,6 @@ jobs: uses: ./ with: node-version: ${{ matrix.node-version }} - - name: Verify node and npm - run: __tests__/verify-node.sh "${{ matrix.node-version }}" - shell: bash manifest: runs-on: ${{ matrix.os }} From 8624ddbdce6443553a7b456fd5f0b66ae19ee70f Mon Sep 17 00:00:00 2001 From: Gordey Doronin Date: Wed, 30 Jun 2021 09:27:49 +0200 Subject: [PATCH 17/18] Extract common setup logic to hook --- __tests__/installer.test.ts | 34 ++++++---------------------------- 1 file changed, 6 insertions(+), 28 deletions(-) diff --git a/__tests__/installer.test.ts b/__tests__/installer.test.ts index 0376761..59fc979 100644 --- a/__tests__/installer.test.ts +++ b/__tests__/installer.test.ts @@ -550,13 +550,15 @@ describe('setup-node', () => { }); describe('LTS version', () => { - it('find latest LTS version and resolve it from local cache (lts/erbium)', async () => { - // arrange + beforeEach(() => { os.platform = 'linux'; os.arch = 'x64'; - - inputs['node-version'] = 'lts/erbium'; inputs.stable = 'true'; + }); + + it('find latest LTS version and resolve it from local cache (lts/erbium)', async () => { + // arrange + inputs['node-version'] = 'lts/erbium'; const toolPath = path.normalize('/cache/node/12.16.2/x64'); findSpy.mockReturnValue(toolPath); @@ -586,11 +588,7 @@ describe('setup-node', () => { it('find latest LTS version and install it from manifest (lts/erbium)', async () => { // arrange - os.platform = 'linux'; - os.arch = 'x64'; - inputs['node-version'] = 'lts/erbium'; - inputs.stable = 'true'; const toolPath = path.normalize('/cache/node/12.16.2/x64'); findSpy.mockImplementation(() => ''); @@ -630,11 +628,7 @@ describe('setup-node', () => { it('find latest LTS version and resolve it from local cache (lts/*)', async () => { // arrange - os.platform = 'linux'; - os.arch = 'x64'; - inputs['node-version'] = 'lts/*'; - inputs.stable = 'true'; const toolPath = path.normalize('/cache/node/14.0.0/x64'); findSpy.mockReturnValue(toolPath); @@ -664,11 +658,7 @@ describe('setup-node', () => { it('find latest LTS version and install it from manifest (lts/*)', async () => { // arrange - os.platform = 'linux'; - os.arch = 'x64'; - inputs['node-version'] = 'lts/*'; - inputs.stable = 'true'; const toolPath = path.normalize('/cache/node/14.0.0/x64'); findSpy.mockImplementation(() => ''); @@ -708,11 +698,7 @@ describe('setup-node', () => { it('fail with unexpected LTS alias (lts/)', async () => { // arrange - os.platform = 'linux'; - os.arch = 'x64'; - inputs['node-version'] = 'lts/'; - inputs.stable = 'true'; findSpy.mockImplementation(() => ''); @@ -733,11 +719,7 @@ describe('setup-node', () => { it('fail to find LTS version (lts/unknown)', async () => { // arrange - os.platform = 'linux'; - os.arch = 'x64'; - inputs['node-version'] = 'lts/unknown'; - inputs.stable = 'true'; findSpy.mockImplementation(() => ''); @@ -761,11 +743,7 @@ describe('setup-node', () => { it('fail if manifest is not available', async () => { // arrange - os.platform = 'linux'; - os.arch = 'x64'; - inputs['node-version'] = 'lts/erbium'; - inputs.stable = 'true'; // ... but not in the local cache findSpy.mockImplementation(() => ''); From 48042628a6db42682e77501e473361c6da26bbb0 Mon Sep 17 00:00:00 2001 From: Gordey Doronin Date: Wed, 30 Jun 2021 09:34:42 +0200 Subject: [PATCH 18/18] Stricter check and cleaner messaging --- __tests__/installer.test.ts | 4 ++-- dist/index.js | 4 ++-- src/installer.ts | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/__tests__/installer.test.ts b/__tests__/installer.test.ts index 59fc979..9948923 100644 --- a/__tests__/installer.test.ts +++ b/__tests__/installer.test.ts @@ -696,7 +696,7 @@ describe('setup-node', () => { ); }); - it('fail with unexpected LTS alias (lts/)', async () => { + it('fail with unable to parse LTS alias (lts/)', async () => { // arrange inputs['node-version'] = 'lts/'; @@ -713,7 +713,7 @@ describe('setup-node', () => { 'Getting manifest from actions/node-versions@main' ); expect(cnSpy).toHaveBeenCalledWith( - `::error::Unexpected LTS alias '' for Node version 'lts/'${osm.EOL}` + `::error::Unable to parse LTS alias for Node version 'lts/'${osm.EOL}` ); }); diff --git a/dist/index.js b/dist/index.js index 170f827..1c614cd 100644 --- a/dist/index.js +++ b/dist/index.js @@ -13225,7 +13225,7 @@ function getNode(versionSpec, stable, checkLatest, auth, arch = os.arch()) { } exports.getNode = getNode; function isLtsAlias(versionSpec) { - return versionSpec.startsWith('lts'); + return versionSpec.startsWith('lts/'); } function getManifest(auth) { core.debug('Getting manifest from actions/node-versions@main'); @@ -13235,7 +13235,7 @@ function resolveLtsAliasFromManifest(versionSpec, stable, manifest) { var _a; const alias = (_a = versionSpec.split('lts/')[1]) === null || _a === void 0 ? void 0 : _a.toLowerCase(); if (!alias) { - throw new Error(`Unexpected LTS alias '${alias}' for Node version '${versionSpec}'`); + throw new Error(`Unable to parse LTS alias for Node version '${versionSpec}'`); } core.debug(`LTS alias '${alias}' for Node version '${versionSpec}'`); // Supported formats are `lts/` and `lts/*`. Where asterisk means highest possible LTS. diff --git a/src/installer.ts b/src/installer.ts index 47d24c9..b43e544 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -193,7 +193,7 @@ export async function getNode( } function isLtsAlias(versionSpec: string): boolean { - return versionSpec.startsWith('lts'); + return versionSpec.startsWith('lts/'); } function getManifest(auth: string | undefined): Promise { @@ -210,7 +210,7 @@ function resolveLtsAliasFromManifest( if (!alias) { throw new Error( - `Unexpected LTS alias '${alias}' for Node version '${versionSpec}'` + `Unable to parse LTS alias for Node version '${versionSpec}'` ); }