Compare commits

...

4 Commits

Author SHA1 Message Date
Aparna Jyothi
19df1001b0 test cases 2025-01-31 13:16:15 +05:30
Aparna Jyothi
17e88b6567 print 2025-01-31 11:51:22 +05:30
Aparna Jyothi
7188cb1e62 prints 2025-01-31 11:46:26 +05:30
Aparna Jyothi
91a5e5da06 update mirrorURL versions 2025-01-31 11:11:24 +05:30
11 changed files with 633 additions and 149 deletions

View File

@ -13,6 +13,10 @@ import each from 'jest-each';
import * as main from '../src/main'; import * as main from '../src/main';
import * as util from '../src/util'; import * as util from '../src/util';
import OfficialBuilds from '../src/distributions/official_builds/official_builds'; import OfficialBuilds from '../src/distributions/official_builds/official_builds';
import * as installerFactory from '../src/distributions/installer-factory';
jest.mock('../src/distributions/installer-factory', () => ({
getNodejsDistribution: jest.fn()
}));
describe('main tests', () => { describe('main tests', () => {
let inputs = {} as any; let inputs = {} as any;
@ -281,3 +285,125 @@ describe('main tests', () => {
}); });
}); });
}); });
// Mock the necessary modules
jest.mock('@actions/core');
jest.mock('./distributions/installer-factory');
// Create a mock object that satisfies the BaseDistribution type
const createMockNodejsDistribution = () => ({
setupNodeJs: jest.fn(),
// Mocking other properties required by the BaseDistribution type (adjust based on your actual types)
httpClient: {}, // Example for httpClient, replace with proper mock if necessary
osPlat: 'darwin', // Example platform ('darwin', 'win32', 'linux', etc.)
nodeInfo: {
version: '14.x',
arch: 'x64',
platform: 'darwin',
},
getDistributionUrl: jest.fn().mockReturnValue('https://nodejs.org/dist/'), // Default distribution URL
install: jest.fn(),
validate: jest.fn(),
// Mock any other methods/properties defined in BaseDistribution
});
// Define the mock structure for BaseDistribution type (adjust to your actual type)
interface BaseDistribution {
setupNodeJs: jest.Mock;
httpClient: object;
osPlat: string;
nodeInfo: {
version: string;
arch: string;
platform: string;
};
getDistributionUrl: jest.Mock;
install: jest.Mock;
validate: jest.Mock;
}
describe('Mirror URL Tests', () => {
beforeEach(() => {
jest.clearAllMocks();
});
it('should pass mirror URL correctly when provided', async () => {
(core.getInput as jest.Mock).mockImplementation((name: string) => {
if (name === 'mirror-url') return 'https://custom-mirror-url.com';
if (name === 'node-version') return '14.x';
return '';
});
const mockNodejsDistribution = createMockNodejsDistribution();
(installerFactory.getNodejsDistribution as unknown as jest.Mock<typeof installerFactory.getNodejsDistribution>).mockReturnValue(mockNodejsDistribution);
await main.run();
// Ensure setupNodeJs is called with the correct parameters, including the mirror URL
expect(mockNodejsDistribution.setupNodeJs).toHaveBeenCalledWith({
versionSpec: '14.x',
checkLatest: false,
auth: undefined,
stable: true,
arch: 'x64',
mirrorURL: 'https://custom-mirror-url.com',
});
});
it('should use default mirror URL when no mirror URL is provided', async () => {
(core.getInput as jest.Mock).mockImplementation((name: string) => {
if (name === 'mirror-url') return '';
if (name === 'node-version') return '14.x';
return '';
});
const mockNodejsDistribution = createMockNodejsDistribution();
(installerFactory.getNodejsDistribution as jest.Mock).mockReturnValue(mockNodejsDistribution);
await main.run();
// Expect that setupNodeJs is called with an empty mirror URL (which will default inside the function)
expect(mockNodejsDistribution.setupNodeJs).toHaveBeenCalledWith(expect.objectContaining({
mirrorURL: '', // Default URL is expected to be handled internally
}));
});
it('should handle mirror URL with spaces correctly', async () => {
(core.getInput as jest.Mock).mockImplementation((name: string) => {
if (name === 'mirror-url') return ' https://custom-mirror-url.com ';
if (name === 'node-version') return '14.x';
return '';
});
const mockNodejsDistribution = createMockNodejsDistribution();
(installerFactory.getNodejsDistribution as jest.Mock).mockReturnValue(mockNodejsDistribution);
await main.run();
// Expect that setupNodeJs is called with the trimmed mirror URL
expect(mockNodejsDistribution.setupNodeJs).toHaveBeenCalledWith(expect.objectContaining({
mirrorURL: 'https://custom-mirror-url.com',
}));
});
it('should warn if architecture is provided but node-version is missing', async () => {
(core.getInput as jest.Mock).mockImplementation((name: string) => {
if (name === 'architecture') return 'x64';
if (name === 'node-version') return '';
return '';
});
const mockWarning = jest.spyOn(core, 'warning');
const mockNodejsDistribution = createMockNodejsDistribution();
installerFactory.getNodejsDistribution.mockReturnValue(mockNodejsDistribution);
await main.run();
expect(mockWarning).toHaveBeenCalledWith(
'`architecture` is provided but `node-version` is missing. In this configuration, the version/architecture of Node will not be changed.'
);
expect(mockNodejsDistribution.setupNodeJs).not.toHaveBeenCalled(); // Setup Node should not be called
});
});

View File

@ -10,8 +10,8 @@ import osm from 'os';
import path from 'path'; import path from 'path';
import * as main from '../src/main'; import * as main from '../src/main';
import * as auth from '../src/authutil'; import * as auth from '../src/authutil';
import {INodeVersion} from '../src/distributions/base-models'; import {INodeVersion, NodeInputs} from '../src/distributions/base-models';
import NightlyNodejs from '../src/distributions/nightly/nightly_builds';
import nodeTestManifest from './data/versions-manifest.json'; import nodeTestManifest from './data/versions-manifest.json';
import nodeTestDist from './data/node-dist-index.json'; import nodeTestDist from './data/node-dist-index.json';
import nodeTestDistNightly from './data/node-nightly-index.json'; import nodeTestDistNightly from './data/node-nightly-index.json';
@ -606,3 +606,95 @@ describe('setup-node', () => {
); );
}); });
}); });
// Mock core.info to track the log output
jest.mock('@actions/core', () => ({
info: jest.fn(),
}));
// Create a subclass to access the protected method for testing purposes
class TestNightlyNodejs extends NightlyNodejs {
public getDistributionUrlPublic() {
return this.getDistributionUrl(); // This allows us to call the protected method
}
}
describe('NightlyNodejs', () => {
it('uses mirror URL when provided', async () => {
const mirrorURL = 'https://my.custom.mirror/nodejs/nightly';
const nodeInfo: NodeInputs = {
mirrorURL: '', versionSpec: '18.0.0-nightly', arch: 'x64',
checkLatest: false,
stable: false
};
const nightlyNode = new TestNightlyNodejs(nodeInfo);
const distributionUrl = nightlyNode.getDistributionUrlPublic();
expect(distributionUrl).toBe(mirrorURL);
expect(core.info).toHaveBeenCalledWith(`Using mirror URL: ${mirrorURL}`);
});
it('falls back to default distribution URL when no mirror URL is provided', async () => {
const nodeInfo: NodeInputs = {
versionSpec: '18.0.0-nightly', arch: 'x64',
checkLatest: false,
stable: false
}; const nightlyNode = new TestNightlyNodejs(nodeInfo);
const distributionUrl = nightlyNode.getDistributionUrlPublic();
expect(distributionUrl).toBe('https://nodejs.org/download/nightly');
expect(core.info).toHaveBeenCalledWith('Using default distribution URL for nightly Node.js.');
});
it('logs mirror URL when provided', async () => {
const mirrorURL = 'https://custom.mirror/nodejs/nightly';
const nodeInfo: NodeInputs = {
mirrorURL: '', versionSpec: '18.0.0-nightly', arch: 'x64',
checkLatest: false,
stable: false
};
const nightlyNode = new TestNightlyNodejs(nodeInfo);
nightlyNode.getDistributionUrlPublic();
expect(core.info).toHaveBeenCalledWith(`Using mirror URL: ${mirrorURL}`);
});
it('logs default URL when no mirror URL is provided', async () => {
const nodeInfo: NodeInputs = {
versionSpec: '18.0.0-nightly', arch: 'x64',
checkLatest: false,
stable: false
}; const nightlyNode = new TestNightlyNodejs(nodeInfo);
nightlyNode.getDistributionUrlPublic();
expect(core.info).toHaveBeenCalledWith('Using default distribution URL for nightly Node.js.');
});
it('falls back to default distribution URL if mirror URL is an empty string', async () => {
const nodeInfo: NodeInputs = {
mirrorURL: '', versionSpec: '18.0.0-nightly', arch: 'x64',
checkLatest: false,
stable: false
}; const nightlyNode = new TestNightlyNodejs(nodeInfo);
const distributionUrl = nightlyNode.getDistributionUrlPublic();
expect(distributionUrl).toBe('https://nodejs.org/download/nightly');
expect(core.info).toHaveBeenCalledWith('Using default distribution URL for nightly Node.js.');
});
it('falls back to default distribution URL if mirror URL is undefined', async () => {
const nodeInfo: NodeInputs = { nodeVersion: '18.0.0-nightly', architecture: 'x64', platform: 'linux' };
const nightlyNode = new TestNightlyNodejs(nodeInfo);
const distributionUrl = nightlyNode.getDistributionUrlPublic();
expect(distributionUrl).toBe('https://nodejs.org/download/nightly');
expect(core.info).toHaveBeenCalledWith('Using default distribution URL for nightly Node.js.');
});
});

View File

@ -829,3 +829,101 @@ describe('setup-node', () => {
); );
}); });
}); });
describe('OfficialBuilds - Mirror URL functionality', () => {
const nodeInfo: NodeInputs = { nodeVersion: '18.0.0-nightly', architecture: 'x64', platform: 'linux', mirrorURL: '' };
it('should download using the mirror URL when provided', async () => {
const mirrorURL = 'https://my.custom.mirror/nodejs';
nodeInfo.mirrorURL = mirrorURL;
const officialBuilds = new OfficialBuilds(nodeInfo);
// Mock download from mirror URL
const mockDownloadPath = '/some/temp/path';
jest.spyOn(tc, 'downloadTool').mockResolvedValue(mockDownloadPath);
await officialBuilds.setupNodeJs();
expect(core.info).toHaveBeenCalledWith('Attempting to download using mirror URL...');
expect(core.info).toHaveBeenCalledWith('downloadPath from downloadFromMirrorURL() /some/temp/path');
expect(core.addPath).toHaveBeenCalledWith(mockDownloadPath);
});
it('should log a message when mirror URL is used', async () => {
const mirrorURL = 'https://my.custom.mirror/nodejs';
nodeInfo.mirrorURL = mirrorURL;
const officialBuilds = new OfficialBuilds(nodeInfo);
const mockDownloadPath = '/some/temp/path';
jest.spyOn(tc, 'downloadTool').mockResolvedValue(mockDownloadPath);
await officialBuilds.setupNodeJs();
expect(core.info).toHaveBeenCalledWith(`Using mirror URL: ${mirrorURL}`);
});
it('should fall back to default URL if mirror URL is not provided', async () => {
nodeInfo.mirrorURL = ''; // No mirror URL provided
const officialBuilds = new OfficialBuilds(nodeInfo);
const mockDownloadPath = '/some/temp/path';
jest.spyOn(tc, 'downloadTool').mockResolvedValue(mockDownloadPath);
await officialBuilds.setupNodeJs();
expect(core.info).toHaveBeenCalledWith('Attempting to download from default Node.js URL...');
expect(core.addPath).toHaveBeenCalledWith(mockDownloadPath);
});
it('should log an error and handle failure during mirror URL download', async () => {
const mirrorURL = 'https://my.custom.mirror/nodejs';
nodeInfo.mirrorURL = mirrorURL;
const officialBuilds = new OfficialBuilds(nodeInfo);
// Simulate an error during the download process
const errorMessage = 'Network error';
jest.spyOn(tc, 'downloadTool').mockRejectedValue(new Error(errorMessage));
await officialBuilds.setupNodeJs();
expect(core.info).toHaveBeenCalledWith('Attempting to download using mirror URL...');
expect(core.error).toHaveBeenCalledWith(errorMessage);
expect(core.debug).toHaveBeenCalledWith(expect.stringContaining('empty stack'));
});
it('should log a fallback message if downloading from the mirror URL fails', async () => {
const mirrorURL = 'https://my.custom.mirror/nodejs';
nodeInfo.mirrorURL = mirrorURL;
const officialBuilds = new OfficialBuilds(nodeInfo);
// Simulate download failure and fallback to default URL
const errorMessage = 'Network error';
jest.spyOn(tc, 'downloadTool').mockRejectedValue(new Error(errorMessage));
const mockDownloadPath = '/some/temp/path';
jest.spyOn(tc, 'downloadTool').mockResolvedValue(mockDownloadPath);
await officialBuilds.setupNodeJs();
expect(core.info).toHaveBeenCalledWith('Failed to download from mirror URL. Falling back to default Node.js URL...');
expect(core.addPath).toHaveBeenCalledWith(mockDownloadPath);
});
it('should throw an error if mirror URL is not provided and downloading from both mirror and default fails', async () => {
nodeInfo.mirrorURL = ''; // No mirror URL
const officialBuilds = new OfficialBuilds(nodeInfo);
// Simulate failure in both mirror and default download
const errorMessage = 'Network error';
jest.spyOn(tc, 'downloadTool').mockRejectedValue(new Error(errorMessage));
await expect(officialBuilds.setupNodeJs()).rejects.toThrowError(new Error('Unable to find Node version for platform linux and architecture x64.'));
});
it('should throw an error if mirror URL is undefined and not provided', async () => {
nodeInfo.mirrorURL = undefined; // Undefined mirror URL
const officialBuilds = new OfficialBuilds(nodeInfo);
// Simulate a missing mirror URL scenario
await expect(officialBuilds.setupNodeJs()).rejects.toThrowError('Mirror URL is undefined');
});
});

132
dist/setup/index.js vendored
View File

@ -100154,6 +100154,14 @@ class BaseDistribution {
return response.result || []; return response.result || [];
}); });
} }
getMirrorUrlVersions() {
return __awaiter(this, void 0, void 0, function* () {
const initialUrl = this.getDistributionMirrorUrl();
const dataUrl = `${initialUrl}/index.json`;
const response = yield this.httpClient.getJson(dataUrl);
return response.result || [];
});
}
getNodejsDistInfo(version) { getNodejsDistInfo(version) {
const osArch = this.translateArchToDistUrl(this.nodeInfo.arch); const osArch = this.translateArchToDistUrl(this.nodeInfo.arch);
version = semver_1.default.clean(version) || ''; version = semver_1.default.clean(version) || '';
@ -100165,7 +100173,7 @@ class BaseDistribution {
? `${fileName}.zip` ? `${fileName}.zip`
: `${fileName}.7z` : `${fileName}.7z`
: `${fileName}.tar.gz`; : `${fileName}.tar.gz`;
const initialUrl = this.getDistributionUrl(); const initialUrl = this.getDistributionMirrorUrl();
const url = `${initialUrl}/v${version}/${urlFileName}`; const url = `${initialUrl}/v${version}/${urlFileName}`;
return { return {
downloadUrl: url, downloadUrl: url,
@ -100406,17 +100414,54 @@ exports.getNodejsDistribution = getNodejsDistribution;
"use strict"; "use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) { var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod }; return (mod && mod.__esModule) ? mod : { "default": mod };
}; };
Object.defineProperty(exports, "__esModule", ({ value: true })); Object.defineProperty(exports, "__esModule", ({ value: true }));
const base_distribution_prerelease_1 = __importDefault(__nccwpck_require__(957)); const base_distribution_prerelease_1 = __importDefault(__nccwpck_require__(957));
const core = __importStar(__nccwpck_require__(2186));
class NightlyNodejs extends base_distribution_prerelease_1.default { class NightlyNodejs extends base_distribution_prerelease_1.default {
constructor(nodeInfo) { constructor(nodeInfo) {
super(nodeInfo); super(nodeInfo);
this.distribution = 'nightly'; this.distribution = 'nightly';
} }
getDistributionMirrorUrl() {
// Implement the method to return the mirror URL or an empty string if not available
return this.nodeInfo.mirrorURL || '';
}
// Updated getDistributionUrl method to handle mirror URL or fallback
getDistributionUrl() { getDistributionUrl() {
// Check if mirrorUrl exists in the nodeInfo and return it if available
const mirrorUrl = this.nodeInfo.mirrorURL;
if (mirrorUrl) {
core.info(`Using mirror URL: ${mirrorUrl}`);
return mirrorUrl;
}
// Default to the official Node.js nightly distribution URL if no mirror URL is provided
core.info('Using default distribution URL for nightly Node.js.');
return 'https://nodejs.org/download/nightly'; return 'https://nodejs.org/download/nightly';
} }
} }
@ -100483,6 +100528,7 @@ class OfficialBuilds extends base_distribution_1.default {
try { try {
core.info(`Attempting to download using mirror URL...`); core.info(`Attempting to download using mirror URL...`);
downloadPath = yield this.downloadFromMirrorURL(); // Attempt to download from the mirror downloadPath = yield this.downloadFromMirrorURL(); // Attempt to download from the mirror
core.info('downloadPath from downloadFromMirrorURL() ' + downloadPath);
if (downloadPath) { if (downloadPath) {
toolPath = downloadPath; toolPath = downloadPath;
} }
@ -100603,6 +100649,13 @@ class OfficialBuilds extends base_distribution_1.default {
getDistributionUrl() { getDistributionUrl() {
return `https://nodejs.org/dist`; return `https://nodejs.org/dist`;
} }
getDistributionMirrorUrl() {
const mirrorURL = this.nodeInfo.mirrorURL;
if (!mirrorURL) {
throw new Error('Mirror URL is undefined');
}
return mirrorURL;
}
getManifest() { getManifest() {
core.debug('Getting manifest from actions/node-versions@main'); core.debug('Getting manifest from actions/node-versions@main');
return tc.getManifestFromRepo('actions', 'node-versions', this.nodeInfo.auth, 'main'); return tc.getManifestFromRepo('actions', 'node-versions', this.nodeInfo.auth, 'main');
@ -100670,17 +100723,9 @@ class OfficialBuilds extends base_distribution_1.default {
} }
downloadFromMirrorURL() { downloadFromMirrorURL() {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
const nodeJsVersions = yield this.getNodeJsVersions(); const nodeJsVersions = yield this.getMirrorUrlVersions();
core.info('versions from nodeJSVersions' + nodeJsVersions);
const versions = this.filterVersions(nodeJsVersions); const versions = this.filterVersions(nodeJsVersions);
core.info('versions' + versions);
const evaluatedVersion = this.evaluateVersions(versions); const evaluatedVersion = this.evaluateVersions(versions);
core.info('versionSpec' + this.nodeInfo.versionSpec);
if (this.nodeInfo.checkLatest) {
const evaluatedVersion = yield this.findVersionInDist(nodeJsVersions);
this.nodeInfo.versionSpec = evaluatedVersion;
core.info('versionSpec' + this.nodeInfo.versionSpec);
}
if (!evaluatedVersion) { if (!evaluatedVersion) {
throw new Error(`Unable to find Node version '${this.nodeInfo.versionSpec}' for platform ${this.osPlat} and architecture ${this.nodeInfo.arch}.`); throw new Error(`Unable to find Node version '${this.nodeInfo.versionSpec}' for platform ${this.osPlat} and architecture ${this.nodeInfo.arch}.`);
} }
@ -100714,11 +100759,35 @@ exports["default"] = OfficialBuilds;
"use strict"; "use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) { var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod }; return (mod && mod.__esModule) ? mod : { "default": mod };
}; };
Object.defineProperty(exports, "__esModule", ({ value: true })); Object.defineProperty(exports, "__esModule", ({ value: true }));
const base_distribution_1 = __importDefault(__nccwpck_require__(7)); const base_distribution_1 = __importDefault(__nccwpck_require__(7));
const core = __importStar(__nccwpck_require__(2186));
class RcBuild extends base_distribution_1.default { class RcBuild extends base_distribution_1.default {
constructor(nodeInfo) { constructor(nodeInfo) {
super(nodeInfo); super(nodeInfo);
@ -100726,6 +100795,16 @@ class RcBuild extends base_distribution_1.default {
getDistributionUrl() { getDistributionUrl() {
return 'https://nodejs.org/download/rc'; return 'https://nodejs.org/download/rc';
} }
getDistributionMirrorUrl() {
// Check if mirrorUrl exists in the nodeInfo and return it if available
const mirrorUrl = this.nodeInfo.mirrorURL;
if (mirrorUrl) {
core.info(`Using mirror URL: ${mirrorUrl}`);
return mirrorUrl;
}
// Return the default URL if no mirror URL is provided
return this.getDistributionUrl();
}
} }
exports["default"] = RcBuild; exports["default"] = RcBuild;
@ -100737,11 +100816,35 @@ exports["default"] = RcBuild;
"use strict"; "use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) { var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod }; return (mod && mod.__esModule) ? mod : { "default": mod };
}; };
Object.defineProperty(exports, "__esModule", ({ value: true })); Object.defineProperty(exports, "__esModule", ({ value: true }));
const base_distribution_prerelease_1 = __importDefault(__nccwpck_require__(957)); const base_distribution_prerelease_1 = __importDefault(__nccwpck_require__(957));
const core = __importStar(__nccwpck_require__(2186));
class CanaryBuild extends base_distribution_prerelease_1.default { class CanaryBuild extends base_distribution_prerelease_1.default {
constructor(nodeInfo) { constructor(nodeInfo) {
super(nodeInfo); super(nodeInfo);
@ -100750,6 +100853,15 @@ class CanaryBuild extends base_distribution_prerelease_1.default {
getDistributionUrl() { getDistributionUrl() {
return 'https://nodejs.org/download/v8-canary'; return 'https://nodejs.org/download/v8-canary';
} }
getDistributionMirrorUrl() {
// Check if mirrorUrl exists in the nodeInfo and return it if available
const mirrorUrl = this.nodeInfo.mirrorURL;
if (mirrorUrl) {
core.info(`Using mirror URL: ${mirrorUrl}`);
return mirrorUrl;
}
return 'https://nodejs.org/download/v8-canary';
}
} }
exports["default"] = CanaryBuild; exports["default"] = CanaryBuild;

View File

@ -25,7 +25,7 @@ export default abstract class BaseDistribution {
} }
protected abstract getDistributionUrl(): string; protected abstract getDistributionUrl(): string;
protected abstract getDistributionMirrorUrl(): string;
public async setupNodeJs() { public async setupNodeJs() {
let nodeJsVersions: INodeVersion[] | undefined; let nodeJsVersions: INodeVersion[] | undefined;
@ -105,6 +105,15 @@ export default abstract class BaseDistribution {
return response.result || []; return response.result || [];
} }
protected async getMirrorUrlVersions(): Promise<INodeVersion[]> {
const initialUrl = this.getDistributionMirrorUrl();
const dataUrl = `${initialUrl}/index.json`;
const response = await this.httpClient.getJson<INodeVersion[]>(dataUrl);
return response.result || [];
}
protected getNodejsDistInfo(version: string) { protected getNodejsDistInfo(version: string) {
const osArch: string = this.translateArchToDistUrl(this.nodeInfo.arch); const osArch: string = this.translateArchToDistUrl(this.nodeInfo.arch);
version = semver.clean(version) || ''; version = semver.clean(version) || '';
@ -118,7 +127,7 @@ export default abstract class BaseDistribution {
? `${fileName}.zip` ? `${fileName}.zip`
: `${fileName}.7z` : `${fileName}.7z`
: `${fileName}.tar.gz`; : `${fileName}.tar.gz`;
const initialUrl = this.getDistributionUrl(); const initialUrl = this.getDistributionMirrorUrl();
const url = `${initialUrl}/v${version}/${urlFileName}`; const url = `${initialUrl}/v${version}/${urlFileName}`;
return <INodeVersionInfo>{ return <INodeVersionInfo>{
@ -131,7 +140,9 @@ export default abstract class BaseDistribution {
protected getNodejsMirrorURLInfo(version: string) { protected getNodejsMirrorURLInfo(version: string) {
const mirrorURL = this.nodeInfo.mirrorURL; const mirrorURL = this.nodeInfo.mirrorURL;
const osArch: string = this.translateArchToDistUrl(this.nodeInfo.arch); const osArch: string = this.translateArchToDistUrl(this.nodeInfo.arch);
version = semver.clean(version) || ''; version = semver.clean(version) || '';
const fileName: string = const fileName: string =
this.osPlat == 'win32' this.osPlat == 'win32'
@ -173,7 +184,9 @@ export default abstract class BaseDistribution {
info.downloadUrl info.downloadUrl
); );
} }
core.error(`Download failed from ${info.downloadUrl}. Please check the URl and try again.`); core.error(
`Download failed from ${info.downloadUrl}. Please check the URl and try again.`
);
throw err; throw err;
} }
@ -195,7 +208,7 @@ export default abstract class BaseDistribution {
protected async acquireWindowsNodeFromFallbackLocation( protected async acquireWindowsNodeFromFallbackLocation(
version: string, version: string,
arch: string = os.arch(), arch: string = os.arch(),
downloadUrl : string downloadUrl: string
): Promise<string> { ): Promise<string> {
const initialUrl = this.getDistributionUrl(); const initialUrl = this.getDistributionUrl();
core.info('url: ' + initialUrl); core.info('url: ' + initialUrl);
@ -214,8 +227,12 @@ export default abstract class BaseDistribution {
libUrl = `${initialUrl}/v${version}/win-${osArch}/node.lib`; libUrl = `${initialUrl}/v${version}/win-${osArch}/node.lib`;
core.info(`Downloading only node binary from ${exeUrl}`); core.info(`Downloading only node binary from ${exeUrl}`);
if(downloadUrl != exeUrl ){core.error('unable to download node binary with the provided URL. Please check and try again');}
if (downloadUrl != exeUrl) {
core.error(
'unable to download node binary with the provided URL. Please check and try again'
);
}
const exePath = await tc.downloadTool(exeUrl); const exePath = await tc.downloadTool(exeUrl);
await io.cp(exePath, path.join(tempDir, 'node.exe')); await io.cp(exePath, path.join(tempDir, 'node.exe'));

View File

@ -4,7 +4,7 @@ export interface NodeInputs {
auth?: string; auth?: string;
checkLatest: boolean; checkLatest: boolean;
stable: boolean; stable: boolean;
mirrorURL: string; mirrorURL?: string;
} }
export interface INodeVersionInfo { export interface INodeVersionInfo {
@ -12,7 +12,6 @@ export interface INodeVersionInfo {
resolvedVersion: string; resolvedVersion: string;
arch: string; arch: string;
fileName: string; fileName: string;
} }
export interface INodeVersion { export interface INodeVersion {

View File

@ -1,13 +1,31 @@
import BasePrereleaseNodejs from '../base-distribution-prerelease'; import BasePrereleaseNodejs from '../base-distribution-prerelease';
import {NodeInputs} from '../base-models'; import {NodeInputs} from '../base-models';
import * as core from '@actions/core';
export default class NightlyNodejs extends BasePrereleaseNodejs { export default class NightlyNodejs extends BasePrereleaseNodejs {
protected distribution = 'nightly'; protected distribution = 'nightly';
constructor(nodeInfo: NodeInputs) { constructor(nodeInfo: NodeInputs) {
super(nodeInfo); super(nodeInfo);
} }
protected getDistributionMirrorUrl(): string {
// Implement the method to return the mirror URL or an empty string if not available
return this.nodeInfo.mirrorURL || '';
}
// Updated getDistributionUrl method to handle mirror URL or fallback
protected getDistributionUrl(): string { protected getDistributionUrl(): string {
// Check if mirrorUrl exists in the nodeInfo and return it if available
const mirrorUrl = this.nodeInfo.mirrorURL;
if (mirrorUrl) {
core.info(`Using mirror URL: ${mirrorUrl}`);
return mirrorUrl;
}
// Default to the official Node.js nightly distribution URL if no mirror URL is provided
core.info('Using default distribution URL for nightly Node.js.');
return 'https://nodejs.org/download/nightly'; return 'https://nodejs.org/download/nightly';
} }
} }

View File

@ -12,139 +12,135 @@ interface INodeRelease extends tc.IToolRelease {
export default class OfficialBuilds extends BaseDistribution { export default class OfficialBuilds extends BaseDistribution {
constructor(nodeInfo: NodeInputs) { constructor(nodeInfo: NodeInputs) {
super(nodeInfo); super(nodeInfo);
} }
public async setupNodeJs() { public async setupNodeJs() {
if(this.nodeInfo.mirrorURL){ if (this.nodeInfo.mirrorURL) {
let downloadPath = ''; let downloadPath = '';
let toolPath = ''; let toolPath = '';
try { try {
core.info(`Attempting to download using mirror URL...`); core.info(`Attempting to download using mirror URL...`);
downloadPath = await this.downloadFromMirrorURL(); // Attempt to download from the mirror downloadPath = await this.downloadFromMirrorURL(); // Attempt to download from the mirror
if (downloadPath) { core.info('downloadPath from downloadFromMirrorURL() '+ downloadPath);
toolPath = downloadPath; if (downloadPath) {
} toolPath = downloadPath;
} catch (err) { }
core.info((err as Error).message); } catch (err) {
core.debug((err as Error).stack ?? 'empty stack'); core.info((err as Error).message);
} core.debug((err as Error).stack ?? 'empty stack');
}
} else {
let manifest: tc.IToolRelease[] | undefined;
let nodeJsVersions: INodeVersion[] | undefined;
const osArch = this.translateArchToDistUrl(this.nodeInfo.arch);
}else{ if (this.isLtsAlias(this.nodeInfo.versionSpec)) {
let manifest: tc.IToolRelease[] | undefined; core.info('Attempt to resolve LTS alias from manifest...');
let nodeJsVersions: INodeVersion[] | undefined;
const osArch = this.translateArchToDistUrl(this.nodeInfo.arch);
if (this.isLtsAlias(this.nodeInfo.versionSpec)) { // No try-catch since it's not possible to resolve LTS alias without manifest
core.info('Attempt to resolve LTS alias from manifest...'); manifest = await this.getManifest();
// No try-catch since it's not possible to resolve LTS alias without manifest this.nodeInfo.versionSpec = this.resolveLtsAliasFromManifest(
manifest = await this.getManifest(); this.nodeInfo.versionSpec,
this.nodeInfo.stable,
this.nodeInfo.versionSpec = this.resolveLtsAliasFromManifest( manifest
this.nodeInfo.versionSpec,
this.nodeInfo.stable,
manifest
);
}
if (this.isLatestSyntax(this.nodeInfo.versionSpec)) {
nodeJsVersions = await this.getNodeJsVersions();
const versions = this.filterVersions(nodeJsVersions);
this.nodeInfo.versionSpec = this.evaluateVersions(versions);
core.info('getting latest node version...');
}
if (this.nodeInfo.checkLatest) {
core.info('Attempt to resolve the latest version from manifest...');
const resolvedVersion = await this.resolveVersionFromManifest(
this.nodeInfo.versionSpec,
this.nodeInfo.stable,
osArch,
manifest
);
if (resolvedVersion) {
this.nodeInfo.versionSpec = resolvedVersion;
core.info(`Resolved as '${resolvedVersion}'`);
} else {
core.info(
`Failed to resolve version ${this.nodeInfo.versionSpec} from manifest`
); );
} }
}
let toolPath = this.findVersionInHostedToolCacheDirectory(); if (this.isLatestSyntax(this.nodeInfo.versionSpec)) {
nodeJsVersions = await this.getNodeJsVersions();
const versions = this.filterVersions(nodeJsVersions);
this.nodeInfo.versionSpec = this.evaluateVersions(versions);
if (toolPath) { core.info('getting latest node version...');
core.info(`Found in cache @ ${toolPath}`); }
this.addToolPath(toolPath);
return;
}
let downloadPath = ''; if (this.nodeInfo.checkLatest) {
try { core.info('Attempt to resolve the latest version from manifest...');
core.info(`Attempting to download ${this.nodeInfo.versionSpec}...`); const resolvedVersion = await this.resolveVersionFromManifest(
this.nodeInfo.versionSpec,
const versionInfo = await this.getInfoFromManifest( this.nodeInfo.stable,
this.nodeInfo.versionSpec, osArch,
this.nodeInfo.stable, manifest
osArch,
manifest
);
if (versionInfo) {
core.info(
`Acquiring ${versionInfo.resolvedVersion} - ${versionInfo.arch} from ${versionInfo.downloadUrl}`
); );
downloadPath = await tc.downloadTool( if (resolvedVersion) {
versionInfo.downloadUrl, this.nodeInfo.versionSpec = resolvedVersion;
undefined, core.info(`Resolved as '${resolvedVersion}'`);
this.nodeInfo.auth } else {
); core.info(
`Failed to resolve version ${this.nodeInfo.versionSpec} from manifest`
if (downloadPath) {
toolPath = await this.extractArchive(
downloadPath,
versionInfo,
false
); );
} }
} else {
core.info(
'Not found in manifest. Falling back to download directly from Node'
);
} }
} catch (err) {
// Rate limit? let toolPath = this.findVersionInHostedToolCacheDirectory();
if (
err instanceof tc.HTTPError && if (toolPath) {
(err.httpStatusCode === 403 || err.httpStatusCode === 429) core.info(`Found in cache @ ${toolPath}`);
) { this.addToolPath(toolPath);
core.info( return;
`Received HTTP status code ${err.httpStatusCode}. This usually indicates the rate limit has been exceeded`
);
} else {
core.info((err as Error).message);
} }
core.debug((err as Error).stack ?? 'empty stack');
core.info('Falling back to download directly from Node');
}
if (!toolPath) { let downloadPath = '';
toolPath = await this.downloadDirectlyFromNode(); try {
} core.info(`Attempting to download ${this.nodeInfo.versionSpec}...`);
if (this.osPlat != 'win32') { const versionInfo = await this.getInfoFromManifest(
toolPath = path.join(toolPath, 'bin'); this.nodeInfo.versionSpec,
} this.nodeInfo.stable,
osArch,
manifest
);
core.addPath(toolPath); if (versionInfo) {
core.info(
`Acquiring ${versionInfo.resolvedVersion} - ${versionInfo.arch} from ${versionInfo.downloadUrl}`
);
downloadPath = await tc.downloadTool(
versionInfo.downloadUrl,
undefined,
this.nodeInfo.auth
);
if (downloadPath) {
toolPath = await this.extractArchive(
downloadPath,
versionInfo,
false
);
}
} else {
core.info(
'Not found in manifest. Falling back to download directly from Node'
);
}
} catch (err) {
// Rate limit?
if (
err instanceof tc.HTTPError &&
(err.httpStatusCode === 403 || err.httpStatusCode === 429)
) {
core.info(
`Received HTTP status code ${err.httpStatusCode}. This usually indicates the rate limit has been exceeded`
);
} else {
core.info((err as Error).message);
}
core.debug((err as Error).stack ?? 'empty stack');
core.info('Falling back to download directly from Node');
}
if (!toolPath) {
toolPath = await this.downloadDirectlyFromNode();
}
if (this.osPlat != 'win32') {
toolPath = path.join(toolPath, 'bin');
}
core.addPath(toolPath);
}
} }
}
protected addToolPath(toolPath: string) { protected addToolPath(toolPath: string) {
if (this.osPlat != 'win32') { if (this.osPlat != 'win32') {
@ -200,6 +196,13 @@ export default class OfficialBuilds extends BaseDistribution {
return `https://nodejs.org/dist`; return `https://nodejs.org/dist`;
} }
protected getDistributionMirrorUrl(): string {
const mirrorURL = this.nodeInfo.mirrorURL;
if (!mirrorURL) {
throw new Error('Mirror URL is undefined');
}
return mirrorURL;
}
private getManifest(): Promise<tc.IToolRelease[]> { private getManifest(): Promise<tc.IToolRelease[]> {
core.debug('Getting manifest from actions/node-versions@main'); core.debug('Getting manifest from actions/node-versions@main');
@ -314,20 +317,13 @@ export default class OfficialBuilds extends BaseDistribution {
} }
protected async downloadFromMirrorURL() { protected async downloadFromMirrorURL() {
const nodeJsVersions = await this.getNodeJsVersions(); const nodeJsVersions = await this.getMirrorUrlVersions();
core.info('versions from nodeJSVersions'+nodeJsVersions);
const versions = this.filterVersions(nodeJsVersions); const versions = this.filterVersions(nodeJsVersions);
core.info('versions'+versions);
const evaluatedVersion = this.evaluateVersions(versions); const evaluatedVersion = this.evaluateVersions(versions);
core.info('versionSpec'+this.nodeInfo.versionSpec);
if (this.nodeInfo.checkLatest) {
const evaluatedVersion = await this.findVersionInDist(nodeJsVersions);
this.nodeInfo.versionSpec = evaluatedVersion;
core.info('versionSpec'+this.nodeInfo.versionSpec);
}
if (!evaluatedVersion) { if (!evaluatedVersion) {
throw new Error( throw new Error(
@ -337,15 +333,18 @@ export default class OfficialBuilds extends BaseDistribution {
const toolName = this.getNodejsMirrorURLInfo(evaluatedVersion); const toolName = this.getNodejsMirrorURLInfo(evaluatedVersion);
try { try {
const toolPath = await this.downloadNodejs(toolName); const toolPath = await this.downloadNodejs(toolName);
return toolPath; return toolPath;
} catch (error) { } catch (error) {
if (error instanceof tc.HTTPError && error.httpStatusCode === 404) { if (error instanceof tc.HTTPError && error.httpStatusCode === 404) {
core.error( core.error(
`Node version ${this.nodeInfo.versionSpec} for platform ${this.osPlat} and architecture ${this.nodeInfo.arch} was found but failed to download. ` + `Node version ${this.nodeInfo.versionSpec} for platform ${this.osPlat} and architecture ${this.nodeInfo.arch} was found but failed to download. ` +
'This usually happens when downloadable binaries are not fully updated at https://nodejs.org/. ' + 'This usually happens when downloadable binaries are not fully updated at https://nodejs.org/. ' +
'To resolve this issue you may either fall back to the older version or try again later.' 'To resolve this issue you may either fall back to the older version or try again later.'
); );
} else { } else {
// For any other error type, you can log the error message. // For any other error type, you can log the error message.
@ -355,5 +354,4 @@ export default class OfficialBuilds extends BaseDistribution {
throw error; throw error;
} }
} }
} }

View File

@ -1,7 +1,9 @@
import BaseDistribution from '../base-distribution'; import BaseDistribution from '../base-distribution';
import {NodeInputs} from '../base-models'; import {NodeInputs} from '../base-models';
import * as core from '@actions/core';
export default class RcBuild extends BaseDistribution { export default class RcBuild extends BaseDistribution {
constructor(nodeInfo: NodeInputs) { constructor(nodeInfo: NodeInputs) {
super(nodeInfo); super(nodeInfo);
} }
@ -9,4 +11,16 @@ export default class RcBuild extends BaseDistribution {
getDistributionUrl(): string { getDistributionUrl(): string {
return 'https://nodejs.org/download/rc'; return 'https://nodejs.org/download/rc';
} }
protected getDistributionMirrorUrl(): string {
// Check if mirrorUrl exists in the nodeInfo and return it if available
const mirrorUrl = this.nodeInfo.mirrorURL;
if (mirrorUrl) {
core.info(`Using mirror URL: ${mirrorUrl}`);
return mirrorUrl;
}
// Return the default URL if no mirror URL is provided
return this.getDistributionUrl();
}
} }

View File

@ -1,7 +1,8 @@
import BasePrereleaseNodejs from '../base-distribution-prerelease'; import BasePrereleaseNodejs from '../base-distribution-prerelease';
import {NodeInputs} from '../base-models'; import {NodeInputs} from '../base-models';
import * as core from '@actions/core';
export default class CanaryBuild extends BasePrereleaseNodejs { export default class CanaryBuild extends BasePrereleaseNodejs {
protected distribution = 'v8-canary'; protected distribution = 'v8-canary';
constructor(nodeInfo: NodeInputs) { constructor(nodeInfo: NodeInputs) {
super(nodeInfo); super(nodeInfo);
@ -10,4 +11,14 @@ export default class CanaryBuild extends BasePrereleaseNodejs {
protected getDistributionUrl(): string { protected getDistributionUrl(): string {
return 'https://nodejs.org/download/v8-canary'; return 'https://nodejs.org/download/v8-canary';
} }
protected getDistributionMirrorUrl(): string {
// Check if mirrorUrl exists in the nodeInfo and return it if available
const mirrorUrl = this.nodeInfo.mirrorURL;
if (mirrorUrl) {
core.info(`Using mirror URL: ${mirrorUrl}`);
return mirrorUrl;
}
return 'https://nodejs.org/download/v8-canary';
}
} }

View File

@ -35,7 +35,6 @@ export async function run() {
const mirrorURL = core.getInput('mirror-url').trim(); // .trim() to remove any accidental spaces const mirrorURL = core.getInput('mirror-url').trim(); // .trim() to remove any accidental spaces
if (version) { if (version) {
const token = core.getInput('token'); const token = core.getInput('token');
const auth = !token ? undefined : `token ${token}`; const auth = !token ? undefined : `token ${token}`;