From 06981c41e35bc124ffa90eb478be66162f9eca3f Mon Sep 17 00:00:00 2001 From: Dmitry Shibanov Date: Wed, 19 Oct 2022 16:36:26 +0200 Subject: [PATCH 1/9] initial logic --- .github/workflows/versions.yml | 20 ++++++ __tests__/authutil.test.ts | 2 +- __tests__/installer.test.ts | 5 +- dist/setup/index.js | 106 ++++++++++++++++++++++++----- src/installer.ts | 117 +++++++++++++++++++++++++++++---- src/main.ts | 11 ++-- 6 files changed, 224 insertions(+), 37 deletions(-) diff --git a/.github/workflows/versions.yml b/.github/workflows/versions.yml index 9a138ebba..4b539a689 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 "$majorVersion" + shell: bash + manifest: runs-on: ${{ matrix.os }} strategy: diff --git a/__tests__/authutil.test.ts b/__tests__/authutil.test.ts index 1ec4e1e18..594c6a138 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 28d77e7c6..d359f7ab1 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 0daaa2f23..0be3cc249 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,11 +73204,15 @@ 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 (checkLatest) { + if (isNightly && checkLatest) { + nodeVersions = yield getVersionsFromDist(versionSpec); + versionSpec = yield queryDistForMatch(versionSpec, arch, nodeVersions); + } + if (checkLatest && !isNightly) { core.info('Attempt to resolve the latest version from manifest...'); const resolvedVersion = yield resolveVersionFromManifest(versionSpec, stable, auth, osArch, manifest); if (resolvedVersion) { @@ -73220,7 +73225,13 @@ function getNode(versionSpec, stable, checkLatest, auth, arch = os.arch()) { } // check cache let toolPath; - toolPath = tc.find('node', versionSpec, osArch); + if (isNightly) { + const nightlyVersion = findNightlyVersionInHostedToolcache(versionSpec, osArch); + toolPath = nightlyVersion && 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}`); @@ -73316,6 +73327,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/'); } @@ -73382,7 +73398,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); + const url = `${initialUrl}/v${version}/${urlFileName}`; return { downloadUrl: url, resolvedVersion: version, @@ -73403,10 +73420,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`); + if (versionSpec.includes('nightly')) { + return evaluateNightlyVersions(versions, versionSpec); + } versions = versions.sort((a, b) => { if (semver.gt(a, b)) { return 1; @@ -73429,6 +73487,18 @@ function evaluateVersions(versions, versionSpec) { } return version; } +function getNodejsDistUrl(version) { + const prerelease = semver.prerelease(version); + 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'; + } +} function queryDistForMatch(versionSpec, arch = os.arch(), nodeVersions) { return __awaiter(this, void 0, void 0, function* () { let osPlat = os.platform(); @@ -73450,7 +73520,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 +73538,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 +73565,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 +73577,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 +73587,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); @@ -73607,7 +73679,7 @@ const auth = __importStar(__nccwpck_require__(7573)); const path = __importStar(__nccwpck_require__(1017)); const cache_restore_1 = __nccwpck_require__(9517); const cache_utils_1 = __nccwpck_require__(1678); -const os = __nccwpck_require__(2037); +const os_1 = __importDefault(__nccwpck_require__(2037)); function run() { return __awaiter(this, void 0, void 0, function* () { try { @@ -73615,7 +73687,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 @@ -73624,12 +73696,12 @@ function run() { core.warning('`architecture` is provided but `node-version` is missing. In this configuration, the version/architecture of Node will not be changed. To fix this, provide `architecture` in combination with `node-version`'); } if (!arch) { - arch = os.arch(); + arch = os_1.default.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 83a43d859..53ace18e9 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -11,6 +11,8 @@ import fs = require('fs'); // // Node versions interface // see https://nodejs.org/dist/index.json +// for nightly https://nodejs.org/download/nightly/index.json +// for rc https://nodejs.org/download/rc/index.json // export interface INodeVersion { version: string; @@ -38,6 +40,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,12 +54,17 @@ 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 (checkLatest) { + if (isNightly && checkLatest) { + nodeVersions = await getVersionsFromDist(versionSpec); + versionSpec = await queryDistForMatch(versionSpec, arch, nodeVersions); + } + + if (checkLatest && !isNightly) { core.info('Attempt to resolve the latest version from manifest...'); const resolvedVersion = await resolveVersionFromManifest( versionSpec, @@ -75,7 +83,15 @@ export async function getNode( // check cache let toolPath: string; - toolPath = tc.find('node', versionSpec, osArch); + if (isNightly) { + const nightlyVersion = findNightlyVersionInHostedToolcache( + versionSpec, + osArch + ); + toolPath = nightlyVersion && tc.find('node', nightlyVersion, osArch); + } else { + toolPath = tc.find('node', versionSpec, osArch); + } // If not found in cache, download if (toolPath) { @@ -199,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/'); } @@ -306,7 +332,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); + const url = `${initialUrl}/v${version}/${urlFileName}`; return { downloadUrl: url, @@ -338,10 +365,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`); + + if (versionSpec.includes('nightly')) { + return evaluateNightlyVersions(versions, versionSpec); + } + versions = versions.sort((a, b) => { if (semver.gt(a, b)) { return 1; @@ -366,6 +444,17 @@ function evaluateVersions(versions: string[], versionSpec: string): string { return version; } +function getNodejsDistUrl(version: string) { + const prerelease = semver.prerelease(version); + 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'; + } +} + async function queryDistForMatch( versionSpec: string, arch: string = os.arch(), @@ -392,7 +481,7 @@ async function queryDistForMatch( if (!nodeVersions) { core.debug('No dist manifest cached'); - nodeVersions = await getVersionsFromDist(); + nodeVersions = await getVersionsFromDist(versionSpec); } let versions: string[] = []; @@ -410,12 +499,15 @@ 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; } -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 +532,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 +546,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 +557,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')); diff --git a/src/main.ts b/src/main.ts index 6a980a0d6..3faf67c78 100644 --- a/src/main.ts +++ b/src/main.ts @@ -6,7 +6,7 @@ import * as auth from './authutil'; import * as path from 'path'; import {restoreCache} from './cache-restore'; import {isGhes, isCacheFeatureAvailable} from './cache-utils'; -import os = require('os'); +import os from 'os'; export async function run() { try { @@ -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,10 @@ 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 38d01b1022e0b204a41f30182494eec9545fef84 Mon Sep 17 00:00:00 2001 From: Dmitry Shibanov Date: Thu, 20 Oct 2022 11:52:20 +0200 Subject: [PATCH 2/9] add unit tests --- .github/workflows/versions.yml | 20 ++ __tests__/data/node-nightly-index.json | 35 +++ __tests__/data/node-rc-index.json | 28 ++ __tests__/installer.test.ts | 389 ++++++++++++++++++++++++- dist/setup/index.js | 7 +- src/installer.ts | 11 +- 6 files changed, 479 insertions(+), 11 deletions(-) create mode 100644 __tests__/data/node-nightly-index.json create mode 100644 __tests__/data/node-rc-index.json diff --git a/.github/workflows/versions.yml b/.github/workflows/versions.yml index 4b539a689..ce43847ae 100644 --- a/.github/workflows/versions.yml +++ b/.github/workflows/versions.yml @@ -71,6 +71,26 @@ jobs: __tests__/verify-node.sh "$majorVersion" shell: bash + rc-syntax: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, windows-latest, macos-latest] + node-version: [16.0.0-rc.1, 18.0.0-rc.2, 19.0.0-rc.0] + steps: + - uses: actions/checkout@v3 + - name: Setup Node + uses: ./ + with: + node-version: ${{ matrix.node-version }} + - name: Verify node and npm + run: | + rcVersion="${{ matrix.node-version }}" + majorVersion=$(echo $rcVersion | cut -d- -f1) + __tests__/verify-node.sh "$majorVersion" + shell: bash + manifest: runs-on: ${{ matrix.os }} strategy: diff --git a/__tests__/data/node-nightly-index.json b/__tests__/data/node-nightly-index.json new file mode 100644 index 000000000..dd0e7fc05 --- /dev/null +++ b/__tests__/data/node-nightly-index.json @@ -0,0 +1,35 @@ +[ + {"version":"v20.0.0-nightly2022101987cdf7d412","date":"2022-10-19","files":["aix-ppc64","headers","linux-arm64","linux-armv7l","linux-ppc64le","linux-s390x","linux-x64","osx-arm64-tar","osx-x64-pkg","osx-x64-tar","src","win-x64-7z","win-x64-exe","win-x64-msi","win-x64-zip","win-x86-7z","win-x86-exe","win-x86-msi","win-x86-zip"],"npm":"8.19.2","v8":"10.7.193.16","uv":"1.43.0","zlib":"1.2.11","openssl":"3.0.5+quic","modules":"111","lts":false,"security":false}, + {"version":"v19.0.0-nightly202210182672219b78","date":"2022-10-18","files":["aix-ppc64","headers","linux-arm64","linux-armv7l","linux-ppc64le","linux-s390x","linux-x64","osx-arm64-tar","osx-x64-pkg","osx-x64-tar","src","win-x64-7z","win-x64-exe","win-x64-msi","win-x64-zip","win-x86-7z","win-x86-exe","win-x86-msi","win-x86-zip"],"npm":"8.19.2","v8":"10.7.193.13","uv":"1.43.0","zlib":"1.2.11","openssl":"3.0.5+quic","modules":"111","lts":false,"security":false}, + + + {"version":"v19.0.0-nightly202204201fe5d56403","date":"2022-04-20","files":["aix-ppc64","headers","linux-arm64","linux-armv7l","linux-ppc64le","linux-s390x","linux-x64","osx-arm64-tar","osx-x64-tar","src","win-x64-7z","win-x64-exe","win-x64-msi","win-x64-zip"],"npm":"8.7.0","v8":"10.1.124.8","uv":"1.43.0","zlib":"1.2.11","openssl":"3.0.2+quic","modules":"108","lts":false,"security":false}, + {"version":"v18.0.0-nightly20220419bde889bd4e","date":"2022-04-19","files":["aix-ppc64","headers","linux-arm64","linux-armv7l","linux-ppc64le","linux-s390x","linux-x64","osx-arm64-tar","osx-x64-pkg","osx-x64-tar","src","win-x64-7z","win-x64-exe","win-x64-msi","win-x64-zip"],"npm":"8.7.0","v8":"10.1.124.8","uv":"1.43.0","zlib":"1.2.11","openssl":"3.0.2+quic","modules":"108","lts":false,"security":false}, + {"version":"v18.0.0-nightly202204180699150267","date":"2022-04-18","files":["aix-ppc64","headers","linux-arm64","linux-armv7l","linux-ppc64le","linux-s390x","linux-x64","osx-arm64-tar","osx-x64-pkg","osx-x64-tar","src","win-x64-7z","win-x64-exe","win-x64-msi","win-x64-zip"],"npm":"8.7.0","v8":"10.1.124.8","uv":"1.43.0","zlib":"1.2.11","openssl":"3.0.2+quic","modules":"108","lts":false,"security":false}, + + {"version":"v18.0.0-nightly202110204cb3e06ed8","date":"2021-10-20","files":["aix-ppc64","headers","linux-arm64","linux-armv7l","linux-ppc64le","linux-s390x","linux-x64","osx-arm64-tar","osx-x64-pkg","osx-x64-tar","src","win-x64-7z","win-x64-exe","win-x64-msi","win-x64-zip","win-x86-7z","win-x86-exe","win-x86-msi","win-x86-zip"],"npm":"8.1.0","v8":"9.5.172.21","uv":"1.42.0","zlib":"1.2.11","openssl":"3.0.0+quic","modules":"102","lts":false,"security":false}, + {"version":"v17.5.0-nightly20220209e43808936a","date":"2022-02-09","files":["aix-ppc64","headers","linux-arm64","linux-armv7l","linux-ppc64le","linux-s390x","linux-x64","osx-arm64-tar","osx-x64-pkg","osx-x64-tar","src","win-x64-7z","win-x64-exe","win-x64-msi","win-x64-zip","win-x86-7z","win-x86-exe","win-x86-msi","win-x86-zip"],"npm":"8.4.1","v8":"9.6.180.15","uv":"1.43.0","zlib":"1.2.11","openssl":"3.0.1+quic","modules":"102","lts":false,"security":false}, + {"version":"v17.0.0-nightly202110193f11666dc7","date":"2021-10-19","files":["aix-ppc64","headers","linux-arm64","linux-armv7l","linux-ppc64le","linux-s390x","linux-x64","osx-arm64-tar","osx-x64-pkg","osx-x64-tar","src","win-x64-7z","win-x64-exe","win-x64-msi","win-x64-zip","win-x86-7z","win-x86-exe","win-x86-msi","win-x86-zip"],"npm":"8.1.0","v8":"9.5.172.21","uv":"1.42.0","zlib":"1.2.11","openssl":"3.0.0+quic","modules":"102","lts":false,"security":false}, + {"version":"v17.0.0-nightly20211018c0a70203de","date":"2021-10-18","files":["aix-ppc64","headers","linux-arm64","linux-armv7l","linux-ppc64le","linux-s390x","linux-x64","osx-arm64-tar","osx-x64-pkg","osx-x64-tar","src","win-x64-7z","win-x64-exe","win-x64-msi","win-x64-zip","win-x86-7z","win-x86-exe","win-x86-msi","win-x86-zip"],"npm":"8.0.0","v8":"9.5.172.21","uv":"1.42.0","zlib":"1.2.11","openssl":"3.0.0+quic","modules":"102","lts":false,"security":false}, + + {"version":"v16.0.0-nightly20210420a0261d231c","date":"2021-04-20","files":["aix-ppc64","headers","linux-arm64","linux-armv7l","linux-ppc64le","linux-s390x","linux-x64","osx-arm64-tar","osx-x64-pkg","osx-x64-tar","src","win-x64-7z","win-x64-exe","win-x64-msi","win-x64-zip","win-x86-7z","win-x86-exe","win-x86-msi","win-x86-zip"],"npm":"7.10.0","v8":"9.0.257.17","uv":"1.41.0","zlib":"1.2.11","openssl":"1.1.1k+quic","modules":"93","lts":false,"security":false}, + {"version":"v16.0.0-nightly20210417bc31dc0e0f","date":"2021-04-17","files":["aix-ppc64","headers","linux-arm64","linux-ppc64le","linux-s390x","linux-x64","osx-arm64-tar","osx-x64-pkg","osx-x64-tar","src","win-x64-7z","win-x64-exe","win-x64-msi","win-x64-zip","win-x86-7z","win-x86-exe","win-x86-msi","win-x86-zip"],"npm":"7.10.0","v8":"9.0.257.17","uv":"1.41.0","zlib":"1.2.11","openssl":"1.1.1k+quic","modules":"93","lts":false,"security":false}, + {"version":"v16.0.0-nightly20210416d3162da8dd","date":"2021-04-16","files":["aix-ppc64","headers","linux-arm64","linux-ppc64le","linux-s390x","linux-x64","osx-arm64-tar","osx-x64-pkg","osx-x64-tar","src","win-x64-7z","win-x64-exe","win-x64-msi","win-x64-zip","win-x86-7z","win-x86-exe","win-x86-msi","win-x86-zip"],"npm":"7.9.0","v8":"9.0.257.17","uv":"1.41.0","zlib":"1.2.11","openssl":"1.1.1k+quic","modules":"93","lts":false,"security":false}, + {"version":"v16.0.0-nightly20210415c3a5e15ebe","date":"2021-04-15","files":["aix-ppc64","headers","linux-arm64","linux-ppc64le","linux-s390x","linux-x64","osx-arm64-tar","osx-x64-pkg","osx-x64-tar","src","win-x64-7z","win-x64-exe","win-x64-msi","win-x64-zip","win-x86-7z","win-x86-exe","win-x86-msi","win-x86-zip"],"npm":"7.9.0","v8":"9.0.257.17","uv":"1.41.0","zlib":"1.2.11","openssl":"1.1.1k+quic","modules":"93","lts":false,"security":false}, + + + {"version":"v15.0.0-nightly2020102011f1ad939f","date":"2020-10-20","files":["aix-ppc64","headers","linux-arm64","linux-armv7l","linux-ppc64le","linux-s390x","linux-x64","osx-x64-pkg","osx-x64-tar","src","win-x64-7z","win-x64-exe","win-x64-msi","win-x64-zip","win-x86-7z","win-x86-exe","win-x86-msi","win-x86-zip"],"npm":"7.0.2","v8":"8.6.395.16","uv":"1.40.0","zlib":"1.2.11","openssl":"1.1.1g","modules":"88","lts":false,"security":false}, + {"version":"v15.0.0-nightly20201019c55f661551","date":"2020-10-19","files":["aix-ppc64","headers","linux-arm64","linux-armv7l","linux-ppc64le","linux-s390x","linux-x64","osx-x64-pkg","osx-x64-tar","src","win-x64-7z","win-x64-exe","win-x64-msi","win-x64-zip","win-x86-7z","win-x86-exe","win-x86-msi","win-x86-zip"],"npm":"7.0.2","v8":"8.6.395.16","uv":"1.40.0","zlib":"1.2.11","openssl":"1.1.1g","modules":"88","lts":false,"security":false}, + {"version":"v14.0.0-nightly20200421c3554307c6","date":"2020-04-21","files":["aix-ppc64","headers","linux-arm64","linux-armv7l","linux-ppc64le","linux-s390x","linux-x64","osx-x64-pkg","osx-x64-tar","src","win-x64-7z","win-x64-exe","win-x64-msi","win-x64-zip","win-x86-7z","win-x86-exe","win-x86-msi","win-x86-zip"],"npm":"6.14.4","v8":"8.1.307.30","uv":"1.37.0","zlib":"1.2.11","openssl":"1.1.1f","modules":"83","lts":false,"security":false}, + {"version":"v14.0.0-nightly202004204af0598134","date":"2020-04-20","files":["aix-ppc64","headers","linux-arm64","linux-armv7l","linux-ppc64le","linux-s390x","linux-x64","osx-x64-pkg","osx-x64-tar","src","win-x64-7z","win-x64-exe","win-x64-msi","win-x64-zip","win-x86-7z","win-x86-exe","win-x86-msi","win-x86-zip"],"npm":"6.14.4","v8":"8.1.307.26","uv":"1.37.0","zlib":"1.2.11","openssl":"1.1.1f","modules":"83","lts":false,"security":false}, + + {"version":"v13.13.1-nightly20200415947ddec091","date":"2020-04-15","files":["aix-ppc64","headers","linux-arm64","linux-armv7l","linux-ppc64le","linux-s390x","linux-x64","osx-x64-pkg","osx-x64-tar","src","sunos-x64","win-x64-7z","win-x64-exe","win-x64-msi","win-x64-zip","win-x86-7z","win-x86-exe","win-x86-msi","win-x86-zip"],"npm":"6.14.4","v8":"7.9.317.25","uv":"1.35.0","zlib":"1.2.11","openssl":"1.1.1f","modules":"79","lts":false,"security":false}, + {"version":"v13.11.1-nightly2020032628e298f219","date":"2020-03-26","files":["aix-ppc64","headers","linux-arm64","linux-armv7l","linux-ppc64le","linux-s390x","linux-x64","osx-x64-pkg","osx-x64-tar","src","sunos-x64","win-x64-7z","win-x64-exe","win-x64-msi","win-x64-zip","win-x86-7z","win-x86-exe","win-x86-msi","win-x86-zip"],"npm":"6.14.3","v8":"7.9.317.25","uv":"1.35.0","zlib":"1.2.11","openssl":"1.1.1e","modules":"79","lts":false,"security":false}, + + {"version":"v13.10.2-nightly202003056122620832","date":"2020-03-05","files":["aix-ppc64","headers","linux-arm64","linux-armv7l","linux-ppc64le","linux-s390x","linux-x64","osx-x64-pkg","osx-x64-tar","src","sunos-x64","win-x64-7z","win-x64-exe","win-x64-msi","win-x64-zip","win-x86-7z","win-x86-exe","win-x86-msi","win-x86-zip"],"npm":"6.13.7","v8":"7.9.317.25","uv":"1.34.2","zlib":"1.2.11","openssl":"1.1.1d","modules":"79","lts":false,"security":false}, + {"version":"v13.9.1-nightly202003041bca7b6c70","date":"2020-03-04","files":["aix-ppc64","headers","linux-arm64","linux-armv7l","linux-ppc64le","linux-s390x","linux-x64","osx-x64-pkg","osx-x64-tar","src","sunos-x64","win-x64-7z","win-x64-exe","win-x64-msi","win-x64-zip","win-x86-7z","win-x86-exe","win-x86-msi","win-x86-zip"],"npm":"6.13.7","v8":"7.9.317.25","uv":"1.34.2","zlib":"1.2.11","openssl":"1.1.1d","modules":"79","lts":false,"security":false}, + {"version":"v13.0.0-nightly201908175e3b4d6ed9","date":"2019-08-17","files":["aix-ppc64","headers","linux-arm64","linux-armv7l","linux-ppc64le","linux-s390x","linux-x64","osx-x64-pkg","osx-x64-tar","src","sunos-x64","win-x64-7z","win-x64-exe","win-x64-msi","win-x64-zip","win-x86-7z","win-x86-exe","win-x86-msi","win-x86-zip"],"npm":"6.10.2","v8":"7.6.303.28","uv":"1.31.0","zlib":"1.2.11","openssl":"1.1.1c","modules":"77","lts":false,"security":true}, + {"version":"v13.0.0-nightly2019081671b5ce5885","date":"2019-08-16","files":["aix-ppc64","headers","linux-arm64","linux-armv7l","linux-ppc64le","linux-s390x","linux-x64","osx-x64-pkg","osx-x64-tar","src","sunos-x64","win-x64-7z","win-x64-exe","win-x64-msi","win-x64-zip","win-x86-7z","win-x86-exe","win-x86-msi","win-x86-zip"],"npm":"6.10.2","v8":"7.6.303.28","uv":"1.31.0","zlib":"1.2.11","openssl":"1.1.1c","modules":"77","lts":false,"security":true}, + {"version":"v13.0.0-nightly2019072962a809fa54","date":"2019-07-29","files":["aix-ppc64","headers","linux-arm64","linux-armv7l","linux-ppc64le","linux-s390x","linux-x64","osx-x64-pkg","osx-x64-tar","src","sunos-x64","win-x64-7z","win-x64-exe","win-x64-msi","win-x64-zip","win-x86-7z","win-x86-exe","win-x86-msi","win-x86-zip"],"npm":"6.10.0","v8":"7.5.288.22","uv":"1.30.1","zlib":"1.2.11","openssl":"1.1.1c","modules":"74","lts":false,"security":false} + + ] \ No newline at end of file diff --git a/__tests__/data/node-rc-index.json b/__tests__/data/node-rc-index.json new file mode 100644 index 000000000..ba8ff9fec --- /dev/null +++ b/__tests__/data/node-rc-index.json @@ -0,0 +1,28 @@ +[ + {"version":"v19.0.0-rc.2","date":"2022-10-14","files":["aix-ppc64","headers","linux-arm64","linux-armv7l","linux-ppc64le","linux-s390x","linux-x64","osx-arm64-tar","osx-x64-pkg","osx-x64-tar","src","win-x64-7z","win-x64-exe","win-x64-msi","win-x64-zip","win-x86-7z","win-x86-exe","win-x86-msi","win-x86-zip"],"v8":"","uv":"","zlib":null,"openssl":null,"modules":null,"lts":false,"security":false}, + {"version":"v19.0.0-rc.1","date":"2022-10-04","files":["aix-ppc64","headers","linux-arm64","linux-armv7l","linux-ppc64le","linux-s390x","linux-x64","osx-arm64-tar","osx-x64-pkg","osx-x64-tar","src","win-x64-7z","win-x64-exe","win-x64-msi","win-x64-zip","win-x86-7z","win-x86-exe","win-x86-msi","win-x86-zip"],"v8":"","uv":"","zlib":null,"openssl":null,"modules":null,"lts":false,"security":false}, + {"version":"v17.0.0-rc.1","date":"2021-10-05","files":["aix-ppc64","headers","linux-arm64","linux-armv7l","linux-ppc64le","linux-s390x","linux-x64","osx-arm64-tar","osx-x64-pkg","osx-x64-tar","src","win-x64-7z","win-x64-exe","win-x64-msi","win-x64-zip","win-x86-7z","win-x86-exe","win-x86-msi","win-x86-zip"],"v8":"","uv":"","zlib":null,"openssl":null,"modules":null,"lts":false,"security":false}, + {"version":"v17.0.0-rc.0","date":"2021-09-21","files":["aix-ppc64","headers","linux-arm64","linux-armv7l","linux-ppc64le","linux-s390x","linux-x64","osx-arm64-tar","osx-x64-pkg","osx-x64-tar","src","win-x64-7z","win-x64-exe","win-x64-msi","win-x64-zip","win-x86-7z","win-x86-exe","win-x86-msi","win-x86-zip"],"v8":"","uv":"","zlib":null,"openssl":null,"modules":null,"lts":false,"security":false}, + {"version":"v16.17.0-rc.1","date":"2022-08-06","files":["aix-ppc64","headers","linux-arm64","linux-armv7l","linux-ppc64le","linux-s390x","linux-x64","osx-arm64-tar","osx-x64-pkg","osx-x64-tar","src","win-x64-7z","win-x64-exe","win-x64-msi","win-x64-zip","win-x86-7z","win-x86-exe","win-x86-msi","win-x86-zip"],"v8":"","uv":"","zlib":null,"openssl":null,"modules":null,"lts":false,"security":false}, + {"version":"v16.0.0-rc.2","date":"2021-04-07","files":["headers","linux-arm64","linux-ppc64le","linux-x64","osx-x64-pkg","osx-x64-tar","src"],"v8":"","uv":"","zlib":null,"openssl":null,"modules":null,"lts":false,"security":false}, + {"version":"v16.0.0-rc.1","date":"2021-03-30","files":["aix-ppc64","headers","linux-arm64","linux-armv7l","linux-ppc64le","linux-s390x","linux-x64","osx-x64-pkg","osx-x64-tar","src","win-x64-7z","win-x64-exe","win-x64-msi","win-x64-zip","win-x86-7z","win-x86-exe","win-x86-msi","win-x86-zip"],"v8":"","uv":"","zlib":null,"openssl":null,"modules":null,"lts":false,"security":false}, + {"version":"v16.0.0-rc.0","date":"2021-03-19","files":["aix-ppc64","headers","linux-arm64","linux-armv7l","linux-ppc64le","linux-s390x","linux-x64","osx-x64-pkg","osx-x64-tar","src","win-x64-7z","win-x64-exe","win-x64-msi","win-x64-zip","win-x86-7z","win-x86-exe","win-x86-msi","win-x86-zip"],"v8":"","uv":"","zlib":null,"openssl":null,"modules":null,"lts":false,"security":false}, + {"version":"v14.19.0-rc.0","date":"2022-01-25","files":["aix-ppc64","headers","linux-arm64","linux-armv7l","linux-ppc64le","linux-s390x","linux-x64","osx-x64-pkg","osx-x64-tar","src","win-x64-7z","win-x64-exe","win-x64-msi","win-x64-zip","win-x86-7z","win-x86-exe","win-x86-msi","win-x86-zip"],"v8":"","uv":"","zlib":null,"openssl":null,"modules":null,"lts":false,"security":false}, + {"version":"v14.18.0-rc.0","date":"2021-09-08","files":["aix-ppc64","headers","linux-arm64","linux-armv7l","linux-ppc64le","linux-s390x","linux-x64","osx-x64-pkg","osx-x64-tar","src","win-x64-7z","win-x64-exe","win-x64-msi","win-x64-zip","win-x86-7z","win-x86-exe","win-x86-msi","win-x86-zip"],"v8":"","uv":"","zlib":null,"openssl":null,"modules":null,"lts":false,"security":false}, + {"version":"v14.17.4-rc.0","date":"2021-07-20","files":["aix-ppc64","headers","linux-arm64","linux-armv7l","linux-ppc64le","linux-s390x","linux-x64","osx-x64-pkg","osx-x64-tar","src","win-x64-7z","win-x64-exe","win-x64-msi","win-x64-zip","win-x86-7z","win-x86-exe","win-x86-msi","win-x86-zip"],"v8":"","uv":"","zlib":null,"openssl":null,"modules":null,"lts":false,"security":false}, + {"version":"v14.17.1-rc.0","date":"2021-06-11","files":["aix-ppc64","headers","linux-arm64","linux-armv7l","linux-ppc64le","linux-s390x","linux-x64","osx-x64-pkg","osx-x64-tar","src","win-x64-7z","win-x64-exe","win-x64-msi","win-x64-zip","win-x86-7z","win-x86-exe","win-x86-msi","win-x86-zip"],"v8":"","uv":"","zlib":null,"openssl":null,"modules":null,"lts":false,"security":false}, + {"version":"v14.16.0-rc.0","date":"2021-02-22","files":["aix-ppc64","headers","linux-arm64","linux-armv7l","linux-ppc64le","linux-s390x","linux-x64","osx-x64-pkg","osx-x64-tar","src","win-x64-7z","win-x64-exe","win-x64-msi","win-x64-zip","win-x86-7z","win-x86-exe","win-x86-msi","win-x86-zip"],"v8":"","uv":"","zlib":null,"openssl":null,"modules":null,"lts":false,"security":false}, + {"version":"v14.15.5-rc.1","date":"2021-02-08","files":["aix-ppc64","headers","linux-arm64","linux-armv7l","linux-ppc64le","linux-s390x","linux-x64","osx-x64-pkg","osx-x64-tar","src","win-x64-7z","win-x64-exe","win-x64-msi","win-x64-zip","win-x86-7z","win-x86-exe","win-x86-msi","win-x86-zip"],"v8":"","uv":"","zlib":null,"openssl":null,"modules":null,"lts":false,"security":false}, + {"version":"v14.15.5-rc.0","date":"2021-01-27","files":["headers","linux-arm64","linux-armv7l","linux-ppc64le","linux-s390x","linux-x64","osx-x64-pkg","osx-x64-tar","src","win-x64-7z","win-x64-exe","win-x64-msi","win-x64-zip","win-x86-7z","win-x86-exe","win-x86-msi","win-x86-zip"],"v8":"","uv":"","zlib":null,"openssl":null,"modules":null,"lts":false,"security":false}, + {"version":"v14.15.2-rc.0","date":"2020-12-14","files":["headers","linux-arm64","linux-armv7l","linux-ppc64le","linux-s390x","linux-x64","osx-x64-tar","src","win-x64-7z","win-x64-exe","win-x64-msi","win-x64-zip","win-x86-7z","win-x86-exe","win-x86-msi","win-x86-zip"],"v8":"","uv":"","zlib":null,"openssl":null,"modules":null,"lts":false,"security":false}, + {"version":"v14.7.0-rc.1","date":"2020-07-29","files":["aix-ppc64","headers","linux-arm64","linux-armv7l","linux-ppc64le","linux-s390x","linux-x64","osx-x64-pkg","osx-x64-tar","src","win-x64-7z","win-x64-exe","win-x64-msi","win-x64-zip","win-x86-7z","win-x86-exe","win-x86-msi","win-x86-zip"],"v8":"","uv":"","zlib":null,"openssl":null,"modules":null,"lts":false,"security":false}, + {"version":"v13.11.0-rc.1","date":"2020-03-11","files":["headers","linux-arm64","linux-armv7l","linux-ppc64le","linux-x64","osx-x64-pkg","osx-x64-tar","src","sunos-x64","win-x64-7z","win-x64-exe","win-x64-msi","win-x64-zip","win-x86-7z","win-x86-exe","win-x86-msi","win-x86-zip"],"v8":"","uv":"","zlib":null,"openssl":null,"modules":null,"lts":false,"security":false}, + {"version":"v13.11.0-rc.0","date":"2020-03-10","files":["headers","linux-arm64","linux-armv7l","linux-ppc64le","linux-x64","osx-x64-pkg","src","sunos-x64","win-x64-7z","win-x64-exe","win-x64-msi","win-x64-zip"],"v8":"","uv":"","zlib":null,"openssl":null,"modules":null,"lts":false,"security":false}, + {"version":"v13.10.1-rc.0","date":"2020-03-04","files":["aix-ppc64","headers","linux-arm64","linux-armv7l","linux-ppc64le","linux-s390x","linux-x64","osx-x64-pkg","osx-x64-tar","src","sunos-x64","win-x64-7z","win-x64-exe","win-x64-msi","win-x64-zip"],"v8":"","uv":"","zlib":null,"openssl":null,"modules":null,"lts":false,"security":false}, + {"version":"v13.4.0-rc.0","date":"2019-12-13","files":["aix-ppc64","headers","linux-arm64","linux-armv7l","linux-ppc64le","linux-s390x","linux-x64","osx-x64-pkg","osx-x64-tar","src","sunos-x64","win-x64-7z","win-x64-exe","win-x64-msi","win-x64-zip","win-x86-7z","win-x86-exe","win-x86-msi","win-x86-zip"],"v8":"","uv":"","zlib":null,"openssl":null,"modules":null,"lts":false,"security":false}, + {"version":"v13.0.1-rc.0","date":"2019-10-23","files":["aix-ppc64","headers","linux-arm64","linux-armv7l","linux-ppc64le","linux-s390x","linux-x64","osx-x64-pkg","osx-x64-tar","src","sunos-x64","win-x64-7z","win-x64-exe","win-x64-msi","win-x64-zip","win-x86-7z","win-x86-exe","win-x86-msi","win-x86-zip"],"v8":"","uv":"","zlib":null,"openssl":null,"modules":null,"lts":false,"security":false}, + {"version":"v13.0.0-rc.3","date":"2019-10-21","files":["aix-ppc64","headers","linux-arm64","linux-armv7l","linux-ppc64le","linux-s390x","linux-x64","osx-x64-pkg","osx-x64-tar","src","sunos-x64","win-x64-7z","win-x64-exe","win-x64-msi","win-x64-zip","win-x86-7z","win-x86-exe","win-x86-msi","win-x86-zip"],"v8":"","uv":"","zlib":null,"openssl":null,"modules":null,"lts":false,"security":false}, + {"version":"v13.0.0-rc.2","date":"2019-10-15","files":["headers","linux-arm64","linux-armv7l","linux-ppc64le","linux-s390x","linux-x64","osx-x64-pkg","osx-x64-tar","src","sunos-x64","win-x64-7z","win-x64-exe","win-x64-msi","win-x64-zip","win-x86-7z","win-x86-exe","win-x86-msi","win-x86-zip"],"v8":"","uv":"","zlib":null,"openssl":null,"modules":null,"lts":false,"security":false}, + {"version":"v13.0.0-rc.1","date":"2019-10-01","files":["aix-ppc64","headers","linux-arm64","linux-armv7l","linux-ppc64le","linux-s390x","linux-x64","osx-x64-pkg","osx-x64-tar","src","sunos-x64","win-x64-7z","win-x64-exe","win-x64-msi","win-x64-zip","win-x86-7z","win-x86-exe","win-x86-msi","win-x86-zip"],"v8":"","uv":"","zlib":null,"openssl":null,"modules":null,"lts":false,"security":false}, + {"version":"v13.0.0-rc.0","date":"2019-09-25","files":["aix-ppc64","headers","linux-arm64","linux-armv7l","linux-ppc64le","linux-s390x","linux-x64","osx-x64-pkg","osx-x64-tar","src","sunos-x64","win-x64-7z","win-x64-exe","win-x64-msi","win-x64-zip","win-x86-7z","win-x86-exe","win-x86-msi","win-x86-zip"],"v8":"","uv":"","zlib":null,"openssl":null,"modules":null,"lts":false,"security":false} + ] \ No newline at end of file diff --git a/__tests__/installer.test.ts b/__tests__/installer.test.ts index d359f7ab1..7111265db 100644 --- a/__tests__/installer.test.ts +++ b/__tests__/installer.test.ts @@ -4,6 +4,7 @@ import * as tc from '@actions/tool-cache'; import * as exec from '@actions/exec'; import * as im from '../src/installer'; import * as cache from '@actions/cache'; +import * as httpm from '@actions/http-client'; import fs from 'fs'; import cp from 'child_process'; import osm from 'os'; @@ -12,8 +13,10 @@ import each from 'jest-each'; import * as main from '../src/main'; import * as auth from '../src/authutil'; -let nodeTestManifest = require('./data/versions-manifest.json'); -let nodeTestDist = require('./data/node-dist-index.json'); +const nodeTestManifest = require('./data/versions-manifest.json'); +const nodeTestDist = require('./data/node-dist-index.json'); +const nodeTestDistNightly = require('./data/node-nightly-index.json'); +const nodeTestDistRc = require('./data/node-rc-index.json'); describe('setup-node', () => { let inputs = {} as any; @@ -21,6 +24,7 @@ describe('setup-node', () => { let inSpy: jest.SpyInstance; let findSpy: jest.SpyInstance; + let findAllVersionsSpy: jest.SpyInstance; let cnSpy: jest.SpyInstance; let logSpy: jest.SpyInstance; let warningSpy: jest.SpyInstance; @@ -41,6 +45,7 @@ describe('setup-node', () => { let parseNodeVersionSpy: jest.SpyInstance; let isCacheActionAvailable: jest.SpyInstance; let getExecOutputSpy: jest.SpyInstance; + let getJsonSpy: jest.SpyInstance; beforeEach(() => { // @actions/core @@ -61,6 +66,7 @@ describe('setup-node', () => { // @actions/tool-cache findSpy = jest.spyOn(tc, 'find'); + findAllVersionsSpy = jest.spyOn(tc, 'findAllVersions'); dlSpy = jest.spyOn(tc, 'downloadTool'); exSpy = jest.spyOn(tc, 'extractTar'); cacheSpy = jest.spyOn(tc, 'cacheDir'); @@ -68,6 +74,9 @@ describe('setup-node', () => { getDistSpy = jest.spyOn(im, 'getVersionsFromDist'); parseNodeVersionSpy = jest.spyOn(im, 'parseNodeVersionFile'); + // http-client + getJsonSpy = jest.spyOn(httpm.HttpClient.prototype, 'getJson'); + // io whichSpy = jest.spyOn(io, 'which'); existsSpy = jest.spyOn(fs, 'existsSync'); @@ -84,7 +93,30 @@ describe('setup-node', () => { getManifestSpy.mockImplementation( () => nodeTestManifest ); - getDistSpy.mockImplementation(() => nodeTestDist); + + getDistSpy.mockImplementation(version => { + const initialUrl = im.getNodejsDistUrl(version); + if (initialUrl.endsWith('/rc')) { + return nodeTestDistRc; + } else if (initialUrl.endsWith('/nightly')) { + return nodeTestDistNightly; + } else { + return nodeTestDist; + } + }); + + getJsonSpy.mockImplementation(url => { + let res: any; + if (url.includes('/rc')) { + res = nodeTestDistRc; + } else if (url.includes('/nightly')) { + res = nodeTestDistNightly; + } else { + res = nodeTestDist; + } + + return {result: res}; + }); // writes cnSpy = jest.spyOn(process.stdout, 'write'); @@ -359,6 +391,18 @@ describe('setup-node', () => { }); it('acquires specified architecture of node', async () => { + getJsonSpy.mockImplementation(url => { + let res: any; + if (url.includes('/rc')) { + res = nodeTestDistRc; + } else if (url.includes('/nightly')) { + res = nodeTestDistNightly; + } else { + res = nodeTestDist; + } + + return {result: res}; + }); for (const {arch, version, osSpec} of [ {arch: 'x86', version: '12.16.2', osSpec: 'win32'}, {arch: 'x86', version: '14.0.0', osSpec: 'win32'} @@ -399,6 +443,20 @@ describe('setup-node', () => { }, 100000); describe('check-latest flag', () => { + beforeEach(() => { + getJsonSpy.mockImplementation(url => { + let res: any; + if (url.includes('/rc')) { + res = nodeTestDistRc; + } else if (url.includes('/nightly')) { + res = nodeTestDistNightly; + } else { + res = nodeTestDist; + } + + return {result: res}; + }); + }); it('use local version and dont check manifest if check-latest is not specified', async () => { os.platform = 'linux'; os.arch = 'x64'; @@ -897,10 +955,323 @@ describe('setup-node', () => { }); }); + describe('rc versions', () => { + beforeEach(() => { + getJsonSpy.mockImplementation(url => { + let res: any; + if (url.includes('/rc')) { + res = nodeTestDistRc; + } else if (url.includes('/nightly')) { + res = nodeTestDistNightly; + } else { + res = nodeTestDist; + } + + return {result: res}; + }); + }); + + it.each([ + [ + '13.10.1-rc.0', + '13.10.1-rc.0', + 'https://nodejs.org/download/rc/v13.10.1-rc.0/node-v13.10.1-rc.0-linux-x64.tar.gz' + ], + [ + '14.15.5-rc.1', + '14.15.5-rc.1', + 'https://nodejs.org/download/rc/v14.15.5-rc.1/node-v14.15.5-rc.1-linux-x64.tar.gz' + ], + [ + '16.17.0-rc.1', + '16.17.0-rc.1', + 'https://nodejs.org/download/rc/v16.17.0-rc.1/node-v16.17.0-rc.1-linux-x64.tar.gz' + ], + [ + '17.0.0-rc.1', + '17.0.0-rc.1', + 'https://nodejs.org/download/rc/v17.0.0-rc.1/node-v17.0.0-rc.1-linux-x64.tar.gz' + ], + [ + '19.0.0-rc.2', + '19.0.0-rc.2', + 'https://nodejs.org/download/rc/v19.0.0-rc.2/node-v19.0.0-rc.2-linux-x64.tar.gz' + ] + ])( + 'finds the versions in the index.json and installs it', + async (input, expectedVersion, expectedUrl) => { + const toolPath = path.normalize(`/cache/node/${expectedVersion}/x64`); + + findSpy.mockImplementation(() => ''); + findAllVersionsSpy.mockImplementation(() => []); + dlSpy.mockImplementation(async () => '/some/temp/path'); + exSpy.mockImplementation(async () => '/some/other/temp/path'); + cacheSpy.mockImplementation(async () => toolPath); + + inputs['node-version'] = input; + os['arch'] = 'x64'; + os['platform'] = 'linux'; + // act + await main.run(); + + // assert + expect(logSpy).toHaveBeenCalledWith( + `Attempting to download ${input}...` + ); + + expect(logSpy).toHaveBeenCalledWith( + `Acquiring ${expectedVersion} - ${os.arch} from ${expectedUrl}` + ); + expect(logSpy).toHaveBeenCalledWith('Extracting ...'); + expect(logSpy).toHaveBeenCalledWith('Adding to the cache ...'); + expect(cnSpy).toHaveBeenCalledWith( + `::add-path::${path.join(toolPath, 'bin')}${osm.EOL}` + ); + } + ); + + it.each([ + ['13.10.1-rc.0', '13.10.1-rc.0'], + ['14.15.5-rc.1', '14.15.5-rc.1'], + ['16.17.0-rc.1', '16.17.0-rc.1'], + ['17.0.0-rc.1', '17.0.0-rc.1'] + ])( + 'finds the %s version in the hostedToolcache', + async (input, expectedVersion) => { + const toolPath = path.normalize(`/cache/node/${expectedVersion}/x64`); + findSpy.mockReturnValue(toolPath); + + inputs['node-version'] = input; + os['arch'] = 'x64'; + os['platform'] = 'linux'; + + // act + await main.run(); + + // assert + expect(logSpy).toHaveBeenCalledWith(`Found in cache @ ${toolPath}`); + expect(cnSpy).toHaveBeenCalledWith( + `::add-path::${path.join(toolPath, 'bin')}${osm.EOL}` + ); + } + ); + + it('throws an error if version is not found', async () => { + const versionSpec = '19.0.0-rc.3'; + + findSpy.mockImplementation(() => ''); + findAllVersionsSpy.mockImplementation(() => []); + dlSpy.mockImplementation(async () => '/some/temp/path'); + exSpy.mockImplementation(async () => '/some/other/temp/path'); + + inputs['node-version'] = versionSpec; + os['arch'] = 'x64'; + os['platform'] = 'linux'; + // act + await main.run(); + + // assert + expect(logSpy).toHaveBeenCalledWith( + `Attempting to download ${versionSpec}...` + ); + expect(cnSpy).toHaveBeenCalledWith( + `::error::Unable to find Node version '${versionSpec}' for platform ${os.platform} and architecture ${os.arch}.${osm.EOL}` + ); + }); + }); + + describe('nightly versions', () => { + beforeEach(() => { + getJsonSpy.mockImplementation(url => { + let res: any; + if (url.includes('/rc')) { + res = nodeTestDistRc; + } else if (url.includes('/nightly')) { + res = nodeTestDistNightly; + } else { + res = nodeTestDist; + } + + return {result: res}; + }); + }); + + it.each([ + [ + '17.5.0-nightly', + '17.5.0-nightly20220209e43808936a', + 'https://nodejs.org/download/nightly/v17.5.0-nightly20220209e43808936a/node-v17.5.0-nightly20220209e43808936a-linux-x64.tar.gz' + ], + [ + '17-nightly', + '17.5.0-nightly20220209e43808936a', + 'https://nodejs.org/download/nightly/v17.5.0-nightly20220209e43808936a/node-v17.5.0-nightly20220209e43808936a-linux-x64.tar.gz' + ], + [ + '18.0.0-nightly', + '18.0.0-nightly20220419bde889bd4e', + 'https://nodejs.org/download/nightly/v18.0.0-nightly20220419bde889bd4e/node-v18.0.0-nightly20220419bde889bd4e-linux-x64.tar.gz' + ], + [ + '18-nightly', + '18.0.0-nightly20220419bde889bd4e', + 'https://nodejs.org/download/nightly/v18.0.0-nightly20220419bde889bd4e/node-v18.0.0-nightly20220419bde889bd4e-linux-x64.tar.gz' + ], + [ + '20.0.0-nightly', + '20.0.0-nightly2022101987cdf7d412', + 'https://nodejs.org/download/nightly/v20.0.0-nightly2022101987cdf7d412/node-v20.0.0-nightly2022101987cdf7d412-linux-x64.tar.gz' + ] + ])( + 'finds the versions in the index.json and installs it', + async (input, expectedVersion, expectedUrl) => { + const toolPath = path.normalize(`/cache/node/${expectedVersion}/x64`); + + findSpy.mockImplementation(() => ''); + findAllVersionsSpy.mockImplementation(() => []); + dlSpy.mockImplementation(async () => '/some/temp/path'); + exSpy.mockImplementation(async () => '/some/other/temp/path'); + cacheSpy.mockImplementation(async () => toolPath); + + inputs['node-version'] = input; + os['arch'] = 'x64'; + os['platform'] = 'linux'; + // act + await main.run(); + + // assert + expect(logSpy).toHaveBeenCalledWith( + `Attempting to download ${input}...` + ); + + expect(logSpy).toHaveBeenCalledWith( + `Acquiring ${expectedVersion} - ${os.arch} from ${expectedUrl}` + ); + expect(logSpy).toHaveBeenCalledWith('Extracting ...'); + expect(logSpy).toHaveBeenCalledWith('Adding to the cache ...'); + expect(cnSpy).toHaveBeenCalledWith( + `::add-path::${path.join(toolPath, 'bin')}${osm.EOL}` + ); + } + ); + + it.each([ + ['17.5.0-nightly', '17.5.0-nightly20220209e43808936a'], + ['17-nightly', '17.5.0-nightly20220209e43808936a'], + ['20.0.0-nightly', '20.0.0-nightly2022101987cdf7d412'] + ])( + 'finds the %s version in the hostedToolcache', + async (input, expectedVersion) => { + const toolPath = path.normalize(`/cache/node/${expectedVersion}/x64`); + findSpy.mockReturnValue(toolPath); + findAllVersionsSpy.mockReturnValue([ + '17.5.0-nightly20220209e43808936a', + '17.5.0-nightly20220209e43808935a', + '20.0.0-nightly2022101987cdf7d412', + '20.0.0-nightly2022101987cdf7d411' + ]); + + inputs['node-version'] = input; + os['arch'] = 'x64'; + os['platform'] = 'linux'; + + // act + await main.run(); + + // assert + expect(findAllVersionsSpy).toHaveBeenCalled(); + expect(logSpy).toHaveBeenCalledWith(`Found in cache @ ${toolPath}`); + expect(cnSpy).toHaveBeenCalledWith( + `::add-path::${path.join(toolPath, 'bin')}${osm.EOL}` + ); + } + ); + + it.each([ + [ + '17.5.0-nightly', + '17.5.0-nightly20220209e43808936a', + '17.0.0-nightly202110193f11666dc7', + 'https://nodejs.org/download/nightly/v17.5.0-nightly20220209e43808936a/node-v17.5.0-nightly20220209e43808936a-linux-x64.tar.gz' + ], + [ + '17-nightly', + '17.5.0-nightly20220209e43808936a', + '17.0.0-nightly202110193f11666dc7', + 'https://nodejs.org/download/nightly/v17.5.0-nightly20220209e43808936a/node-v17.5.0-nightly20220209e43808936a-linux-x64.tar.gz' + ], + [ + '18.0.0-nightly', + '18.0.0-nightly20220419bde889bd4e', + '18.0.0-nightly202204180699150267', + 'https://nodejs.org/download/nightly/v18.0.0-nightly20220419bde889bd4e/node-v18.0.0-nightly20220419bde889bd4e-linux-x64.tar.gz' + ], + [ + '18-nightly', + '18.0.0-nightly20220419bde889bd4e', + '18.0.0-nightly202204180699150267', + 'https://nodejs.org/download/nightly/v18.0.0-nightly20220419bde889bd4e/node-v18.0.0-nightly20220419bde889bd4e-linux-x64.tar.gz' + ], + [ + '20.0.0-nightly', + '20.0.0-nightly2022101987cdf7d412', + '20.0.0-nightly2022101987cdf7d411', + 'https://nodejs.org/download/nightly/v20.0.0-nightly2022101987cdf7d412/node-v20.0.0-nightly2022101987cdf7d412-linux-x64.tar.gz' + ] + ])( + 'get %s version from dist if check-latest is true', + async (input, expectedVersion, foundVersion, expectedUrl) => { + const foundToolPath = path.normalize(`/cache/node/${foundVersion}/x64`); + const toolPath = path.normalize(`/cache/node/${expectedVersion}/x64`); + + inputs['node-version'] = input; + inputs['check-latest'] = 'true'; + os['arch'] = 'x64'; + os['platform'] = 'linux'; + + findSpy.mockReturnValue(foundToolPath); + findAllVersionsSpy.mockReturnValue([ + '17.0.0-nightly202110193f11666dc7', + '18.0.0-nightly202204180699150267', + '20.0.0-nightly2022101987cdf7d411' + ]); + dlSpy.mockImplementation(async () => '/some/temp/path'); + exSpy.mockImplementation(async () => '/some/other/temp/path'); + cacheSpy.mockImplementation(async () => toolPath); + + // act + await main.run(); + + // assert + expect(findAllVersionsSpy).toHaveBeenCalled(); + expect(logSpy).toHaveBeenCalledWith( + `Acquiring ${expectedVersion} - ${os.arch} from ${expectedUrl}` + ); + expect(logSpy).toHaveBeenCalledWith('Extracting ...'); + expect(logSpy).toHaveBeenCalledWith('Adding to the cache ...'); + expect(cnSpy).toHaveBeenCalledWith( + `::add-path::${path.join(toolPath, 'bin')}${osm.EOL}` + ); + } + ); + }); + describe('latest alias syntax', () => { it.each(['latest', 'current', 'node'])( 'download the %s version if alias is provided', async inputVersion => { + getJsonSpy.mockImplementation(url => { + let res: any; + if (url.includes('/rc')) { + res = nodeTestDistRc; + } else if (url.includes('/nightly')) { + res = nodeTestDistNightly; + } else { + res = nodeTestDist; + } + + return {result: res}; + }); // Arrange inputs['node-version'] = inputVersion; @@ -927,6 +1298,18 @@ describe('setup-node', () => { it.each(['latest', 'current', 'node'])( 'download the %s version if alias is provided', async inputVersion => { + getJsonSpy.mockImplementation(url => { + let res: any; + if (url.includes('/rc')) { + res = nodeTestDistRc; + } else if (url.includes('/nightly')) { + res = nodeTestDistNightly; + } else { + res = nodeTestDist; + } + + return {result: res}; + }); // Arrange inputs['node-version'] = inputVersion; const expectedVersion = nodeTestDist[0]; diff --git a/dist/setup/index.js b/dist/setup/index.js index 0be3cc249..861793de6 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -73428,10 +73428,10 @@ function evaluateNightlyVersions(versions, versionSpec) { const rawVersion = isValidVersion ? raw : semver.coerce(raw); if (rawVersion) { if (prerelease !== 'nightly') { - range = `${rawVersion}+${prerelease.replace('nightly', 'nightly.')}`; + range = `${rawVersion}-${prerelease.replace('nightly', 'nightly.')}`; } else { - range = semver.validRange(`^${rawVersion}`); + range = `${semver.validRange(`^${rawVersion}-0`)}-0`; } } if (range) { @@ -73443,7 +73443,7 @@ function evaluateNightlyVersions(versions, versionSpec) { }); for (let i = versions.length - 1; i >= 0; i--) { const potential = versions[i]; - const satisfied = semver.satisfies(potential.replace('-nightly', '+nightly.'), range); + const satisfied = semver.satisfies(potential.replace('-nightly', '-nightly.'), range, { includePrerelease: true }); if (satisfied) { version = potential; break; @@ -73499,6 +73499,7 @@ function getNodejsDistUrl(version) { return 'https://nodejs.org/download/rc'; } } +exports.getNodejsDistUrl = getNodejsDistUrl; function queryDistForMatch(versionSpec, arch = os.arch(), nodeVersions) { return __awaiter(this, void 0, void 0, function* () { let osPlat = os.platform(); diff --git a/src/installer.ts b/src/installer.ts index 53ace18e9..ccb558e7f 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -376,9 +376,9 @@ function evaluateNightlyVersions( const rawVersion = isValidVersion ? raw : semver.coerce(raw); if (rawVersion) { if (prerelease !== 'nightly') { - range = `${rawVersion}+${prerelease.replace('nightly', 'nightly.')}`; + range = `${rawVersion}-${prerelease.replace('nightly', 'nightly.')}`; } else { - range = semver.validRange(`^${rawVersion}`); + range = `${semver.validRange(`^${rawVersion}-0`)}-0`; } } @@ -392,8 +392,9 @@ function evaluateNightlyVersions( for (let i = versions.length - 1; i >= 0; i--) { const potential: string = versions[i]; const satisfied: boolean = semver.satisfies( - potential.replace('-nightly', '+nightly.'), - range + potential.replace('-nightly', '-nightly.'), + range, + {includePrerelease: true} ); if (satisfied) { version = potential; @@ -444,7 +445,7 @@ function evaluateVersions(versions: string[], versionSpec: string): string { return version; } -function getNodejsDistUrl(version: string) { +export function getNodejsDistUrl(version: string) { const prerelease = semver.prerelease(version); if (version.includes('nightly')) { return 'https://nodejs.org/download/nightly'; From 290087601340a6ff2ef0b66694d376537a98f1fc Mon Sep 17 00:00:00 2001 From: Dmitry Shibanov Date: Sun, 23 Oct 2022 14:05:58 +0200 Subject: [PATCH 3/9] fix comments --- dist/setup/index.js | 47 ++++++++++++++++++++------------------------ src/cache-restore.ts | 2 +- src/installer.ts | 21 +++++++------------- 3 files changed, 29 insertions(+), 41 deletions(-) diff --git a/dist/setup/index.js b/dist/setup/index.js index 861793de6..97df553fa 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -73172,6 +73172,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; @@ -73180,7 +73183,7 @@ var __importStar = (this && this.__importStar) || function (mod) { return result; }; Object.defineProperty(exports, "__esModule", ({ value: true })); -const os = __nccwpck_require__(2037); +const os_1 = __importDefault(__nccwpck_require__(2037)); const assert = __importStar(__nccwpck_require__(9491)); const core = __importStar(__nccwpck_require__(2186)); const hc = __importStar(__nccwpck_require__(9925)); @@ -73188,14 +73191,14 @@ const io = __importStar(__nccwpck_require__(7436)); const tc = __importStar(__nccwpck_require__(7784)); const path = __importStar(__nccwpck_require__(1017)); const semver = __importStar(__nccwpck_require__(5911)); -const fs = __nccwpck_require__(7147); -function getNode(versionSpec, stable, checkLatest, auth, arch = os.arch()) { +const fs_1 = __importDefault(__nccwpck_require__(7147)); +function getNode(versionSpec, stable, checkLatest, auth, arch = os_1.default.arch()) { return __awaiter(this, void 0, void 0, function* () { // Store manifest data to avoid multiple calls let manifest; let nodeVersions; let isNightly = versionSpec.includes('nightly'); - let osPlat = os.platform(); + let osPlat = os_1.default.platform(); let osArch = translateArchToDistUrl(arch); if (isLtsAlias(versionSpec)) { core.info('Attempt to resolve LTS alias from manifest...'); @@ -73295,7 +73298,7 @@ function getNode(versionSpec, stable, checkLatest, auth, arch = os.arch()) { extPath = yield tc.extract7z(downloadPath, undefined, _7zPath); // 7z extracts to folder matching file name let nestedPath = path.join(extPath, path.basename(info.fileName, '.7z')); - if (fs.existsSync(nestedPath)) { + if (fs_1.default.existsSync(nestedPath)) { extPath = nestedPath; } } @@ -73364,7 +73367,7 @@ 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()), manifest) { +function getInfoFromManifest(versionSpec, stable, auth, osArch = translateArchToDistUrl(os_1.default.arch()), manifest) { return __awaiter(this, void 0, void 0, function* () { let info = null; if (!manifest) { @@ -73382,9 +73385,9 @@ function getInfoFromManifest(versionSpec, stable, auth, osArch = translateArchTo return info; }); } -function getInfoFromDist(versionSpec, arch = os.arch(), nodeVersions) { +function getInfoFromDist(versionSpec, arch = os_1.default.arch(), nodeVersions) { return __awaiter(this, void 0, void 0, function* () { - let osPlat = os.platform(); + let osPlat = os_1.default.platform(); let osArch = translateArchToDistUrl(arch); let version = yield queryDistForMatch(versionSpec, arch, nodeVersions); if (!version) { @@ -73408,7 +73411,7 @@ function getInfoFromDist(versionSpec, arch = os.arch(), nodeVersions) { }; }); } -function resolveVersionFromManifest(versionSpec, stable, auth, osArch = translateArchToDistUrl(os.arch()), manifest) { +function resolveVersionFromManifest(versionSpec, stable, auth, osArch = translateArchToDistUrl(os_1.default.arch()), manifest) { return __awaiter(this, void 0, void 0, function* () { try { const info = yield getInfoFromManifest(versionSpec, stable, auth, osArch, manifest); @@ -73435,17 +73438,11 @@ function evaluateNightlyVersions(versions, versionSpec) { } } 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, { includePrerelease: true }); + versions.sort((a, b) => +semver.lt(a, b) * 1 - 0.5); + for (const currentVersion of versions) { + const satisfied = semver.satisfies(currentVersion.replace('-nightly', '-nightly.'), range, { includePrerelease: true }); if (satisfied) { - version = potential; + version = currentVersion; break; } } @@ -73495,14 +73492,12 @@ function getNodejsDistUrl(version) { else if (!prerelease) { return 'https://nodejs.org/dist'; } - else { - return 'https://nodejs.org/download/rc'; - } + return 'https://nodejs.org/download/rc'; } exports.getNodejsDistUrl = getNodejsDistUrl; -function queryDistForMatch(versionSpec, arch = os.arch(), nodeVersions) { +function queryDistForMatch(versionSpec, arch = os_1.default.arch(), nodeVersions) { return __awaiter(this, void 0, void 0, function* () { - let osPlat = os.platform(); + let osPlat = os_1.default.platform(); let osArch = translateArchToDistUrl(arch); // node offers a json list of versions let dataFileName; @@ -73564,10 +73559,10 @@ exports.getVersionsFromDist = getVersionsFromDist; // This method attempts to download and cache the resources from these alternative locations. // Note also that the files are normally zipped but in this case they are just an exe // and lib file in a folder, not zipped. -function acquireNodeFromFallbackLocation(version, arch = os.arch()) { +function acquireNodeFromFallbackLocation(version, arch = os_1.default.arch()) { return __awaiter(this, void 0, void 0, function* () { const initialUrl = getNodejsDistUrl(version); - let osPlat = os.platform(); + let osPlat = os_1.default.platform(); let osArch = translateArchToDistUrl(arch); // Create temporary folder to download in to const tempDownloadFolder = 'temp_' + Math.floor(Math.random() * 2000000000); diff --git a/src/cache-restore.ts b/src/cache-restore.ts index d49b27fc5..7f761da44 100644 --- a/src/cache-restore.ts +++ b/src/cache-restore.ts @@ -4,7 +4,7 @@ import * as glob from '@actions/glob'; import path from 'path'; import fs from 'fs'; -import {State, Outputs} from './constants'; +import {State} from './constants'; import { getCacheDirectoryPath, getPackageManagerInfo, diff --git a/src/installer.ts b/src/installer.ts index ccb558e7f..0b00bb1c2 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -1,4 +1,4 @@ -import os = require('os'); +import os from 'os'; import * as assert from 'assert'; import * as core from '@actions/core'; import * as hc from '@actions/http-client'; @@ -6,7 +6,7 @@ import * as io from '@actions/io'; import * as tc from '@actions/tool-cache'; import * as path from 'path'; import * as semver from 'semver'; -import fs = require('fs'); +import fs from 'fs'; // // Node versions interface @@ -383,21 +383,15 @@ function evaluateNightlyVersions( } 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]; + versions.sort((a, b) => +semver.lt(a, b) * 1 - 0.5); + for (const currentVersion of versions) { const satisfied: boolean = semver.satisfies( - potential.replace('-nightly', '-nightly.'), + currentVersion.replace('-nightly', '-nightly.'), range, {includePrerelease: true} ); if (satisfied) { - version = potential; + version = currentVersion; break; } } @@ -451,9 +445,8 @@ export function getNodejsDistUrl(version: string) { return 'https://nodejs.org/download/nightly'; } else if (!prerelease) { return 'https://nodejs.org/dist'; - } else { - return 'https://nodejs.org/download/rc'; } + return 'https://nodejs.org/download/rc'; } async function queryDistForMatch( From ca842d5a5e52d71c1c7f9e9051efb94fd357905a Mon Sep 17 00:00:00 2001 From: Dmitry Shibanov Date: Sun, 23 Oct 2022 14:25:50 +0200 Subject: [PATCH 4/9] fix tests and update documentation --- README.md | 12 +++--- __tests__/installer.test.ts | 80 ------------------------------------- dist/setup/index.js | 6 +-- docs/advanced-usage.md | 36 +++++++++++++++++ src/installer.ts | 7 ++-- 5 files changed, 50 insertions(+), 91 deletions(-) diff --git a/README.md b/README.md index c3d07869d..a73c66462 100644 --- a/README.md +++ b/README.md @@ -116,11 +116,13 @@ jobs: 1. [Check latest version](docs/advanced-usage.md#check-latest-version) 2. [Using a node version file](docs/advanced-usage.md#node-version-file) 3. [Using different architectures](docs/advanced-usage.md#architecture) -4. [Caching packages data](docs/advanced-usage.md#caching-packages-data) -5. [Using multiple operating systems and architectures](docs/advanced-usage.md#multiple-operating-systems-and-architectures) -6. [Publishing to npmjs and GPR with npm](docs/advanced-usage.md#publish-to-npmjs-and-gpr-with-npm) -7. [Publishing to npmjs and GPR with yarn](docs/advanced-usage.md#publish-to-npmjs-and-gpr-with-yarn) -8. [Using private packages](docs/advanced-usage.md#use-private-packages) +4. [Using nigthly versions](docs/advanced-usage.md#nightly-versions) +5. [Using rc versions](docs/advanced-usage.md#rc-versions) +6. [Caching packages data](docs/advanced-usage.md#caching-packages-data) +7. [Using multiple operating systems and architectures](docs/advanced-usage.md#multiple-operating-systems-and-architectures) +8. [Publishing to npmjs and GPR with npm](docs/advanced-usage.md#publish-to-npmjs-and-gpr-with-npm) +9. [Publishing to npmjs and GPR with yarn](docs/advanced-usage.md#publish-to-npmjs-and-gpr-with-yarn) +10. [Using private packages](docs/advanced-usage.md#use-private-packages) ## License diff --git a/__tests__/installer.test.ts b/__tests__/installer.test.ts index 7111265db..3c3105e2c 100644 --- a/__tests__/installer.test.ts +++ b/__tests__/installer.test.ts @@ -391,18 +391,6 @@ describe('setup-node', () => { }); it('acquires specified architecture of node', async () => { - getJsonSpy.mockImplementation(url => { - let res: any; - if (url.includes('/rc')) { - res = nodeTestDistRc; - } else if (url.includes('/nightly')) { - res = nodeTestDistNightly; - } else { - res = nodeTestDist; - } - - return {result: res}; - }); for (const {arch, version, osSpec} of [ {arch: 'x86', version: '12.16.2', osSpec: 'win32'}, {arch: 'x86', version: '14.0.0', osSpec: 'win32'} @@ -443,20 +431,6 @@ describe('setup-node', () => { }, 100000); describe('check-latest flag', () => { - beforeEach(() => { - getJsonSpy.mockImplementation(url => { - let res: any; - if (url.includes('/rc')) { - res = nodeTestDistRc; - } else if (url.includes('/nightly')) { - res = nodeTestDistNightly; - } else { - res = nodeTestDist; - } - - return {result: res}; - }); - }); it('use local version and dont check manifest if check-latest is not specified', async () => { os.platform = 'linux'; os.arch = 'x64'; @@ -956,21 +930,6 @@ describe('setup-node', () => { }); describe('rc versions', () => { - beforeEach(() => { - getJsonSpy.mockImplementation(url => { - let res: any; - if (url.includes('/rc')) { - res = nodeTestDistRc; - } else if (url.includes('/nightly')) { - res = nodeTestDistNightly; - } else { - res = nodeTestDist; - } - - return {result: res}; - }); - }); - it.each([ [ '13.10.1-rc.0', @@ -1081,21 +1040,6 @@ describe('setup-node', () => { }); describe('nightly versions', () => { - beforeEach(() => { - getJsonSpy.mockImplementation(url => { - let res: any; - if (url.includes('/rc')) { - res = nodeTestDistRc; - } else if (url.includes('/nightly')) { - res = nodeTestDistNightly; - } else { - res = nodeTestDist; - } - - return {result: res}; - }); - }); - it.each([ [ '17.5.0-nightly', @@ -1260,18 +1204,6 @@ describe('setup-node', () => { it.each(['latest', 'current', 'node'])( 'download the %s version if alias is provided', async inputVersion => { - getJsonSpy.mockImplementation(url => { - let res: any; - if (url.includes('/rc')) { - res = nodeTestDistRc; - } else if (url.includes('/nightly')) { - res = nodeTestDistNightly; - } else { - res = nodeTestDist; - } - - return {result: res}; - }); // Arrange inputs['node-version'] = inputVersion; @@ -1298,18 +1230,6 @@ describe('setup-node', () => { it.each(['latest', 'current', 'node'])( 'download the %s version if alias is provided', async inputVersion => { - getJsonSpy.mockImplementation(url => { - let res: any; - if (url.includes('/rc')) { - res = nodeTestDistRc; - } else if (url.includes('/nightly')) { - res = nodeTestDistNightly; - } else { - res = nodeTestDist; - } - - return {result: res}; - }); // Arrange inputs['node-version'] = inputVersion; const expectedVersion = nodeTestDist[0]; diff --git a/dist/setup/index.js b/dist/setup/index.js index 97df553fa..3a820b6ba 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -73489,10 +73489,10 @@ function getNodejsDistUrl(version) { if (version.includes('nightly')) { return 'https://nodejs.org/download/nightly'; } - else if (!prerelease) { - return 'https://nodejs.org/dist'; + else if (prerelease) { + return 'https://nodejs.org/download/rc'; } - return 'https://nodejs.org/download/rc'; + return 'https://nodejs.org/dist'; } exports.getNodejsDistUrl = getNodejsDistUrl; function queryDistForMatch(versionSpec, arch = os_1.default.arch(), nodeVersions) { diff --git a/docs/advanced-usage.md b/docs/advanced-usage.md index 4b620cbde..287b130fd 100644 --- a/docs/advanced-usage.md +++ b/docs/advanced-usage.md @@ -104,6 +104,42 @@ jobs: - run: npm test ``` +## Nightly versions + +You can specify a nightly version to download it from https://nodejs.org/download/nightly. + +```yaml +jobs: + build: + runs-on: ubuntu-latest + name: Node sample + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: '16.0.0-nightly' # or 16-nightly + - run: npm ci + - run: npm test +``` + +## RC versions + +You can use specify a rc version to download it from https://nodejs.org/download/rc. + +```yaml +jobs: + build: + runs-on: ubuntu-latest + name: Node sample + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: '16.0.0-rc.1' + - run: npm ci + - run: npm test +``` + ## Caching packages data The action follows [actions/cache](https://github.com/actions/cache/blob/main/examples.md#node---npm) guidelines, and caches global cache on the machine instead of `node_modules`, so cache can be reused between different Node.js versions. diff --git a/src/installer.ts b/src/installer.ts index 0b00bb1c2..dac4f5d97 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -443,10 +443,11 @@ export function getNodejsDistUrl(version: string) { const prerelease = semver.prerelease(version); if (version.includes('nightly')) { return 'https://nodejs.org/download/nightly'; - } else if (!prerelease) { - return 'https://nodejs.org/dist'; + } else if (prerelease) { + return 'https://nodejs.org/download/rc'; } - return 'https://nodejs.org/download/rc'; + + return 'https://nodejs.org/dist'; } async function queryDistForMatch( From 6dfecd47b39e9af4d128865cc4608c1e06d09a40 Mon Sep 17 00:00:00 2001 From: Dmitry Shibanov Date: Mon, 24 Oct 2022 11:38:00 +0200 Subject: [PATCH 5/9] fix comment --- 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 3a820b6ba..be1167823 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -73438,7 +73438,7 @@ function evaluateNightlyVersions(versions, versionSpec) { } } if (range) { - versions.sort((a, b) => +semver.lt(a, b) * 1 - 0.5); + versions.sort((a, b) => +semver.lt(a, b) - 0.5); for (const currentVersion of versions) { const satisfied = semver.satisfies(currentVersion.replace('-nightly', '-nightly.'), range, { includePrerelease: true }); if (satisfied) { diff --git a/src/installer.ts b/src/installer.ts index dac4f5d97..51af33578 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -383,7 +383,7 @@ function evaluateNightlyVersions( } if (range) { - versions.sort((a, b) => +semver.lt(a, b) * 1 - 0.5); + versions.sort((a, b) => +semver.lt(a, b) - 0.5); for (const currentVersion of versions) { const satisfied: boolean = semver.satisfies( currentVersion.replace('-nightly', '-nightly.'), From 65270bbd5582032571746d4c5531670130448195 Mon Sep 17 00:00:00 2001 From: Dmitry Shibanov Date: Tue, 25 Oct 2022 21:08:55 +0200 Subject: [PATCH 6/9] add fixes --- dist/setup/index.js | 2 +- src/installer.ts | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/dist/setup/index.js b/dist/setup/index.js index be1167823..a39bcda26 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -73440,7 +73440,7 @@ function evaluateNightlyVersions(versions, versionSpec) { if (range) { versions.sort((a, b) => +semver.lt(a, b) - 0.5); for (const currentVersion of versions) { - const satisfied = semver.satisfies(currentVersion.replace('-nightly', '-nightly.'), range, { includePrerelease: true }); + const satisfied = semver.satisfies(currentVersion.replace('-nightly', '-nightly.'), range, { includePrerelease: true }) && currentVersion.includes('nightly'); if (satisfied) { version = currentVersion; break; diff --git a/src/installer.ts b/src/installer.ts index 51af33578..37bb7ce8f 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -385,11 +385,12 @@ function evaluateNightlyVersions( if (range) { versions.sort((a, b) => +semver.lt(a, b) - 0.5); for (const currentVersion of versions) { - const satisfied: boolean = semver.satisfies( - currentVersion.replace('-nightly', '-nightly.'), - range, - {includePrerelease: true} - ); + const satisfied: boolean = + semver.satisfies( + currentVersion.replace('-nightly', '-nightly.'), + range, + {includePrerelease: true} + ) && currentVersion.includes('nightly'); if (satisfied) { version = currentVersion; break; From 882cfbaf7805b7a67aa7a34e4f19096f6a39ae2a Mon Sep 17 00:00:00 2001 From: Dmitry Shibanov Date: Tue, 8 Nov 2022 20:38:57 +0100 Subject: [PATCH 7/9] work on resolving comments --- .github/workflows/versions.yml | 2 +- __tests__/README.md | 10 +++++++++ dist/setup/index.js | 9 ++------ docs/advanced-usage.md | 40 ++++++++++++++++++++++++++++++++-- src/installer.ts | 11 +++------- 5 files changed, 54 insertions(+), 18 deletions(-) create mode 100644 __tests__/README.md diff --git a/.github/workflows/versions.yml b/.github/workflows/versions.yml index ce43847ae..34da05a7a 100644 --- a/.github/workflows/versions.yml +++ b/.github/workflows/versions.yml @@ -57,7 +57,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest, windows-latest, macos-latest] - node-version: [17-nightly, 18-nightly, 19-nightly] + node-version: [16.0.0-nightly20210420a0261d231c, 17-nightly, 18.0.0-nightly] steps: - uses: actions/checkout@v3 - name: Setup Node diff --git a/__tests__/README.md b/__tests__/README.md new file mode 100644 index 000000000..bbb4ac069 --- /dev/null +++ b/__tests__/README.md @@ -0,0 +1,10 @@ +Files located in data directory are used only for testing purposes. + + +## Here the list of files in the data directory + - `.nvmrc`, `.tools-versions` and `package.json` are used to test node-version-file logic + - `package-lock.json`, `pnpm-lock.yaml` and `yarn.lock` are used to test cache logic + - `versions-manifest.json` is used for unit testing to check downloading Node.js versions from the node-versions repository. + - `node-dist-index.json` is used for unit testing to check downloading Node.js versions from the official site. + - `node-rc-index.json` is used for unit testing to check downloading Node.js rc versions from the official site. + - `node-nightly-index.json` is used for unit testing to check downloading Node.js nightly builds from the official site. \ No newline at end of file diff --git a/dist/setup/index.js b/dist/setup/index.js index a39bcda26..c3e536479 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -73438,7 +73438,7 @@ function evaluateNightlyVersions(versions, versionSpec) { } } if (range) { - versions.sort((a, b) => +semver.lt(a, b) - 0.5); + versions.sort(semver.rcompare); for (const currentVersion of versions) { const satisfied = semver.satisfies(currentVersion.replace('-nightly', '-nightly.'), range, { includePrerelease: true }) && currentVersion.includes('nightly'); if (satisfied) { @@ -73462,12 +73462,7 @@ function evaluateVersions(versions, versionSpec) { if (versionSpec.includes('nightly')) { return evaluateNightlyVersions(versions, versionSpec); } - versions = versions.sort((a, b) => { - if (semver.gt(a, b)) { - return 1; - } - return -1; - }); + versions = versions.sort(semver.rcompare); for (let i = versions.length - 1; i >= 0; i--) { const potential = versions[i]; const satisfied = semver.satisfies(potential, versionSpec); diff --git a/docs/advanced-usage.md b/docs/advanced-usage.md index 287b130fd..c2a8374ea 100644 --- a/docs/advanced-usage.md +++ b/docs/advanced-usage.md @@ -106,7 +106,25 @@ jobs: ## Nightly versions -You can specify a nightly version to download it from https://nodejs.org/download/nightly. +You can specify a nightly version to download it from https://nodejs.org/download/nightly. + +### Install nightly build for specific node version + +```yaml +jobs: + build: + runs-on: ubuntu-latest + name: Node sample + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: '16.0.0-nightly' # it will install the latest nigthly release for node 16.0.0 + - run: npm ci + - run: npm test +``` + +### Install nightly build for major node version ```yaml jobs: @@ -117,7 +135,23 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: - node-version: '16.0.0-nightly' # or 16-nightly + node-version: '16-nightly' # it will install the latest nigthly release for node 16 + - run: npm ci + - run: npm test +``` + +### Install the exact nightly version + +```yaml +jobs: + build: + runs-on: ubuntu-latest + name: Node sample + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: '16.0.0-nightly20210420a0261d231c' - run: npm ci - run: npm test ``` @@ -140,6 +174,8 @@ jobs: - run: npm test ``` +**Note:** You should specify the exact version for rc: `16.0.0-rc.1`. + ## Caching packages data The action follows [actions/cache](https://github.com/actions/cache/blob/main/examples.md#node---npm) guidelines, and caches global cache on the machine instead of `node_modules`, so cache can be reused between different Node.js versions. diff --git a/src/installer.ts b/src/installer.ts index 37bb7ce8f..1b5659b6a 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -370,7 +370,7 @@ function evaluateNightlyVersions( versionSpec: string ): string { let version = ''; - let range: string | null | undefined; + let range: string | undefined; const [raw, prerelease] = versionSpec.split('-'); const isValidVersion = semver.valid(raw); const rawVersion = isValidVersion ? raw : semver.coerce(raw); @@ -383,7 +383,7 @@ function evaluateNightlyVersions( } if (range) { - versions.sort((a, b) => +semver.lt(a, b) - 0.5); + versions.sort(semver.rcompare); for (const currentVersion of versions) { const satisfied: boolean = semver.satisfies( @@ -416,12 +416,7 @@ function evaluateVersions(versions: string[], versionSpec: string): string { return evaluateNightlyVersions(versions, versionSpec); } - versions = versions.sort((a, b) => { - if (semver.gt(a, b)) { - return 1; - } - return -1; - }); + versions = versions.sort(semver.rcompare); for (let i = versions.length - 1; i >= 0; i--) { const potential: string = versions[i]; const satisfied: boolean = semver.satisfies(potential, versionSpec); From 0dbcb6ae71214970ca50d95a0821cd96ef55c530 Mon Sep 17 00:00:00 2001 From: Dmitry Shibanov Date: Wed, 9 Nov 2022 13:14:35 +0100 Subject: [PATCH 8/9] rebuild dist --- dist/setup/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dist/setup/index.js b/dist/setup/index.js index c3e536479..8292b338e 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -73691,7 +73691,7 @@ function run() { } if (version) { const token = core.getInput('token'); - const auth = !token || cache_utils_1.isGhes() ? undefined : `token ${token}`; + const auth = !token ? 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); From ce01da25772ec77000d7cf16688b8713fefb994c Mon Sep 17 00:00:00 2001 From: Dmitry Shibanov Date: Wed, 9 Nov 2022 21:16:59 +0100 Subject: [PATCH 9/9] fix documentation --- __tests__/README.md | 6 +++--- docs/advanced-usage.md | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/__tests__/README.md b/__tests__/README.md index bbb4ac069..c14898431 100644 --- a/__tests__/README.md +++ b/__tests__/README.md @@ -5,6 +5,6 @@ Files located in data directory are used only for testing purposes. - `.nvmrc`, `.tools-versions` and `package.json` are used to test node-version-file logic - `package-lock.json`, `pnpm-lock.yaml` and `yarn.lock` are used to test cache logic - `versions-manifest.json` is used for unit testing to check downloading Node.js versions from the node-versions repository. - - `node-dist-index.json` is used for unit testing to check downloading Node.js versions from the official site. - - `node-rc-index.json` is used for unit testing to check downloading Node.js rc versions from the official site. - - `node-nightly-index.json` is used for unit testing to check downloading Node.js nightly builds from the official site. \ No newline at end of file + - `node-dist-index.json` is used for unit testing to check downloading Node.js versions from the official site. The file was constructed from https://nodejs.org/dist/index.json + - `node-rc-index.json` is used for unit testing to check downloading Node.js rc versions from the official site. The file was constructed from https://nodejs.org/download/rc/index.json + - `node-nightly-index.json` is used for unit testing to check downloading Node.js nightly builds from the official site. The file was constructed from https://nodejs.org/download/nightly/index.json \ No newline at end of file diff --git a/docs/advanced-usage.md b/docs/advanced-usage.md index c2a8374ea..4789f2ead 100644 --- a/docs/advanced-usage.md +++ b/docs/advanced-usage.md @@ -108,7 +108,7 @@ jobs: You can specify a nightly version to download it from https://nodejs.org/download/nightly. -### Install nightly build for specific node version +### Install the nightly build for a major version ```yaml jobs: @@ -119,12 +119,12 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: - node-version: '16.0.0-nightly' # it will install the latest nigthly release for node 16.0.0 + node-version: '16-nightly' # it will install the latest nightly release for node 16 - run: npm ci - run: npm test ``` -### Install nightly build for major node version +### Install the nightly build for a specific version ```yaml jobs: @@ -135,12 +135,12 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: - node-version: '16-nightly' # it will install the latest nigthly release for node 16 + node-version: '16.0.0-nightly' # it will install the latest nightly release for node 16.0.0 - run: npm ci - run: npm test ``` -### Install the exact nightly version +### Install an exact nightly version ```yaml jobs: @@ -174,7 +174,7 @@ jobs: - run: npm test ``` -**Note:** You should specify the exact version for rc: `16.0.0-rc.1`. +**Note:** Unlike nightly versions, which support version range specifiers, you must specify the exact version for a release candidate: `16.0.0-rc.1`. ## Caching packages data The action follows [actions/cache](https://github.com/actions/cache/blob/main/examples.md#node---npm) guidelines, and caches global cache on the machine instead of `node_modules`, so cache can be reused between different Node.js versions.