From ccb6d0562b735a1599e5cac6f70b614e2d030a9f Mon Sep 17 00:00:00 2001 From: Dmitry Shibanov Date: Thu, 13 Oct 2022 14:15:49 +0200 Subject: [PATCH 01/14] add nightly build support --- .github/workflows/versions.yml | 20 +++++++++++++++++ dist/setup/index.js | 40 ++++++++++++++++++++++++--------- src/installer.ts | 41 +++++++++++++++++++++++++--------- 3 files changed, 81 insertions(+), 20 deletions(-) diff --git a/.github/workflows/versions.yml b/.github/workflows/versions.yml index 9a138ebb..5292aa4d 100644 --- a/.github/workflows/versions.yml +++ b/.github/workflows/versions.yml @@ -51,6 +51,26 @@ jobs: __tests__/verify-node.sh "${BASH_REMATCH[1]}" shell: bash + nightly-syntax: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, windows-latest, macos-latest] + node-version: [17-nightly, 18-nightly, 19-nightly] + steps: + - uses: actions/checkout@v3 + - name: Setup Node + uses: ./ + with: + node-version: ${{ matrix.node-version }} + - name: Verify node and npm + run: | + nightlyVersion="${{ matrix.node-version }}" + majorVersion=$(echo $nightlyVersion | cut -d- -f1) + __tests__/verify-node.sh "${BASH_REMATCH[1]}" + shell: bash + manifest: runs-on: ${{ matrix.os }} strategy: diff --git a/dist/setup/index.js b/dist/setup/index.js index 0daaa2f2..ba9be2fc 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -73194,6 +73194,7 @@ function getNode(versionSpec, stable, checkLatest, auth, arch = os.arch()) { // Store manifest data to avoid multiple calls let manifest; let nodeVersions; + let isNightly = versionSpec.includes('nightly'); let osPlat = os.platform(); let osArch = translateArchToDistUrl(arch); if (isLtsAlias(versionSpec)) { @@ -73203,10 +73204,14 @@ function getNode(versionSpec, stable, checkLatest, auth, arch = os.arch()) { versionSpec = resolveLtsAliasFromManifest(versionSpec, stable, manifest); } if (isLatestSyntax(versionSpec)) { - nodeVersions = yield getVersionsFromDist(); + nodeVersions = yield getVersionsFromDist(versionSpec); versionSpec = yield queryDistForMatch(versionSpec, arch, nodeVersions); core.info(`getting latest node version...`); } + if (isNightly) { + nodeVersions = yield getVersionsFromDist(versionSpec); + versionSpec = yield queryDistForMatch(versionSpec, arch, nodeVersions); + } if (checkLatest) { core.info('Attempt to resolve the latest version from manifest...'); const resolvedVersion = yield resolveVersionFromManifest(versionSpec, stable, auth, osArch, manifest); @@ -73382,7 +73387,8 @@ function getInfoFromDist(versionSpec, arch = os.arch(), nodeVersions) { ? `node-v${version}-win-${osArch}` : `node-v${version}-${osPlat}-${osArch}`; let urlFileName = osPlat == 'win32' ? `${fileName}.7z` : `${fileName}.tar.gz`; - let url = `https://nodejs.org/dist/v${version}/${urlFileName}`; + const initialUrl = getNodejsDistUrl(versionSpec); + let url = `${initialUrl}/v${version}/${urlFileName}`; return { downloadUrl: url, resolvedVersion: version, @@ -73407,7 +73413,7 @@ function resolveVersionFromManifest(versionSpec, stable, auth, osArch = translat function evaluateVersions(versions, versionSpec) { let version = ''; core.debug(`evaluating ${versions.length} versions`); - versions = versions.sort((a, b) => { + versions = versions.map(item => item.replace('nightly', 'nightly.')).sort((a, b) => { if (semver.gt(a, b)) { return 1; } @@ -73429,6 +73435,18 @@ function evaluateVersions(versions, versionSpec) { } return version; } +function getNodejsDistUrl(version) { + const prerelease = semver.prerelease(version); + if (!prerelease || !prerelease.length) { + return 'https://nodejs.org/dist'; + } + else if (prerelease[0] === 'nightly') { + return 'https://nodejs.org/download/nightly'; + } + else { + return 'https://nodejs.org/download/rc'; + } +} function queryDistForMatch(versionSpec, arch = os.arch(), nodeVersions) { return __awaiter(this, void 0, void 0, function* () { let osPlat = os.platform(); @@ -73450,7 +73468,7 @@ function queryDistForMatch(versionSpec, arch = os.arch(), nodeVersions) { } if (!nodeVersions) { core.debug('No dist manifest cached'); - nodeVersions = yield getVersionsFromDist(); + nodeVersions = yield getVersionsFromDist(versionSpec); } let versions = []; if (isLatestSyntax(versionSpec)) { @@ -73468,9 +73486,10 @@ function queryDistForMatch(versionSpec, arch = os.arch(), nodeVersions) { return version; }); } -function getVersionsFromDist() { +function getVersionsFromDist(versionSpec) { return __awaiter(this, void 0, void 0, function* () { - let dataUrl = 'https://nodejs.org/dist/index.json'; + const initialUrl = getNodejsDistUrl(versionSpec); + const dataUrl = `${initialUrl}/index.json`; let httpClient = new hc.HttpClient('setup-node', [], { allowRetries: true, maxRetries: 3 @@ -73494,6 +73513,7 @@ exports.getVersionsFromDist = getVersionsFromDist; // and lib file in a folder, not zipped. function acquireNodeFromFallbackLocation(version, arch = os.arch()) { return __awaiter(this, void 0, void 0, function* () { + const initialUrl = getNodejsDistUrl(version); let osPlat = os.platform(); let osArch = translateArchToDistUrl(arch); // Create temporary folder to download in to @@ -73505,8 +73525,8 @@ function acquireNodeFromFallbackLocation(version, arch = os.arch()) { let exeUrl; let libUrl; try { - exeUrl = `https://nodejs.org/dist/v${version}/win-${osArch}/node.exe`; - libUrl = `https://nodejs.org/dist/v${version}/win-${osArch}/node.lib`; + exeUrl = `${initialUrl}/v${version}/win-${osArch}/node.exe`; + libUrl = `${initialUrl}/v${version}/win-${osArch}/node.lib`; core.info(`Downloading only node binary from ${exeUrl}`); const exePath = yield tc.downloadTool(exeUrl); yield io.cp(exePath, path.join(tempDir, 'node.exe')); @@ -73515,8 +73535,8 @@ function acquireNodeFromFallbackLocation(version, arch = os.arch()) { } catch (err) { if (err instanceof tc.HTTPError && err.httpStatusCode == 404) { - exeUrl = `https://nodejs.org/dist/v${version}/node.exe`; - libUrl = `https://nodejs.org/dist/v${version}/node.lib`; + exeUrl = `${initialUrl}/v${version}/node.exe`; + libUrl = `${initialUrl}/v${version}/node.lib`; const exePath = yield tc.downloadTool(exeUrl); yield io.cp(exePath, path.join(tempDir, 'node.exe')); const libPath = yield tc.downloadTool(libUrl); diff --git a/src/installer.ts b/src/installer.ts index 83a43d85..4292d892 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -11,6 +11,7 @@ import fs = require('fs'); // // Node versions interface // see https://nodejs.org/dist/index.json +// for nightly https://nodejs.org/download/nightly/index.json // export interface INodeVersion { version: string; @@ -38,6 +39,7 @@ export async function getNode( // Store manifest data to avoid multiple calls let manifest: INodeRelease[] | undefined; let nodeVersions: INodeVersion[] | undefined; + let isNightly = versionSpec.includes('nightly'); let osPlat: string = os.platform(); let osArch: string = translateArchToDistUrl(arch); @@ -51,11 +53,16 @@ export async function getNode( } if (isLatestSyntax(versionSpec)) { - nodeVersions = await getVersionsFromDist(); + nodeVersions = await getVersionsFromDist(versionSpec); versionSpec = await queryDistForMatch(versionSpec, arch, nodeVersions); core.info(`getting latest node version...`); } + if (isNightly) { + nodeVersions = await getVersionsFromDist(versionSpec); + versionSpec = await queryDistForMatch(versionSpec, arch, nodeVersions); + } + if (checkLatest) { core.info('Attempt to resolve the latest version from manifest...'); const resolvedVersion = await resolveVersionFromManifest( @@ -306,7 +313,8 @@ async function getInfoFromDist( : `node-v${version}-${osPlat}-${osArch}`; let urlFileName: string = osPlat == 'win32' ? `${fileName}.7z` : `${fileName}.tar.gz`; - let url = `https://nodejs.org/dist/v${version}/${urlFileName}`; + const initialUrl = getNodejsDistUrl(versionSpec); + let url = `${initialUrl}/v${version}/${urlFileName}`; return { downloadUrl: url, @@ -342,7 +350,7 @@ async function resolveVersionFromManifest( function evaluateVersions(versions: string[], versionSpec: string): string { let version = ''; core.debug(`evaluating ${versions.length} versions`); - versions = versions.sort((a, b) => { + versions = versions.map(item => item.replace('nightly', 'nightly.')).sort((a, b) => { if (semver.gt(a, b)) { return 1; } @@ -366,6 +374,17 @@ function evaluateVersions(versions: string[], versionSpec: string): string { return version; } +function getNodejsDistUrl(version: string | semver.SemVer) { + const prerelease = semver.prerelease(version); + if (!prerelease || !prerelease.length) { + return 'https://nodejs.org/dist'; + } else if (prerelease[0] === 'nightly') { + return 'https://nodejs.org/download/nightly'; + } else { + return 'https://nodejs.org/download/rc'; + } +} + async function queryDistForMatch( versionSpec: string, arch: string = os.arch(), @@ -392,7 +411,7 @@ async function queryDistForMatch( if (!nodeVersions) { core.debug('No dist manifest cached'); - nodeVersions = await getVersionsFromDist(); + nodeVersions = await getVersionsFromDist(versionSpec); } let versions: string[] = []; @@ -414,8 +433,9 @@ async function queryDistForMatch( return version; } -export async function getVersionsFromDist(): Promise { - let dataUrl = 'https://nodejs.org/dist/index.json'; +export async function getVersionsFromDist(versionSpec: string): Promise { + const initialUrl = getNodejsDistUrl(versionSpec); + const dataUrl = `${initialUrl}/index.json`; let httpClient = new hc.HttpClient('setup-node', [], { allowRetries: true, maxRetries: 3 @@ -440,6 +460,7 @@ async function acquireNodeFromFallbackLocation( version: string, arch: string = os.arch() ): Promise { + const initialUrl = getNodejsDistUrl(version); let osPlat: string = os.platform(); let osArch: string = translateArchToDistUrl(arch); @@ -453,8 +474,8 @@ async function acquireNodeFromFallbackLocation( let exeUrl: string; let libUrl: string; try { - exeUrl = `https://nodejs.org/dist/v${version}/win-${osArch}/node.exe`; - libUrl = `https://nodejs.org/dist/v${version}/win-${osArch}/node.lib`; + exeUrl = `${initialUrl}/v${version}/win-${osArch}/node.exe`; + libUrl = `${initialUrl}/v${version}/win-${osArch}/node.lib`; core.info(`Downloading only node binary from ${exeUrl}`); @@ -464,8 +485,8 @@ async function acquireNodeFromFallbackLocation( await io.cp(libPath, path.join(tempDir, 'node.lib')); } catch (err) { if (err instanceof tc.HTTPError && err.httpStatusCode == 404) { - exeUrl = `https://nodejs.org/dist/v${version}/node.exe`; - libUrl = `https://nodejs.org/dist/v${version}/node.lib`; + exeUrl = `${initialUrl}/v${version}/node.exe`; + libUrl = `${initialUrl}/v${version}/node.lib`; const exePath = await tc.downloadTool(exeUrl); await io.cp(exePath, path.join(tempDir, 'node.exe')); From 4a77f694db29b879706b860e88f6cef55fbfde28 Mon Sep 17 00:00:00 2001 From: Dmitry Shibanov Date: Thu, 13 Oct 2022 15:14:57 +0200 Subject: [PATCH 02/14] testing: add debug lines --- dist/setup/index.js | 2 ++ src/installer.ts | 2 ++ 2 files changed, 4 insertions(+) diff --git a/dist/setup/index.js b/dist/setup/index.js index ba9be2fc..8f6d31a9 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -73413,6 +73413,8 @@ function resolveVersionFromManifest(versionSpec, stable, auth, osArch = translat function evaluateVersions(versions, versionSpec) { let version = ''; core.debug(`evaluating ${versions.length} versions`); + core.debug(`version 1 is ${versions[0]}`); + core.debug(`version spec is ${versionSpec}`); versions = versions.map(item => item.replace('nightly', 'nightly.')).sort((a, b) => { if (semver.gt(a, b)) { return 1; diff --git a/src/installer.ts b/src/installer.ts index 4292d892..53f4e633 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -350,6 +350,8 @@ async function resolveVersionFromManifest( function evaluateVersions(versions: string[], versionSpec: string): string { let version = ''; core.debug(`evaluating ${versions.length} versions`); + core.debug(`version 1 is ${versions[0]}`); + core.debug(`version spec is ${versionSpec}`); versions = versions.map(item => item.replace('nightly', 'nightly.')).sort((a, b) => { if (semver.gt(a, b)) { return 1; From ab789e9b5b3c5911ebe5c8d8fb27cdf9cf889548 Mon Sep 17 00:00:00 2001 From: Dmitry Shibanov Date: Thu, 13 Oct 2022 15:25:42 +0200 Subject: [PATCH 03/14] testing: add debug line --- dist/setup/index.js | 1 + src/installer.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/dist/setup/index.js b/dist/setup/index.js index 8f6d31a9..53dfb0e9 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -73224,6 +73224,7 @@ function getNode(versionSpec, stable, checkLatest, auth, arch = os.arch()) { } } // check cache + core.debug('check toolcache'); let toolPath; toolPath = tc.find('node', versionSpec, osArch); // If not found in cache, download diff --git a/src/installer.ts b/src/installer.ts index 53f4e633..c7e700b8 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -81,6 +81,7 @@ export async function getNode( } // check cache + core.debug('check toolcache'); let toolPath: string; toolPath = tc.find('node', versionSpec, osArch); From 20838dd9776f0bbd6ccf57ac26080f50b4c61824 Mon Sep 17 00:00:00 2001 From: Dmitry Shibanov Date: Thu, 13 Oct 2022 15:50:46 +0200 Subject: [PATCH 04/14] testing: add possible fixes --- dist/setup/index.js | 8 ++++---- src/installer.ts | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/dist/setup/index.js b/dist/setup/index.js index 53dfb0e9..6ee7f6f9 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -73208,11 +73208,11 @@ function getNode(versionSpec, stable, checkLatest, auth, arch = os.arch()) { versionSpec = yield queryDistForMatch(versionSpec, arch, nodeVersions); core.info(`getting latest node version...`); } - if (isNightly) { + if (isNightly && checkLatest) { nodeVersions = yield getVersionsFromDist(versionSpec); versionSpec = yield queryDistForMatch(versionSpec, arch, nodeVersions); } - if (checkLatest) { + if (checkLatest && !isNightly) { core.info('Attempt to resolve the latest version from manifest...'); const resolvedVersion = yield resolveVersionFromManifest(versionSpec, stable, auth, osArch, manifest); if (resolvedVersion) { @@ -73416,7 +73416,7 @@ function evaluateVersions(versions, versionSpec) { core.debug(`evaluating ${versions.length} versions`); core.debug(`version 1 is ${versions[0]}`); core.debug(`version spec is ${versionSpec}`); - versions = versions.map(item => item.replace('nightly', 'nightly.')).sort((a, b) => { + versions = versions.map(item => item.replace('-nightly', '+nightly.')).sort((a, b) => { if (semver.gt(a, b)) { return 1; } @@ -73424,7 +73424,7 @@ function evaluateVersions(versions, versionSpec) { }); for (let i = versions.length - 1; i >= 0; i--) { const potential = versions[i]; - const satisfied = semver.satisfies(potential, versionSpec); + const satisfied = semver.satisfies(potential, versionSpec.replace('-', '+')); if (satisfied) { version = potential; break; diff --git a/src/installer.ts b/src/installer.ts index c7e700b8..375b1894 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -58,12 +58,12 @@ export async function getNode( core.info(`getting latest node version...`); } - if (isNightly) { + if (isNightly && checkLatest) { nodeVersions = await getVersionsFromDist(versionSpec); versionSpec = await queryDistForMatch(versionSpec, arch, nodeVersions); } - if (checkLatest) { + if (checkLatest && !isNightly) { core.info('Attempt to resolve the latest version from manifest...'); const resolvedVersion = await resolveVersionFromManifest( versionSpec, @@ -353,7 +353,7 @@ function evaluateVersions(versions: string[], versionSpec: string): string { core.debug(`evaluating ${versions.length} versions`); core.debug(`version 1 is ${versions[0]}`); core.debug(`version spec is ${versionSpec}`); - versions = versions.map(item => item.replace('nightly', 'nightly.')).sort((a, b) => { + versions = versions.map(item => item.replace('-nightly', '+nightly.')).sort((a, b) => { if (semver.gt(a, b)) { return 1; } @@ -361,7 +361,7 @@ function evaluateVersions(versions: string[], versionSpec: string): string { }); for (let i = versions.length - 1; i >= 0; i--) { const potential: string = versions[i]; - const satisfied: boolean = semver.satisfies(potential, versionSpec); + const satisfied: boolean = semver.satisfies(potential, versionSpec.replace('-', '+')); if (satisfied) { version = potential; break; From ee9cdf3888e80924d973ab1c75455f4a5af4e2ca Mon Sep 17 00:00:00 2001 From: Dmitry Shibanov Date: Thu, 13 Oct 2022 16:23:29 +0200 Subject: [PATCH 05/14] testing: add possible fixes --- dist/setup/index.js | 6 +++--- src/installer.ts | 13 +++++++++---- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/dist/setup/index.js b/dist/setup/index.js index 6ee7f6f9..a0f91fef 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -73239,7 +73239,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, manifest); + info = yield getInfoFromManifest(versionSpec, !isNightly, auth, osArch, manifest); if (info) { core.info(`Acquiring ${info.resolvedVersion} - ${info.arch} from ${info.downloadUrl}`); downloadPath = yield tc.downloadTool(info.downloadUrl, undefined, auth); @@ -73416,7 +73416,7 @@ function evaluateVersions(versions, versionSpec) { core.debug(`evaluating ${versions.length} versions`); core.debug(`version 1 is ${versions[0]}`); core.debug(`version spec is ${versionSpec}`); - versions = versions.map(item => item.replace('-nightly', '+nightly.')).sort((a, b) => { + versions = versions.sort((a, b) => { if (semver.gt(a, b)) { return 1; } @@ -73424,7 +73424,7 @@ function evaluateVersions(versions, versionSpec) { }); for (let i = versions.length - 1; i >= 0; i--) { const potential = versions[i]; - const satisfied = semver.satisfies(potential, versionSpec.replace('-', '+')); + const satisfied = semver.satisfies(potential.replace('-nightly', '+nightly.'), versionSpec.replace('-nightly', '+nightly.')); if (satisfied) { version = potential; break; diff --git a/src/installer.ts b/src/installer.ts index 375b1894..595ea65f 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -99,7 +99,7 @@ export async function getNode( try { info = await getInfoFromManifest( versionSpec, - stable, + !isNightly, auth, osArch, manifest @@ -353,7 +353,7 @@ function evaluateVersions(versions: string[], versionSpec: string): string { core.debug(`evaluating ${versions.length} versions`); core.debug(`version 1 is ${versions[0]}`); core.debug(`version spec is ${versionSpec}`); - versions = versions.map(item => item.replace('-nightly', '+nightly.')).sort((a, b) => { + versions = versions.sort((a, b) => { if (semver.gt(a, b)) { return 1; } @@ -361,7 +361,10 @@ function evaluateVersions(versions: string[], versionSpec: string): string { }); for (let i = versions.length - 1; i >= 0; i--) { const potential: string = versions[i]; - const satisfied: boolean = semver.satisfies(potential, versionSpec.replace('-', '+')); + const satisfied: boolean = semver.satisfies( + potential.replace('-nightly', '+nightly.'), + versionSpec.replace('-nightly', '+nightly.') + ); if (satisfied) { version = potential; break; @@ -436,7 +439,9 @@ async function queryDistForMatch( return version; } -export async function getVersionsFromDist(versionSpec: string): Promise { +export async function getVersionsFromDist( + versionSpec: string +): Promise { const initialUrl = getNodejsDistUrl(versionSpec); const dataUrl = `${initialUrl}/index.json`; let httpClient = new hc.HttpClient('setup-node', [], { From 9b82ea39efc434d49bb3fa9234a5a49d0681183e Mon Sep 17 00:00:00 2001 From: Dmitry Shibanov Date: Thu, 13 Oct 2022 16:27:08 +0200 Subject: [PATCH 06/14] minor fix --- dist/setup/index.js | 2 +- src/installer.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dist/setup/index.js b/dist/setup/index.js index a0f91fef..f6f679a3 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -73424,7 +73424,7 @@ function evaluateVersions(versions, versionSpec) { }); for (let i = versions.length - 1; i >= 0; i--) { const potential = versions[i]; - const satisfied = semver.satisfies(potential.replace('-nightly', '+nightly.'), versionSpec.replace('-nightly', '+nightly.')); + const satisfied = semver.satisfies(potential.replace('-nightly', '+nightly.'), versionSpec.replace('-nightly', '+nightly')); if (satisfied) { version = potential; break; diff --git a/src/installer.ts b/src/installer.ts index 595ea65f..38e98bd7 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -363,7 +363,7 @@ function evaluateVersions(versions: string[], versionSpec: string): string { const potential: string = versions[i]; const satisfied: boolean = semver.satisfies( potential.replace('-nightly', '+nightly.'), - versionSpec.replace('-nightly', '+nightly.') + versionSpec.replace('-nightly', '+nightly') ); if (satisfied) { version = potential; From ccbc0aae4e18405fb6e97431e4b0cfaf74a90a91 Mon Sep 17 00:00:00 2001 From: Dmitry Shibanov Date: Thu, 13 Oct 2022 17:07:36 +0200 Subject: [PATCH 07/14] add major support --- dist/setup/index.js | 4 ++++ src/installer.ts | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/dist/setup/index.js b/dist/setup/index.js index f6f679a3..f4ff5882 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -73416,6 +73416,10 @@ function evaluateVersions(versions, versionSpec) { core.debug(`evaluating ${versions.length} versions`); core.debug(`version 1 is ${versions[0]}`); core.debug(`version spec is ${versionSpec}`); + versionSpec = + versionSpec.includes('nightly') && !semver.valid(versionSpec.split('-')[0]) + ? versionSpec.split('-')[0] + : versionSpec; versions = versions.sort((a, b) => { if (semver.gt(a, b)) { return 1; diff --git a/src/installer.ts b/src/installer.ts index 38e98bd7..32281996 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -353,6 +353,10 @@ function evaluateVersions(versions: string[], versionSpec: string): string { core.debug(`evaluating ${versions.length} versions`); core.debug(`version 1 is ${versions[0]}`); core.debug(`version spec is ${versionSpec}`); + versionSpec = + versionSpec.includes('nightly') && !semver.valid(versionSpec.split('-')[0]) + ? versionSpec.split('-')[0] + : versionSpec; versions = versions.sort((a, b) => { if (semver.gt(a, b)) { return 1; From d7c7dfa509893856457a91b19ad30a89aa506f36 Mon Sep 17 00:00:00 2001 From: Dmitry Shibanov Date: Wed, 19 Oct 2022 12:14:29 +0200 Subject: [PATCH 08/14] fix e2e test --- .github/workflows/versions.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/versions.yml b/.github/workflows/versions.yml index 5292aa4d..4b539a68 100644 --- a/.github/workflows/versions.yml +++ b/.github/workflows/versions.yml @@ -68,7 +68,7 @@ jobs: run: | nightlyVersion="${{ matrix.node-version }}" majorVersion=$(echo $nightlyVersion | cut -d- -f1) - __tests__/verify-node.sh "${BASH_REMATCH[1]}" + __tests__/verify-node.sh "$majorVersion" shell: bash manifest: From a4ae07903c6e148cd8d999d43d04a02fdd9241cf Mon Sep 17 00:00:00 2001 From: Dmitry Shibanov Date: Wed, 19 Oct 2022 14:03:13 +0200 Subject: [PATCH 09/14] fixing bugs --- __tests__/authutil.test.ts | 2 +- __tests__/installer.test.ts | 5 +-- dist/setup/index.js | 59 +++++++++++++++++++++++++------- src/installer.ts | 68 ++++++++++++++++++++++++++++++------- src/main.ts | 8 ++--- 5 files changed, 110 insertions(+), 32 deletions(-) diff --git a/__tests__/authutil.test.ts b/__tests__/authutil.test.ts index 1ec4e1e1..594c6a13 100644 --- a/__tests__/authutil.test.ts +++ b/__tests__/authutil.test.ts @@ -1,4 +1,4 @@ -import os = require('os'); +import os from 'os'; import * as fs from 'fs'; import * as path from 'path'; import * as core from '@actions/core'; diff --git a/__tests__/installer.test.ts b/__tests__/installer.test.ts index 28d77e7c..d359f7ab 100644 --- a/__tests__/installer.test.ts +++ b/__tests__/installer.test.ts @@ -6,7 +6,7 @@ import * as im from '../src/installer'; import * as cache from '@actions/cache'; import fs from 'fs'; import cp from 'child_process'; -import osm = require('os'); +import osm from 'os'; import path from 'path'; import each from 'jest-each'; import * as main from '../src/main'; @@ -138,7 +138,8 @@ describe('setup-node', () => { }); it('can mock dist versions', async () => { - let versions: im.INodeVersion[] = await im.getVersionsFromDist(); + const versionSpec = '1.2.3'; + let versions: im.INodeVersion[] = await im.getVersionsFromDist(versionSpec); expect(versions).toBeDefined(); expect(versions?.length).toBe(23); }); diff --git a/dist/setup/index.js b/dist/setup/index.js index f4ff5882..18342fae 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -73410,16 +73410,51 @@ function resolveVersionFromManifest(versionSpec, stable, auth, osArch = translat } }); } +function evaluateNightlyVersions(versions, versionSpec) { + let version = ''; + let range; + const [raw, prerelease] = versionSpec.split('-'); + const isValidVersion = semver.valid(raw); + const rawVersion = isValidVersion ? raw : semver.coerce(raw); + if (rawVersion) { + if (prerelease !== 'nightly') { + range = `${rawVersion}+${prerelease.replace('nightly', 'nightly.')}`; + } + else { + range = semver.validRange(`^${rawVersion}`); + } + } + if (range) { + versions = versions.sort((a, b) => { + if (semver.gt(a, b)) { + return 1; + } + return -1; + }); + for (let i = versions.length - 1; i >= 0; i--) { + const potential = versions[i]; + const satisfied = semver.satisfies(potential.replace('-nightly', '+nightly.'), range); + if (satisfied) { + version = potential; + break; + } + } + } + if (version) { + core.debug(`matched: ${version}`); + } + else { + core.debug('match not found'); + } + return version; +} // TODO - should we just export this from @actions/tool-cache? Lifted directly from there function evaluateVersions(versions, versionSpec) { let version = ''; core.debug(`evaluating ${versions.length} versions`); - core.debug(`version 1 is ${versions[0]}`); - core.debug(`version spec is ${versionSpec}`); - versionSpec = - versionSpec.includes('nightly') && !semver.valid(versionSpec.split('-')[0]) - ? versionSpec.split('-')[0] - : versionSpec; + if (versionSpec.includes('nightly')) { + return evaluateNightlyVersions(versions, versionSpec); + } versions = versions.sort((a, b) => { if (semver.gt(a, b)) { return 1; @@ -73428,7 +73463,7 @@ function evaluateVersions(versions, versionSpec) { }); for (let i = versions.length - 1; i >= 0; i--) { const potential = versions[i]; - const satisfied = semver.satisfies(potential.replace('-nightly', '+nightly.'), versionSpec.replace('-nightly', '+nightly')); + const satisfied = semver.satisfies(potential, versionSpec); if (satisfied) { version = potential; break; @@ -73447,7 +73482,7 @@ function getNodejsDistUrl(version) { if (!prerelease || !prerelease.length) { return 'https://nodejs.org/dist'; } - else if (prerelease[0] === 'nightly') { + else if (version.includes('nightly')) { return 'https://nodejs.org/download/nightly'; } else { @@ -73642,7 +73677,7 @@ function run() { // Version is optional. If supplied, install / use from the tool cache // If not supplied then task is still used to setup proxy, auth, etc... // - let version = resolveVersionInput(); + const version = resolveVersionInput(); let arch = core.getInput('architecture'); const cache = core.getInput('cache'); // if architecture supplied but node-version is not @@ -73654,9 +73689,9 @@ function run() { arch = os.arch(); } if (version) { - let token = core.getInput('token'); - let auth = !token || cache_utils_1.isGhes() ? undefined : `token ${token}`; - let stable = (core.getInput('stable') || 'true').toUpperCase() === 'TRUE'; + const token = core.getInput('token'); + const auth = !token || cache_utils_1.isGhes() ? undefined : `token ${token}`; + const stable = (core.getInput('stable') || 'true').toUpperCase() === 'TRUE'; const checkLatest = (core.getInput('check-latest') || 'false').toUpperCase() === 'TRUE'; yield installer.getNode(version, stable, checkLatest, auth, arch); } diff --git a/src/installer.ts b/src/installer.ts index 32281996..b9519995 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -347,16 +347,61 @@ async function resolveVersionFromManifest( } } +function evaluateNightlyVersions( + versions: string[], + versionSpec: string +): string { + let version = ''; + let range: string | null | undefined; + const [raw, prerelease] = versionSpec.split('-'); + const isValidVersion = semver.valid(raw); + const rawVersion = isValidVersion ? raw : semver.coerce(raw); + if (rawVersion) { + if (prerelease !== 'nightly') { + range = `${rawVersion}+${prerelease.replace('nightly', 'nightly.')}`; + } else { + range = semver.validRange(`^${rawVersion}`); + } + } + + if (range) { + versions = versions.sort((a, b) => { + if (semver.gt(a, b)) { + return 1; + } + return -1; + }); + for (let i = versions.length - 1; i >= 0; i--) { + const potential: string = versions[i]; + const satisfied: boolean = semver.satisfies( + potential.replace('-nightly', '+nightly.'), + range + ); + if (satisfied) { + version = potential; + break; + } + } + } + + if (version) { + core.debug(`matched: ${version}`); + } else { + core.debug('match not found'); + } + + return version; +} + // TODO - should we just export this from @actions/tool-cache? Lifted directly from there function evaluateVersions(versions: string[], versionSpec: string): string { let version = ''; core.debug(`evaluating ${versions.length} versions`); - core.debug(`version 1 is ${versions[0]}`); - core.debug(`version spec is ${versionSpec}`); - versionSpec = - versionSpec.includes('nightly') && !semver.valid(versionSpec.split('-')[0]) - ? versionSpec.split('-')[0] - : versionSpec; + + if(versionSpec.includes('nightly')) { + return evaluateNightlyVersions(versions, versionSpec); + } + versions = versions.sort((a, b) => { if (semver.gt(a, b)) { return 1; @@ -365,10 +410,7 @@ function evaluateVersions(versions: string[], versionSpec: string): string { }); for (let i = versions.length - 1; i >= 0; i--) { const potential: string = versions[i]; - const satisfied: boolean = semver.satisfies( - potential.replace('-nightly', '+nightly.'), - versionSpec.replace('-nightly', '+nightly') - ); + const satisfied: boolean = semver.satisfies(potential, versionSpec); if (satisfied) { version = potential; break; @@ -384,11 +426,11 @@ function evaluateVersions(versions: string[], versionSpec: string): string { return version; } -function getNodejsDistUrl(version: string | semver.SemVer) { +function getNodejsDistUrl(version: string) { const prerelease = semver.prerelease(version); if (!prerelease || !prerelease.length) { return 'https://nodejs.org/dist'; - } else if (prerelease[0] === 'nightly') { + } else if (version.includes('nightly')) { return 'https://nodejs.org/download/nightly'; } else { return 'https://nodejs.org/download/rc'; @@ -439,7 +481,7 @@ async function queryDistForMatch( }); // get the latest version that matches the version spec - let version: string = evaluateVersions(versions, versionSpec); + let version = evaluateVersions(versions, versionSpec); return version; } diff --git a/src/main.ts b/src/main.ts index 6a980a0d..bec19354 100644 --- a/src/main.ts +++ b/src/main.ts @@ -14,7 +14,7 @@ export async function run() { // Version is optional. If supplied, install / use from the tool cache // If not supplied then task is still used to setup proxy, auth, etc... // - let version = resolveVersionInput(); + const version = resolveVersionInput(); let arch = core.getInput('architecture'); const cache = core.getInput('cache'); @@ -32,9 +32,9 @@ export async function run() { } if (version) { - let token = core.getInput('token'); - let auth = !token || isGhes() ? undefined : `token ${token}`; - let stable = (core.getInput('stable') || 'true').toUpperCase() === 'TRUE'; + const token = core.getInput('token'); + const auth = !token || isGhes() ? undefined : `token ${token}`; + const stable = (core.getInput('stable') || 'true').toUpperCase() === 'TRUE'; const checkLatest = (core.getInput('check-latest') || 'false').toUpperCase() === 'TRUE'; await installer.getNode(version, stable, checkLatest, auth, arch); From e7c919e11cf3381d328e548ec869c36e623150b2 Mon Sep 17 00:00:00 2001 From: Dmitry Shibanov Date: Wed, 19 Oct 2022 14:19:12 +0200 Subject: [PATCH 10/14] fix if check --- dist/setup/index.js | 8 ++++---- src/installer.ts | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/dist/setup/index.js b/dist/setup/index.js index 18342fae..e7090563 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -73479,12 +73479,12 @@ function evaluateVersions(versions, versionSpec) { } function getNodejsDistUrl(version) { const prerelease = semver.prerelease(version); - if (!prerelease || !prerelease.length) { - return 'https://nodejs.org/dist'; - } - else if (version.includes('nightly')) { + if (version.includes('nightly')) { return 'https://nodejs.org/download/nightly'; } + else if (!prerelease) { + return 'https://nodejs.org/dist'; + } else { return 'https://nodejs.org/download/rc'; } diff --git a/src/installer.ts b/src/installer.ts index b9519995..c727a6dc 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -428,10 +428,10 @@ function evaluateVersions(versions: string[], versionSpec: string): string { function getNodejsDistUrl(version: string) { const prerelease = semver.prerelease(version); - if (!prerelease || !prerelease.length) { - return 'https://nodejs.org/dist'; - } else if (version.includes('nightly')) { + if (version.includes('nightly')) { return 'https://nodejs.org/download/nightly'; + } else if (!prerelease) { + return 'https://nodejs.org/dist'; } else { return 'https://nodejs.org/download/rc'; } From 60732b496693486fa36434b6259b4040052e6e7d Mon Sep 17 00:00:00 2001 From: Dmitry Shibanov Date: Wed, 19 Oct 2022 15:26:27 +0200 Subject: [PATCH 11/14] fix toolcache --- dist/setup/index.js | 13 ++++++++++++- src/installer.ts | 22 ++++++++++++++++++++-- src/main.ts | 3 ++- 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/dist/setup/index.js b/dist/setup/index.js index e7090563..43838707 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -73226,7 +73226,13 @@ function getNode(versionSpec, stable, checkLatest, auth, arch = os.arch()) { // check cache core.debug('check toolcache'); let toolPath; - toolPath = tc.find('node', versionSpec, osArch); + if (isNightly) { + const nightlyVersion = findNightlyVersionInHostedToolcache(versionSpec, osArch); + toolPath = tc.find('node', nightlyVersion, osArch); + } + else { + toolPath = tc.find('node', versionSpec, osArch); + } // If not found in cache, download if (toolPath) { core.info(`Found in cache @ ${toolPath}`); @@ -73322,6 +73328,11 @@ function getNode(versionSpec, stable, checkLatest, auth, arch = os.arch()) { }); } exports.getNode = getNode; +function findNightlyVersionInHostedToolcache(versionsSpec, osArch) { + const foundAllVersions = tc.findAllVersions('node', osArch); + const version = evaluateVersions(foundAllVersions, versionsSpec); + return version; +} function isLtsAlias(versionSpec) { return versionSpec.startsWith('lts/'); } diff --git a/src/installer.ts b/src/installer.ts index c727a6dc..efa081a7 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -83,7 +83,15 @@ export async function getNode( // check cache core.debug('check toolcache'); let toolPath: string; - toolPath = tc.find('node', versionSpec, osArch); + if (isNightly) { + const nightlyVersion = findNightlyVersionInHostedToolcache( + versionSpec, + osArch + ); + toolPath = tc.find('node', nightlyVersion, osArch); + } else { + toolPath = tc.find('node', versionSpec, osArch); + } // If not found in cache, download if (toolPath) { @@ -207,6 +215,16 @@ export async function getNode( core.addPath(toolPath); } +function findNightlyVersionInHostedToolcache( + versionsSpec: string, + osArch: string +) { + const foundAllVersions = tc.findAllVersions('node', osArch); + const version = evaluateVersions(foundAllVersions, versionsSpec); + + return version; +} + function isLtsAlias(versionSpec: string): boolean { return versionSpec.startsWith('lts/'); } @@ -398,7 +416,7 @@ function evaluateVersions(versions: string[], versionSpec: string): string { let version = ''; core.debug(`evaluating ${versions.length} versions`); - if(versionSpec.includes('nightly')) { + if (versionSpec.includes('nightly')) { return evaluateNightlyVersions(versions, versionSpec); } diff --git a/src/main.ts b/src/main.ts index bec19354..45ef02e2 100644 --- a/src/main.ts +++ b/src/main.ts @@ -34,7 +34,8 @@ export async function run() { if (version) { const token = core.getInput('token'); const auth = !token || isGhes() ? undefined : `token ${token}`; - const stable = (core.getInput('stable') || 'true').toUpperCase() === 'TRUE'; + const stable = + (core.getInput('stable') || 'true').toUpperCase() === 'TRUE'; const checkLatest = (core.getInput('check-latest') || 'false').toUpperCase() === 'TRUE'; await installer.getNode(version, stable, checkLatest, auth, arch); From 817ef3e405094cab85aee4337b2bf97063139912 Mon Sep 17 00:00:00 2001 From: Dmitry Shibanov Date: Wed, 19 Oct 2022 15:35:46 +0200 Subject: [PATCH 12/14] add debug line --- dist/setup/index.js | 1 + src/installer.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/dist/setup/index.js b/dist/setup/index.js index 43838707..8d35353f 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -73330,6 +73330,7 @@ function getNode(versionSpec, stable, checkLatest, auth, arch = os.arch()) { exports.getNode = getNode; function findNightlyVersionInHostedToolcache(versionsSpec, osArch) { const foundAllVersions = tc.findAllVersions('node', osArch); + core.debug(foundAllVersions.join('\n')); const version = evaluateVersions(foundAllVersions, versionsSpec); return version; } diff --git a/src/installer.ts b/src/installer.ts index efa081a7..dab8900f 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -220,6 +220,7 @@ function findNightlyVersionInHostedToolcache( osArch: string ) { const foundAllVersions = tc.findAllVersions('node', osArch); + core.debug(foundAllVersions.join('\n')); const version = evaluateVersions(foundAllVersions, versionsSpec); return version; From 3b39c278a3d95d8819eacd125b8751c72f3614fa Mon Sep 17 00:00:00 2001 From: Dmitry Shibanov Date: Wed, 19 Oct 2022 15:38:25 +0200 Subject: [PATCH 13/14] fix toolcache --- dist/setup/index.js | 2 +- src/installer.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dist/setup/index.js b/dist/setup/index.js index 8d35353f..61e4bb61 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -73228,7 +73228,7 @@ function getNode(versionSpec, stable, checkLatest, auth, arch = os.arch()) { let toolPath; if (isNightly) { const nightlyVersion = findNightlyVersionInHostedToolcache(versionSpec, osArch); - toolPath = tc.find('node', nightlyVersion, osArch); + toolPath = nightlyVersion && tc.find('node', nightlyVersion, osArch); } else { toolPath = tc.find('node', versionSpec, osArch); diff --git a/src/installer.ts b/src/installer.ts index dab8900f..776ca6d4 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -88,7 +88,7 @@ export async function getNode( versionSpec, osArch ); - toolPath = tc.find('node', nightlyVersion, osArch); + toolPath = nightlyVersion && tc.find('node', nightlyVersion, osArch); } else { toolPath = tc.find('node', versionSpec, osArch); } From 29be23260c3a613c5f96bd07ee37a4202d31ea7a Mon Sep 17 00:00:00 2001 From: Dmitry Shibanov Date: Wed, 19 Oct 2022 16:01:26 +0200 Subject: [PATCH 14/14] add core debug --- dist/setup/index.js | 1 + src/installer.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/dist/setup/index.js b/dist/setup/index.js index 61e4bb61..ce1cc756 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -73464,6 +73464,7 @@ function evaluateNightlyVersions(versions, versionSpec) { function evaluateVersions(versions, versionSpec) { let version = ''; core.debug(`evaluating ${versions.length} versions`); + core.debug(versions[1]); if (versionSpec.includes('nightly')) { return evaluateNightlyVersions(versions, versionSpec); } diff --git a/src/installer.ts b/src/installer.ts index 776ca6d4..9d7e017f 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -416,6 +416,7 @@ function evaluateNightlyVersions( function evaluateVersions(versions: string[], versionSpec: string): string { let version = ''; core.debug(`evaluating ${versions.length} versions`); + core.debug(versions[1]) if (versionSpec.includes('nightly')) { return evaluateNightlyVersions(versions, versionSpec);