Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support LTS aliases #270

Merged
merged 18 commits into from Jun 30, 2021
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions __tests__/data/versions-manifest.json
Expand Up @@ -2,6 +2,7 @@
{
"version": "14.0.0",
"stable": true,
"lts": "Fermium",
"release_url": "https://github.com/actions/node-versions/releases/tag/14.0.0-20200423.30",
"files": [
{
Expand Down Expand Up @@ -52,6 +53,7 @@
{
"version": "12.16.2",
"stable": true,
"lts": "Erbium",
"release_url": "https://github.com/actions/node-versions/releases/tag/12.16.2-20200423.28",
"files": [
{
Expand All @@ -77,6 +79,7 @@
{
"version": "10.20.1",
"stable": true,
"lts": "Dubnium",
"release_url": "https://github.com/actions/node-versions/releases/tag/10.20.1-20200423.27",
"files": [
{
Expand All @@ -102,6 +105,7 @@
{
"version": "8.17.0",
"stable": true,
"lts": "Carbon",
"release_url": "https://github.com/actions/node-versions/releases/tag/8.17.0-20200423.26",
"files": [
{
Expand All @@ -127,6 +131,7 @@
{
"version": "6.17.1",
"stable": true,
"lts": "Boron",
"release_url": "https://github.com/actions/node-versions/releases/tag/6.17.1-20200423.25",
"files": [
{
Expand Down
164 changes: 164 additions & 0 deletions __tests__/installer.test.ts
Expand Up @@ -134,6 +134,7 @@ describe('setup-node', () => {
let match = await tc.findFromManifest('12.16.2', true, versions);
expect(match).toBeDefined();
expect(match?.version).toBe('12.16.2');
expect((match as any).lts).toBe('Erbium')
});

it('can find 12 from manifest on linux', async () => {
Expand All @@ -148,6 +149,7 @@ describe('setup-node', () => {
let match = await tc.findFromManifest('12.16.2', true, versions);
expect(match).toBeDefined();
expect(match?.version).toBe('12.16.2');
expect((match as any).lts).toBe('Erbium')
});

it('can find 10 from manifest on windows', async () => {
Expand All @@ -162,6 +164,7 @@ describe('setup-node', () => {
let match = await tc.findFromManifest('10', true, versions);
expect(match).toBeDefined();
expect(match?.version).toBe('10.20.1');
expect((match as any).lts).toBe('Dubnium')
});

//--------------------------------------------------
Expand Down Expand Up @@ -217,6 +220,10 @@ describe('setup-node', () => {
expect(cnSpy).toHaveBeenCalledWith('::error::' + errMsg + osm.EOL);
});

//--------------------------------------------------
// Manifest tests
//--------------------------------------------------

it('downloads a version from a manifest match', async () => {
os.platform = 'linux';
os.arch = 'x64';
Expand Down Expand Up @@ -525,4 +532,161 @@ describe('setup-node', () => {
expect(cnSpy).toHaveBeenCalledWith(`::add-path::${expPath}${osm.EOL}`);
});
});

describe('LTS version', () => {
it('find latest LTS version and resolve it from local cache (lts/erbium)', async () => {
// arrange
os.platform = 'linux';
os.arch = 'x64';

inputs['node-version'] = 'lts/erbium';
inputs.stable = 'true';

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

// act
await main.run();

// assert
expect(warningSpy).toHaveBeenCalledWith('LTS version is provided. For LTS versions `check-latest` will be automatically set to true')
expect(logSpy).toHaveBeenCalledWith('Attempt to resolve the latest version from manifest...');
expect(dbgSpy).toHaveBeenCalledWith(`LTS alias 'erbium' for Node version 'lts/erbium'`)
expect(dbgSpy).toHaveBeenCalledWith(`Found LTS release '12.16.2' for Node version 'lts/erbium'`)
expect(logSpy).toHaveBeenCalledWith("Resolved as '12.16.2'");
expect(logSpy).toHaveBeenCalledWith(`Found in cache @ ${toolPath}`);
expect(cnSpy).toHaveBeenCalledWith(`::add-path::${toolPath}/bin${osm.EOL}`);
});

it('find latest LTS version and install it from manifest (lts/erbium)', async () => {
// arrange
os.platform = 'linux';
os.arch = 'x64';

inputs['node-version'] = 'lts/erbium';
inputs.stable = 'true';

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

// act
await main.run();

// assert
expect(warningSpy).toHaveBeenCalledWith('LTS version is provided. For LTS versions `check-latest` will be automatically set to true')
expect(logSpy).toHaveBeenCalledWith('Attempt to resolve the latest version from manifest...');
expect(dbgSpy).toHaveBeenCalledWith(`LTS alias 'erbium' for Node version 'lts/erbium'`)
expect(dbgSpy).toHaveBeenCalledWith(`Found LTS release '12.16.2' for Node version 'lts/erbium'`)
expect(logSpy).toHaveBeenCalledWith("Resolved as '12.16.2'");
expect(logSpy).toHaveBeenCalledWith("Attempting to download 12.16.2...");
expect(logSpy).toHaveBeenCalledWith(`Acquiring 12.16.2 - ${os.arch} from ${expectedUrl}`);
expect(logSpy).toHaveBeenCalledWith('Extracting ...');
expect(logSpy).toHaveBeenCalledWith('Adding to the cache ...');
expect(cnSpy).toHaveBeenCalledWith(`::add-path::${toolPath}/bin${osm.EOL}`);
})

it('find latest LTS version and resolve it from local cache (lts/*)', async () => {
// arrange
os.platform = 'linux';
os.arch = 'x64';

inputs['node-version'] = 'lts/*';
inputs.stable = 'true';

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

// act
await main.run();

// assert
expect(warningSpy).toHaveBeenCalledWith('LTS version is provided. For LTS versions `check-latest` will be automatically set to true')
expect(logSpy).toHaveBeenCalledWith('Attempt to resolve the latest version from manifest...');
expect(dbgSpy).toHaveBeenCalledWith(`LTS alias '*' for Node version 'lts/*'`)
expect(dbgSpy).toHaveBeenCalledWith(`Found LTS release '14.0.0' for Node version 'lts/*'`)
expect(logSpy).toHaveBeenCalledWith("Resolved as '14.0.0'");
expect(logSpy).toHaveBeenCalledWith(`Found in cache @ ${toolPath}`);
expect(cnSpy).toHaveBeenCalledWith(`::add-path::${toolPath}/bin${osm.EOL}`);
});

it('find latest LTS version and install it from manifest (lts/*)', async () => {
// arrange
os.platform = 'linux';
os.arch = 'x64';

inputs['node-version'] = 'lts/*';
inputs.stable = 'true';

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

// act
await main.run();

// assert
expect(warningSpy).toHaveBeenCalledWith('LTS version is provided. For LTS versions `check-latest` will be automatically set to true')
expect(logSpy).toHaveBeenCalledWith('Attempt to resolve the latest version from manifest...');
expect(dbgSpy).toHaveBeenCalledWith(`LTS alias '*' for Node version 'lts/*'`)
expect(dbgSpy).toHaveBeenCalledWith(`Found LTS release '14.0.0' for Node version 'lts/*'`)
expect(logSpy).toHaveBeenCalledWith("Resolved as '14.0.0'");
expect(logSpy).toHaveBeenCalledWith("Attempting to download 14.0.0...");
expect(logSpy).toHaveBeenCalledWith(`Acquiring 14.0.0 - ${os.arch} from ${expectedUrl}`);
expect(logSpy).toHaveBeenCalledWith('Extracting ...');
expect(logSpy).toHaveBeenCalledWith('Adding to the cache ...');
expect(cnSpy).toHaveBeenCalledWith(`::add-path::${toolPath}/bin${osm.EOL}`);
})

it('fail with unexpected LTS alias (lts/)', async () => {
// arrange
os.platform = 'linux';
os.arch = 'x64';

inputs['node-version'] = 'lts/';
inputs.stable = 'true';

findSpy.mockImplementation(() => '');

// act
await main.run();

// assert
expect(warningSpy).toHaveBeenCalledWith('LTS version is provided. For LTS versions `check-latest` will be automatically set to true')
expect(logSpy).toHaveBeenCalledWith('Attempt to resolve the latest version from manifest...');
expect(logSpy).toHaveBeenCalledWith('Unable to resolve version from manifest...');
expect(dbgSpy).toHaveBeenCalledWith(`Unexpected LTS alias '' for Node version 'lts/'`)
expect(logSpy).toHaveBeenCalledWith('Failed to resolve version lts/ from manifest');
expect(cnSpy).toHaveBeenCalledWith(`::error::Unable to find Node version 'lts/' for platform linux and architecture x64.${osm.EOL}`);
});

it('fail to find LTS version (lts/unknown)', async () => {
// arrange
os.platform = 'linux';
os.arch = 'x64';

inputs['node-version'] = 'lts/unknown';
inputs.stable = 'true';

findSpy.mockImplementation(() => '');

// act
await main.run();

// assert
expect(warningSpy).toHaveBeenCalledWith('LTS version is provided. For LTS versions `check-latest` will be automatically set to true')
expect(logSpy).toHaveBeenCalledWith('Attempt to resolve the latest version from manifest...');
expect(dbgSpy).toHaveBeenCalledWith(`LTS alias 'unknown' for Node version 'lts/unknown'`)
expect(logSpy).toHaveBeenCalledWith('Unable to resolve version from manifest...');
expect(dbgSpy).toHaveBeenCalledWith(`Unable to find LTS release 'unknown' for Node version 'lts/unknown'.`)
expect(logSpy).toHaveBeenCalledWith('Failed to resolve version lts/unknown from manifest');
expect(cnSpy).toHaveBeenCalledWith(`::error::Unable to find Node version 'lts/unknown' for platform linux and architecture x64.${osm.EOL}`);
});
})
});
40 changes: 40 additions & 0 deletions src/installer.ts
Expand Up @@ -34,6 +34,11 @@ export async function getNode(
let osPlat: string = os.platform();
let osArch: string = translateArchToDistUrl(arch);

if (isLts(versionSpec)) {
core.warning('LTS version is provided. For LTS versions `check-latest` will be automatically set to true');
gordey4doronin marked this conversation as resolved.
Show resolved Hide resolved
checkLatest = true;
}

if (checkLatest) {
core.info('Attempt to resolve the latest version from manifest...');
const resolvedVersion = await resolveVersionFromManifest(
Expand Down Expand Up @@ -170,6 +175,36 @@ export async function getNode(
core.addPath(toolPath);
}

function isLts(versionSpec: string): boolean {
gordey4doronin marked this conversation as resolved.
Show resolved Hide resolved
return versionSpec.startsWith('lts')
}

function findLtsVersionFromManifest(
versionSpec: string,
stable: boolean,
candidates: Array<tc.IToolRelease & { lts?: string }>
maxim-lobanov marked this conversation as resolved.
Show resolved Hide resolved
): string {
const alias = versionSpec.split('lts/')[1]?.toLowerCase();

if (!alias) {
throw new Error(`Unexpected LTS alias '${alias}' for Node version '${versionSpec}'`);
}

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

const release = alias === '*'
maxim-lobanov marked this conversation as resolved.
Show resolved Hide resolved
? candidates.find(x => !!x.lts && x.stable === stable)
: candidates.find(x => x.lts?.toLowerCase() === alias && x.stable === stable);

if (!release) {
throw new Error(`Unable to find LTS release '${alias}' for Node version '${versionSpec}'.`);
}

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

return release.version.split('.')[0];
}

async function getInfoFromManifest(
versionSpec: string,
stable: boolean,
Expand All @@ -183,6 +218,11 @@ async function getInfoFromManifest(
auth,
'main'
);

if (isLts(versionSpec)) {
versionSpec = findLtsVersionFromManifest(versionSpec, stable, releases);
maxim-lobanov marked this conversation as resolved.
Show resolved Hide resolved
}

const rel = await tc.findFromManifest(versionSpec, stable, releases, osArch);

if (rel && rel.files.length > 0) {
Expand Down