Compare commits

...

4 Commits
v4 ... main

Author SHA1 Message Date
aparnajyothi-y
49933ea528
Bump @action/cache from 4.0.2 to 4.0.3 (#1262)
Some checks are pending
versions / version-file-volta (ubuntu-latest) (push) Waiting to run
versions / version-file-volta (windows-latest) (push) Waiting to run
versions / version-file-volta-extends (macos-13) (push) Waiting to run
versions / version-file-volta-extends (macos-latest) (push) Waiting to run
versions / version-file-volta-extends (ubuntu-latest) (push) Waiting to run
versions / version-file-volta-extends (windows-latest) (push) Waiting to run
versions / node-dist (17, macos-13) (push) Waiting to run
versions / node-dist (17, macos-latest) (push) Waiting to run
versions / node-dist (17, ubuntu-latest) (push) Waiting to run
versions / node-dist (17, windows-latest) (push) Waiting to run
versions / node-dist (19, macos-13) (push) Waiting to run
versions / node-dist (19, macos-latest) (push) Waiting to run
versions / node-dist (19, ubuntu-latest) (push) Waiting to run
versions / node-dist (19, windows-latest) (push) Waiting to run
versions / old-versions (macos-13) (push) Waiting to run
versions / old-versions (ubuntu-latest) (push) Waiting to run
versions / old-versions (windows-latest) (push) Waiting to run
versions / arch (push) Waiting to run
versions / node-latest-aliases (current, macos-13) (push) Waiting to run
versions / node-latest-aliases (current, macos-latest) (push) Waiting to run
versions / node-latest-aliases (current, ubuntu-latest) (push) Waiting to run
versions / node-latest-aliases (current, windows-latest) (push) Waiting to run
versions / node-latest-aliases (latest, macos-13) (push) Waiting to run
versions / node-latest-aliases (latest, macos-latest) (push) Waiting to run
versions / node-latest-aliases (latest, ubuntu-latest) (push) Waiting to run
versions / node-latest-aliases (latest, windows-latest) (push) Waiting to run
versions / node-latest-aliases (node, macos-13) (push) Waiting to run
versions / node-latest-aliases (node, macos-latest) (push) Waiting to run
versions / node-latest-aliases (node, ubuntu-latest) (push) Waiting to run
versions / node-latest-aliases (node, windows-latest) (push) Waiting to run
* Update versions.yml

* Update versions.yml

* actions/cache upgrade to 4.0.3

* events update

* npm audit fix revert

* npm adit fix revert
2025-04-02 14:20:51 -05:00
Marco Ippolito
e3ce749e20
feat: support private mirrors (#1240)
* feat: support private mirrors

* chore: change fallback message with mirrors
2025-04-02 10:49:47 -05:00
fregante
40337cb8f7
Add support for indented eslint output (#1245)
Some checks failed
versions / version-file-volta (windows-latest) (push) Has been cancelled
versions / version-file-volta-extends (macos-13) (push) Has been cancelled
versions / version-file-volta-extends (macos-latest) (push) Has been cancelled
versions / version-file-volta-extends (ubuntu-latest) (push) Has been cancelled
versions / version-file-volta-extends (windows-latest) (push) Has been cancelled
versions / node-dist (17, macos-13) (push) Has been cancelled
versions / node-dist (17, macos-latest) (push) Has been cancelled
versions / node-dist (17, ubuntu-latest) (push) Has been cancelled
versions / node-dist (17, windows-latest) (push) Has been cancelled
versions / node-dist (19, macos-13) (push) Has been cancelled
versions / node-dist (19, macos-latest) (push) Has been cancelled
versions / node-dist (19, ubuntu-latest) (push) Has been cancelled
versions / node-dist (19, windows-latest) (push) Has been cancelled
versions / old-versions (macos-13) (push) Has been cancelled
versions / old-versions (ubuntu-latest) (push) Has been cancelled
versions / old-versions (windows-latest) (push) Has been cancelled
versions / arch (push) Has been cancelled
versions / node-latest-aliases (current, macos-13) (push) Has been cancelled
versions / node-latest-aliases (current, macos-latest) (push) Has been cancelled
versions / node-latest-aliases (current, ubuntu-latest) (push) Has been cancelled
versions / node-latest-aliases (current, windows-latest) (push) Has been cancelled
versions / node-latest-aliases (latest, macos-13) (push) Has been cancelled
versions / node-latest-aliases (latest, macos-latest) (push) Has been cancelled
versions / node-latest-aliases (latest, ubuntu-latest) (push) Has been cancelled
versions / node-latest-aliases (latest, windows-latest) (push) Has been cancelled
versions / node-latest-aliases (node, macos-13) (push) Has been cancelled
versions / node-latest-aliases (node, macos-latest) (push) Has been cancelled
versions / node-latest-aliases (node, ubuntu-latest) (push) Has been cancelled
versions / node-latest-aliases (node, windows-latest) (push) Has been cancelled
Update configuration files / Update configuration files (push) Has been cancelled
2025-03-24 16:12:02 -05:00
Flo Edelmann
1ccdddc9b8
Make eslint-compact matcher compatible with Stylelint (#98) 2025-03-24 12:48:16 -05:00
31 changed files with 564 additions and 260 deletions

View File

@ -4,7 +4,7 @@
"owner": "eslint-compact",
"pattern": [
{
"regexp": "^(.+):\\sline\\s(\\d+),\\scol\\s(\\d+),\\s(Error|Warning|Info)\\s-\\s(.+)\\s\\((.+)\\)$",
"regexp": "^(.+):\\sline\\s(\\d+),\\scol\\s(\\d+),\\s([Ee]rror|[Ww]arning|[Ii]nfo)\\s-\\s(.+)\\s\\((.+)\\)$",
"file": 1,
"line": 2,
"column": 3,

View File

@ -4,7 +4,7 @@
"owner": "eslint-stylish",
"pattern": [
{
"regexp": "^([^\\s].*)$",
"regexp": "^\\s*([^\\s].*)$",
"file": 1
},
{

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -76,6 +76,21 @@ See [action.yml](action.yml)
# Set always-auth option in npmrc file.
# Default: ''
always-auth: ''
# Optional mirror to download binaries from.
# Artifacts need to match the official Node.js
# Example:
# V8 Canaray Build: <mirror_url>/download/v8-canary
# RC Build: <mirror_url>/download/rc
# Official: Build <mirror_url>/dist
# Nightly build: <mirror_url>/download/nightly
# Default: ''
mirror: ''
# Optional mirror token.
# The token will be used as a bearer token in the Authorization header
# Default: ''
mirror-token: ''
```
<!-- end usage -->

View File

@ -498,6 +498,70 @@ describe('setup-node', () => {
);
}
);
it.each([
[
'20.0.0-v8-canary',
'20.0.0-v8-canary20221103f7e2421e91',
'20.0.0-v8-canary20221030fefe1c0879',
'https://my_mirror.org/download/v8-canary/v20.0.0-v8-canary20221103f7e2421e91/node-v20.0.0-v8-canary20221103f7e2421e91-linux-x64.tar.gz'
],
[
'20-v8-canary',
'20.0.0-v8-canary20221103f7e2421e91',
'20.0.0-v8-canary20221030fefe1c0879',
'https://my_mirror.org/download/v8-canary/v20.0.0-v8-canary20221103f7e2421e91/node-v20.0.0-v8-canary20221103f7e2421e91-linux-x64.tar.gz'
],
[
'19.0.0-v8-canary',
'19.0.0-v8-canary202210187d6960f23f',
'19.0.0-v8-canary202210172ec229fc56',
'https://my_mirror.org/download/v8-canary/v19.0.0-v8-canary202210187d6960f23f/node-v19.0.0-v8-canary202210187d6960f23f-linux-x64.tar.gz'
],
[
'19-v8-canary',
'19.0.0-v8-canary202210187d6960f23f',
'19.0.0-v8-canary202210172ec229fc56',
'https://my_mirror.org/download/v8-canary/v19.0.0-v8-canary202210187d6960f23f/node-v19.0.0-v8-canary202210187d6960f23f-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';
inputs['mirror'] = 'https://my_mirror.org';
inputs['mirror-token'] = 'faketoken';
findSpy.mockReturnValue(foundToolPath);
findAllVersionsSpy.mockReturnValue([
'20.0.0-v8-canary20221030fefe1c0879',
'19.0.0-v8-canary202210172ec229fc56',
'20.0.0-v8-canary2022102310ff1e5a8d'
]);
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('setup-node v8 canary tests', () => {

View File

@ -315,7 +315,7 @@ describe('setup-node', () => {
await main.run();
workingUrls.forEach(url => {
expect(dlSpy).toHaveBeenCalledWith(url);
expect(dlSpy).toHaveBeenCalledWith(url, undefined, undefined);
});
expect(cnSpy).toHaveBeenCalledWith(`::add-path::${toolPath}${osm.EOL}`);
});
@ -449,6 +449,54 @@ describe('setup-node', () => {
}
}, 100000);
it('acquires specified architecture of node from mirror', async () => {
for (const {arch, version, osSpec} of [
{
arch: 'x86',
version: '18.0.0-nightly202110204cb3e06ed8',
osSpec: 'win32'
},
{
arch: 'x86',
version: '20.0.0-nightly2022101987cdf7d412',
osSpec: 'win32'
}
]) {
os.platform = osSpec;
os.arch = arch;
const fileExtension = os.platform === 'win32' ? '7z' : 'tar.gz';
const platform = {
linux: 'linux',
darwin: 'darwin',
win32: 'win'
}[os.platform];
inputs['node-version'] = version;
inputs['architecture'] = arch;
inputs['always-auth'] = false;
inputs['token'] = 'faketoken';
inputs['mirror'] = 'https://my-mirror.org';
inputs['mirror-token'] = 'my-mirror-token';
const expectedUrl = `https://my-mirror.org/download/nightly/v${version}/node-v${version}-${platform}-${arch}.${fileExtension}`;
// ... but not in the local cache
findSpy.mockImplementation(() => '');
findAllVersionsSpy.mockImplementation(() => []);
dlSpy.mockImplementation(async () => '/some/temp/path');
const toolPath = path.normalize(`/cache/node/${version}/${arch}`);
exSpy.mockImplementation(async () => '/some/other/temp/path');
cacheSpy.mockImplementation(async () => toolPath);
await main.run();
expect(dlSpy).toHaveBeenCalled();
expect(logSpy).toHaveBeenCalledWith(
`Acquiring ${version} - ${arch} from ${expectedUrl}`
);
}
}, 100000);
describe('nightly versions', () => {
it.each([
[

View File

@ -282,6 +282,43 @@ describe('setup-node', () => {
expect(cnSpy).toHaveBeenCalledWith(`::add-path::${expPath}${osm.EOL}`);
});
it('falls back to a version from node dist from mirror', async () => {
os.platform = 'linux';
os.arch = 'x64';
// a version which is not in the manifest but is in node dist
const versionSpec = '11.15.0';
const mirror = 'https://my_mirror_url';
inputs['node-version'] = versionSpec;
inputs['always-auth'] = false;
inputs['token'] = 'faketoken';
inputs['mirror'] = mirror;
inputs['mirror-token'] = 'faketoken';
// ... but not in the local cache
findSpy.mockImplementation(() => '');
dlSpy.mockImplementation(async () => '/some/temp/path');
const toolPath = path.normalize('/cache/node/11.15.0/x64');
exSpy.mockImplementation(async () => '/some/other/temp/path');
cacheSpy.mockImplementation(async () => toolPath);
await main.run();
const expPath = path.join(toolPath, 'bin');
expect(getManifestSpy).toHaveBeenCalled();
expect(logSpy).toHaveBeenCalledWith(
`Attempting to download ${versionSpec}...`
);
expect(logSpy).toHaveBeenCalledWith(
`Not found in manifest. Falling back to download directly from ${mirror}`
);
expect(dlSpy).toHaveBeenCalled();
expect(exSpy).toHaveBeenCalled();
expect(cnSpy).toHaveBeenCalledWith(`::add-path::${expPath}${osm.EOL}`);
});
it('falls back to a version from node dist', async () => {
os.platform = 'linux';
os.arch = 'x64';
@ -828,4 +865,46 @@ describe('setup-node', () => {
}
);
});
it('acquires specified architecture of node from mirror', async () => {
for (const {arch, version, osSpec} of [
{arch: 'x86', version: '12.16.2', osSpec: 'win32'},
{arch: 'x86', version: '14.0.0', osSpec: 'win32'}
]) {
os.platform = osSpec;
os.arch = arch;
const fileExtension = os.platform === 'win32' ? '7z' : 'tar.gz';
const platform = {
linux: 'linux',
darwin: 'darwin',
win32: 'win'
}[os.platform];
inputs['node-version'] = version;
inputs['architecture'] = arch;
inputs['always-auth'] = false;
inputs['token'] = 'faketoken';
inputs['mirror'] = 'https://my_mirror_url';
inputs['mirror-token'] = 'faketoken';
const expectedUrl =
arch === 'x64'
? `https://github.com/actions/node-versions/releases/download/${version}/node-${version}-${platform}-${arch}.zip`
: `https://my_mirror_url/dist/v${version}/node-v${version}-${platform}-${arch}.${fileExtension}`;
// ... but not in the local cache
findSpy.mockImplementation(() => '');
dlSpy.mockImplementation(async () => '/some/temp/path');
const toolPath = path.normalize(`/cache/node/${version}/${arch}`);
exSpy.mockImplementation(async () => '/some/other/temp/path');
cacheSpy.mockImplementation(async () => toolPath);
await main.run();
expect(dlSpy).toHaveBeenCalled();
expect(logSpy).toHaveBeenCalledWith(
`Acquiring ${version} - ${arch} from ${expectedUrl}`
);
}
}, 100000);
});

View File

@ -25,6 +25,10 @@ inputs:
description: 'Used to specify a package manager for caching in the default directory. Supported values: npm, yarn, pnpm.'
cache-dependency-path:
description: 'Used to specify the path to a dependency file: package-lock.json, yarn.lock, etc. Supports wildcards or a list of file names for caching multiple dependencies.'
mirror:
description: 'Used to specify an alternative mirror to downlooad Node.js binaries from'
mirror-token:
description: 'The token used as Authorization header when fetching from the mirror'
# TODO: add input to control forcing to pull from cloud or dist.
# escape valve for someone having issues or needing the absolute latest which isn't cached yet
outputs:

View File

@ -220,7 +220,7 @@ function restoreCacheV2(paths, primaryKey, restoreKeys, options, enableCrossOsAr
};
const response = yield twirpClient.GetCacheEntryDownloadURL(request);
if (!response.ok) {
core.debug(`Cache not found for keys: ${keys.join(', ')}`);
core.debug(`Cache not found for version ${request.version} of keys: ${keys.join(', ')}`);
return undefined;
}
core.info(`Cache hit for: ${request.key}`);
@ -2204,6 +2204,7 @@ const cacheUtils_1 = __nccwpck_require__(680);
const auth_1 = __nccwpck_require__(4552);
const http_client_1 = __nccwpck_require__(4844);
const cache_twirp_client_1 = __nccwpck_require__(1486);
const util_1 = __nccwpck_require__(7564);
/**
* This class is a wrapper around the CacheServiceClientJSON class generated by Twirp.
*
@ -2263,6 +2264,7 @@ class CacheServiceClient {
(0, core_1.debug)(`[Response] - ${response.message.statusCode}`);
(0, core_1.debug)(`Headers: ${JSON.stringify(response.message.headers, null, 2)}`);
const body = JSON.parse(rawBody);
(0, util_1.maskSecretUrls)(body);
(0, core_1.debug)(`Body: ${JSON.stringify(body, null, 2)}`);
if (this.isSuccessStatusCode(statusCode)) {
return { response, body };
@ -2444,6 +2446,87 @@ exports.getUserAgentString = getUserAgentString;
/***/ }),
/***/ 7564:
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.maskSecretUrls = exports.maskSigUrl = void 0;
const core_1 = __nccwpck_require__(7484);
/**
* Masks the `sig` parameter in a URL and sets it as a secret.
*
* @param url - The URL containing the signature parameter to mask
* @remarks
* This function attempts to parse the provided URL and identify the 'sig' query parameter.
* If found, it registers both the raw and URL-encoded signature values as secrets using
* the Actions `setSecret` API, which prevents them from being displayed in logs.
*
* The function handles errors gracefully if URL parsing fails, logging them as debug messages.
*
* @example
* ```typescript
* // Mask a signature in an Azure SAS token URL
* maskSigUrl('https://example.blob.core.windows.net/container/file.txt?sig=abc123&se=2023-01-01');
* ```
*/
function maskSigUrl(url) {
if (!url)
return;
try {
const parsedUrl = new URL(url);
const signature = parsedUrl.searchParams.get('sig');
if (signature) {
(0, core_1.setSecret)(signature);
(0, core_1.setSecret)(encodeURIComponent(signature));
}
}
catch (error) {
(0, core_1.debug)(`Failed to parse URL: ${url} ${error instanceof Error ? error.message : String(error)}`);
}
}
exports.maskSigUrl = maskSigUrl;
/**
* Masks sensitive information in URLs containing signature parameters.
* Currently supports masking 'sig' parameters in the 'signed_upload_url'
* and 'signed_download_url' properties of the provided object.
*
* @param body - The object should contain a signature
* @remarks
* This function extracts URLs from the object properties and calls maskSigUrl
* on each one to redact sensitive signature information. The function doesn't
* modify the original object; it only marks the signatures as secrets for
* logging purposes.
*
* @example
* ```typescript
* const responseBody = {
* signed_upload_url: 'https://blob.core.windows.net/?sig=abc123',
* signed_download_url: 'https://blob.core/windows.net/?sig=def456'
* };
* maskSecretUrls(responseBody);
* ```
*/
function maskSecretUrls(body) {
if (typeof body !== 'object' || body === null) {
(0, core_1.debug)('body is not an object or is null');
return;
}
if ('signed_upload_url' in body &&
typeof body.signed_upload_url === 'string') {
maskSigUrl(body.signed_upload_url);
}
if ('signed_download_url' in body &&
typeof body.signed_download_url === 'string') {
maskSigUrl(body.signed_download_url);
}
}
exports.maskSecretUrls = maskSecretUrls;
//# sourceMappingURL=util.js.map
/***/ }),
/***/ 5321:
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
@ -90234,7 +90317,7 @@ module.exports = parseParams
/***/ ((module) => {
"use strict";
module.exports = /*#__PURE__*/JSON.parse('{"name":"@actions/cache","version":"4.0.2","preview":true,"description":"Actions cache lib","keywords":["github","actions","cache"],"homepage":"https://github.com/actions/toolkit/tree/main/packages/cache","license":"MIT","main":"lib/cache.js","types":"lib/cache.d.ts","directories":{"lib":"lib","test":"__tests__"},"files":["lib","!.DS_Store"],"publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/actions/toolkit.git","directory":"packages/cache"},"scripts":{"audit-moderate":"npm install && npm audit --json --audit-level=moderate > audit.json","test":"echo \\"Error: run tests from root\\" && exit 1","tsc":"tsc"},"bugs":{"url":"https://github.com/actions/toolkit/issues"},"dependencies":{"@actions/core":"^1.11.1","@actions/exec":"^1.0.1","@actions/glob":"^0.1.0","@actions/http-client":"^2.1.1","@actions/io":"^1.0.1","@azure/abort-controller":"^1.1.0","@azure/ms-rest-js":"^2.6.0","@azure/storage-blob":"^12.13.0","@protobuf-ts/plugin":"^2.9.4","semver":"^6.3.1"},"devDependencies":{"@types/semver":"^6.0.0","typescript":"^5.2.2"}}');
module.exports = /*#__PURE__*/JSON.parse('{"name":"@actions/cache","version":"4.0.3","preview":true,"description":"Actions cache lib","keywords":["github","actions","cache"],"homepage":"https://github.com/actions/toolkit/tree/main/packages/cache","license":"MIT","main":"lib/cache.js","types":"lib/cache.d.ts","directories":{"lib":"lib","test":"__tests__"},"files":["lib","!.DS_Store"],"publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/actions/toolkit.git","directory":"packages/cache"},"scripts":{"audit-moderate":"npm install && npm audit --json --audit-level=moderate > audit.json","test":"echo \\"Error: run tests from root\\" && exit 1","tsc":"tsc"},"bugs":{"url":"https://github.com/actions/toolkit/issues"},"dependencies":{"@actions/core":"^1.11.1","@actions/exec":"^1.0.1","@actions/glob":"^0.1.0","@actions/http-client":"^2.1.1","@actions/io":"^1.0.1","@azure/abort-controller":"^1.1.0","@azure/ms-rest-js":"^2.6.0","@azure/storage-blob":"^12.13.0","@protobuf-ts/plugin":"^2.9.4","semver":"^6.3.1"},"devDependencies":{"@types/node":"^22.13.9","@types/semver":"^6.0.0","typescript":"^5.2.2"}}');
/***/ }),

143
dist/setup/index.js vendored
View File

@ -220,7 +220,7 @@ function restoreCacheV2(paths, primaryKey, restoreKeys, options, enableCrossOsAr
};
const response = yield twirpClient.GetCacheEntryDownloadURL(request);
if (!response.ok) {
core.debug(`Cache not found for keys: ${keys.join(', ')}`);
core.debug(`Cache not found for version ${request.version} of keys: ${keys.join(', ')}`);
return undefined;
}
core.info(`Cache hit for: ${request.key}`);
@ -2204,6 +2204,7 @@ const cacheUtils_1 = __nccwpck_require__(680);
const auth_1 = __nccwpck_require__(4552);
const http_client_1 = __nccwpck_require__(4844);
const cache_twirp_client_1 = __nccwpck_require__(1486);
const util_1 = __nccwpck_require__(7564);
/**
* This class is a wrapper around the CacheServiceClientJSON class generated by Twirp.
*
@ -2263,6 +2264,7 @@ class CacheServiceClient {
(0, core_1.debug)(`[Response] - ${response.message.statusCode}`);
(0, core_1.debug)(`Headers: ${JSON.stringify(response.message.headers, null, 2)}`);
const body = JSON.parse(rawBody);
(0, util_1.maskSecretUrls)(body);
(0, core_1.debug)(`Body: ${JSON.stringify(body, null, 2)}`);
if (this.isSuccessStatusCode(statusCode)) {
return { response, body };
@ -2444,6 +2446,87 @@ exports.getUserAgentString = getUserAgentString;
/***/ }),
/***/ 7564:
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.maskSecretUrls = exports.maskSigUrl = void 0;
const core_1 = __nccwpck_require__(7484);
/**
* Masks the `sig` parameter in a URL and sets it as a secret.
*
* @param url - The URL containing the signature parameter to mask
* @remarks
* This function attempts to parse the provided URL and identify the 'sig' query parameter.
* If found, it registers both the raw and URL-encoded signature values as secrets using
* the Actions `setSecret` API, which prevents them from being displayed in logs.
*
* The function handles errors gracefully if URL parsing fails, logging them as debug messages.
*
* @example
* ```typescript
* // Mask a signature in an Azure SAS token URL
* maskSigUrl('https://example.blob.core.windows.net/container/file.txt?sig=abc123&se=2023-01-01');
* ```
*/
function maskSigUrl(url) {
if (!url)
return;
try {
const parsedUrl = new URL(url);
const signature = parsedUrl.searchParams.get('sig');
if (signature) {
(0, core_1.setSecret)(signature);
(0, core_1.setSecret)(encodeURIComponent(signature));
}
}
catch (error) {
(0, core_1.debug)(`Failed to parse URL: ${url} ${error instanceof Error ? error.message : String(error)}`);
}
}
exports.maskSigUrl = maskSigUrl;
/**
* Masks sensitive information in URLs containing signature parameters.
* Currently supports masking 'sig' parameters in the 'signed_upload_url'
* and 'signed_download_url' properties of the provided object.
*
* @param body - The object should contain a signature
* @remarks
* This function extracts URLs from the object properties and calls maskSigUrl
* on each one to redact sensitive signature information. The function doesn't
* modify the original object; it only marks the signatures as secrets for
* logging purposes.
*
* @example
* ```typescript
* const responseBody = {
* signed_upload_url: 'https://blob.core.windows.net/?sig=abc123',
* signed_download_url: 'https://blob.core/windows.net/?sig=def456'
* };
* maskSecretUrls(responseBody);
* ```
*/
function maskSecretUrls(body) {
if (typeof body !== 'object' || body === null) {
(0, core_1.debug)('body is not an object or is null');
return;
}
if ('signed_upload_url' in body &&
typeof body.signed_upload_url === 'string') {
maskSigUrl(body.signed_upload_url);
}
if ('signed_download_url' in body &&
typeof body.signed_download_url === 'string') {
maskSigUrl(body.signed_download_url);
}
}
exports.maskSecretUrls = maskSecretUrls;
//# sourceMappingURL=util.js.map
/***/ }),
/***/ 5321:
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
@ -88838,7 +88921,7 @@ function getUserAgent() {
return navigator.userAgent;
}
if (typeof process === "object" && "version" in process) {
if (typeof process === "object" && process.version !== undefined) {
return `Node.js/${process.version.substr(1)} (${process.platform}; ${process.arch})`;
}
@ -97211,9 +97294,13 @@ class BaseDistribution {
}
getNodeJsVersions() {
return __awaiter(this, void 0, void 0, function* () {
const initialUrl = this.getDistributionUrl();
const initialUrl = this.getDistributionUrl(this.nodeInfo.mirror);
const dataUrl = `${initialUrl}/index.json`;
const response = yield this.httpClient.getJson(dataUrl);
const headers = {};
if (this.nodeInfo.mirrorToken) {
headers['Authorization'] = `Bearer ${this.nodeInfo.mirrorToken}`;
}
const response = yield this.httpClient.getJson(dataUrl, headers);
return response.result || [];
});
}
@ -97228,7 +97315,7 @@ class BaseDistribution {
? `${fileName}.zip`
: `${fileName}.7z`
: `${fileName}.tar.gz`;
const initialUrl = this.getDistributionUrl();
const initialUrl = this.getDistributionUrl(this.nodeInfo.mirror);
const url = `${initialUrl}/v${version}/${urlFileName}`;
return {
downloadUrl: url,
@ -97242,7 +97329,7 @@ class BaseDistribution {
let downloadPath = '';
core.info(`Acquiring ${info.resolvedVersion} - ${info.arch} from ${info.downloadUrl}`);
try {
downloadPath = yield tc.downloadTool(info.downloadUrl);
downloadPath = yield tc.downloadTool(info.downloadUrl, undefined, this.nodeInfo.mirrorToken);
}
catch (err) {
if (err instanceof tc.HTTPError &&
@ -97266,7 +97353,7 @@ class BaseDistribution {
}
acquireWindowsNodeFromFallbackLocation(version_1) {
return __awaiter(this, arguments, void 0, function* (version, arch = os_1.default.arch()) {
const initialUrl = this.getDistributionUrl();
const initialUrl = this.getDistributionUrl(this.nodeInfo.mirror);
const osArch = this.translateArchToDistUrl(arch);
// Create temporary folder to download to
const tempDownloadFolder = `temp_${(0, uuid_1.v4)()}`;
@ -97280,18 +97367,18 @@ class BaseDistribution {
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);
const exePath = yield tc.downloadTool(exeUrl, undefined, this.nodeInfo.mirrorToken);
yield io.cp(exePath, path.join(tempDir, 'node.exe'));
const libPath = yield tc.downloadTool(libUrl);
const libPath = yield tc.downloadTool(libUrl, undefined, this.nodeInfo.mirrorToken);
yield io.cp(libPath, path.join(tempDir, 'node.lib'));
}
catch (err) {
if (err instanceof tc.HTTPError && err.httpStatusCode == 404) {
exeUrl = `${initialUrl}/v${version}/node.exe`;
libUrl = `${initialUrl}/v${version}/node.lib`;
const exePath = yield tc.downloadTool(exeUrl);
const exePath = yield tc.downloadTool(exeUrl, undefined, this.nodeInfo.mirrorToken);
yield io.cp(exePath, path.join(tempDir, 'node.exe'));
const libPath = yield tc.downloadTool(libUrl);
const libPath = yield tc.downloadTool(libUrl, undefined, this.nodeInfo.mirrorToken);
yield io.cp(libPath, path.join(tempDir, 'node.lib'));
}
else {
@ -97454,8 +97541,9 @@ class NightlyNodejs extends base_distribution_prerelease_1.default {
super(nodeInfo);
this.distribution = 'nightly';
}
getDistributionUrl() {
return 'https://nodejs.org/download/nightly';
getDistributionUrl(mirror) {
const url = mirror || 'https://nodejs.org';
return `${url}/download/nightly`;
}
}
exports["default"] = NightlyNodejs;
@ -97553,13 +97641,13 @@ class OfficialBuilds extends base_distribution_1.default {
const versionInfo = yield this.getInfoFromManifest(this.nodeInfo.versionSpec, this.nodeInfo.stable, osArch, manifest);
if (versionInfo) {
core.info(`Acquiring ${versionInfo.resolvedVersion} - ${versionInfo.arch} from ${versionInfo.downloadUrl}`);
downloadPath = yield tc.downloadTool(versionInfo.downloadUrl, undefined, this.nodeInfo.auth);
downloadPath = yield tc.downloadTool(versionInfo.downloadUrl, undefined, this.nodeInfo.mirror ? this.nodeInfo.mirrorToken : this.nodeInfo.auth);
if (downloadPath) {
toolPath = yield this.extractArchive(downloadPath, versionInfo, false);
}
}
else {
core.info('Not found in manifest. Falling back to download directly from Node');
core.info(`Not found in manifest. Falling back to download directly from ${this.nodeInfo.mirror || 'Node'}`);
}
}
catch (err) {
@ -97621,12 +97709,13 @@ class OfficialBuilds extends base_distribution_1.default {
version = super.evaluateVersions(versions);
return version;
}
getDistributionUrl() {
return `https://nodejs.org/dist`;
getDistributionUrl(mirror) {
const url = mirror || 'https://nodejs.org';
return `${url}/dist`;
}
getManifest() {
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.mirror ? this.nodeInfo.mirrorToken : this.nodeInfo.auth, 'main');
}
resolveLtsAliasFromManifest(versionSpec, stable, manifest) {
var _a;
@ -97709,8 +97798,9 @@ class RcBuild extends base_distribution_1.default {
constructor(nodeInfo) {
super(nodeInfo);
}
getDistributionUrl() {
return 'https://nodejs.org/download/rc';
getDistributionUrl(mirror) {
const url = mirror || 'https://nodejs.org';
return `${url}/download/rc`;
}
}
exports["default"] = RcBuild;
@ -97733,8 +97823,9 @@ class CanaryBuild extends base_distribution_prerelease_1.default {
super(nodeInfo);
this.distribution = 'v8-canary';
}
getDistributionUrl() {
return 'https://nodejs.org/download/v8-canary';
getDistributionUrl(mirror) {
const url = mirror || 'https://nodejs.org';
return `${url}/download/v8-canary`;
}
}
exports["default"] = CanaryBuild;
@ -97814,6 +97905,8 @@ function run() {
if (version) {
const token = core.getInput('token');
const auth = !token ? undefined : `token ${token}`;
const mirror = core.getInput('mirror');
const mirrorToken = core.getInput('mirror-token');
const stable = (core.getInput('stable') || 'true').toUpperCase() === 'TRUE';
const checkLatest = (core.getInput('check-latest') || 'false').toUpperCase() === 'TRUE';
const nodejsInfo = {
@ -97821,7 +97914,9 @@ function run() {
checkLatest,
auth,
stable,
arch
arch,
mirror,
mirrorToken
};
const nodeDistribution = (0, installer_factory_1.getNodejsDistribution)(nodejsInfo);
yield nodeDistribution.setupNodeJs();
@ -99910,7 +100005,7 @@ module.exports = parseParams
/***/ ((module) => {
"use strict";
module.exports = /*#__PURE__*/JSON.parse('{"name":"@actions/cache","version":"4.0.2","preview":true,"description":"Actions cache lib","keywords":["github","actions","cache"],"homepage":"https://github.com/actions/toolkit/tree/main/packages/cache","license":"MIT","main":"lib/cache.js","types":"lib/cache.d.ts","directories":{"lib":"lib","test":"__tests__"},"files":["lib","!.DS_Store"],"publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/actions/toolkit.git","directory":"packages/cache"},"scripts":{"audit-moderate":"npm install && npm audit --json --audit-level=moderate > audit.json","test":"echo \\"Error: run tests from root\\" && exit 1","tsc":"tsc"},"bugs":{"url":"https://github.com/actions/toolkit/issues"},"dependencies":{"@actions/core":"^1.11.1","@actions/exec":"^1.0.1","@actions/glob":"^0.1.0","@actions/http-client":"^2.1.1","@actions/io":"^1.0.1","@azure/abort-controller":"^1.1.0","@azure/ms-rest-js":"^2.6.0","@azure/storage-blob":"^12.13.0","@protobuf-ts/plugin":"^2.9.4","semver":"^6.3.1"},"devDependencies":{"@types/semver":"^6.0.0","typescript":"^5.2.2"}}');
module.exports = /*#__PURE__*/JSON.parse('{"name":"@actions/cache","version":"4.0.3","preview":true,"description":"Actions cache lib","keywords":["github","actions","cache"],"homepage":"https://github.com/actions/toolkit/tree/main/packages/cache","license":"MIT","main":"lib/cache.js","types":"lib/cache.d.ts","directories":{"lib":"lib","test":"__tests__"},"files":["lib","!.DS_Store"],"publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/actions/toolkit.git","directory":"packages/cache"},"scripts":{"audit-moderate":"npm install && npm audit --json --audit-level=moderate > audit.json","test":"echo \\"Error: run tests from root\\" && exit 1","tsc":"tsc"},"bugs":{"url":"https://github.com/actions/toolkit/issues"},"dependencies":{"@actions/core":"^1.11.1","@actions/exec":"^1.0.1","@actions/glob":"^0.1.0","@actions/http-client":"^2.1.1","@actions/io":"^1.0.1","@azure/abort-controller":"^1.1.0","@azure/ms-rest-js":"^2.6.0","@azure/storage-blob":"^12.13.0","@protobuf-ts/plugin":"^2.9.4","semver":"^6.3.1"},"devDependencies":{"@types/node":"^22.13.9","@types/semver":"^6.0.0","typescript":"^5.2.2"}}');
/***/ }),

View File

@ -418,3 +418,18 @@ Please refer to the [Ensuring workflow access to your package - Configuring a pa
### always-auth input
The always-auth input sets `always-auth=true` in .npmrc file. With this option set [npm](https://docs.npmjs.com/cli/v6/using-npm/config#always-auth)/yarn sends the authentication credentials when making a request to the registries.
## Use private mirror
It is possible to use a private mirror hosting Node.js binaries. This mirror must be a full mirror of the official Node.js distribution.
The mirror URL can be set using the `mirror` input.
It is possible to specify a token to authenticate with the mirror using the `mirror-token` input.
The token will be passed as a bearer token in the `Authorization` header.
```yaml
- uses: actions/setup-node@v4
with:
node-version: '14.x'
mirror: 'https://nodejs.org/dist'
mirror-token: 'your-mirror-token'
```

276
package-lock.json generated
View File

@ -9,7 +9,7 @@
"version": "4.0.0",
"license": "MIT",
"dependencies": {
"@actions/cache": "^4.0.2",
"@actions/cache": "^4.0.3",
"@actions/core": "^1.11.1",
"@actions/exec": "^1.1.1",
"@actions/github": "^5.1.1",
@ -49,9 +49,9 @@
}
},
"node_modules/@actions/cache": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/@actions/cache/-/cache-4.0.2.tgz",
"integrity": "sha512-cBr7JL1q+JKjbBd3w3SZN5OQ1Xg+/D8QLMcE7MpgpghZlL4biBO0ZEeraoTxCZyfN0YY0dxXlLgsgGv/sT5BTg==",
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/@actions/cache/-/cache-4.0.3.tgz",
"integrity": "sha512-SvrqFtYJ7I48A/uXNkoJrnukx5weQv1fGquhs3+4nkByZThBH109KTIqj5x/cGV7JGNvb8dLPVywUOqX1fjiXg==",
"license": "MIT",
"dependencies": {
"@actions/core": "^1.11.1",
@ -106,6 +106,7 @@
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/@actions/github/-/github-5.1.1.tgz",
"integrity": "sha512-Nk59rMDoJaV+mHCOJPXuvB1zIbomlKS0dmSIqPGxd0enAXBnOfn4VWF+CGtRCwXZG9Epa54tZA7VIRlJDS8A6g==",
"license": "MIT",
"dependencies": {
"@actions/http-client": "^2.0.1",
"@octokit/core": "^3.6.0",
@ -347,89 +348,20 @@
}
},
"node_modules/@babel/code-frame": {
"version": "7.22.13",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz",
"integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==",
"version": "7.26.2",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz",
"integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/highlight": "^7.22.13",
"chalk": "^2.4.2"
"@babel/helper-validator-identifier": "^7.25.9",
"js-tokens": "^4.0.0",
"picocolors": "^1.0.0"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/code-frame/node_modules/ansi-styles": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"dev": true,
"dependencies": {
"color-convert": "^1.9.0"
},
"engines": {
"node": ">=4"
}
},
"node_modules/@babel/code-frame/node_modules/chalk": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
"dev": true,
"dependencies": {
"ansi-styles": "^3.2.1",
"escape-string-regexp": "^1.0.5",
"supports-color": "^5.3.0"
},
"engines": {
"node": ">=4"
}
},
"node_modules/@babel/code-frame/node_modules/color-convert": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
"dev": true,
"dependencies": {
"color-name": "1.1.3"
}
},
"node_modules/@babel/code-frame/node_modules/color-name": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
"integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
"dev": true
},
"node_modules/@babel/code-frame/node_modules/escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
"dev": true,
"engines": {
"node": ">=0.8.0"
}
},
"node_modules/@babel/code-frame/node_modules/has-flag": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
"dev": true,
"engines": {
"node": ">=4"
}
},
"node_modules/@babel/code-frame/node_modules/supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"dev": true,
"dependencies": {
"has-flag": "^3.0.0"
},
"engines": {
"node": ">=4"
}
},
"node_modules/@babel/compat-data": {
"version": "7.23.2",
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.2.tgz",
@ -617,19 +549,21 @@
}
},
"node_modules/@babel/helper-string-parser": {
"version": "7.22.5",
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz",
"integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==",
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz",
"integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-validator-identifier": {
"version": "7.22.20",
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
"integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz",
"integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6.9.0"
}
@ -644,109 +578,28 @@
}
},
"node_modules/@babel/helpers": {
"version": "7.23.2",
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.2.tgz",
"integrity": "sha512-lzchcp8SjTSVe/fPmLwtWVBFC7+Tbn8LGHDVfDp9JGxpAY5opSaEFgt8UQvrnECWOTdji2mOWMz1rOhkHscmGQ==",
"version": "7.27.0",
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.0.tgz",
"integrity": "sha512-U5eyP/CTFPuNE3qk+WZMxFkp/4zUzdceQlfzf7DdGdhp+Fezd7HD+i8Y24ZuTMKX3wQBld449jijbGq6OdGNQg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/template": "^7.22.15",
"@babel/traverse": "^7.23.2",
"@babel/types": "^7.23.0"
"@babel/template": "^7.27.0",
"@babel/types": "^7.27.0"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/highlight": {
"version": "7.22.20",
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz",
"integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==",
"dev": true,
"dependencies": {
"@babel/helper-validator-identifier": "^7.22.20",
"chalk": "^2.4.2",
"js-tokens": "^4.0.0"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/highlight/node_modules/ansi-styles": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"dev": true,
"dependencies": {
"color-convert": "^1.9.0"
},
"engines": {
"node": ">=4"
}
},
"node_modules/@babel/highlight/node_modules/chalk": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
"dev": true,
"dependencies": {
"ansi-styles": "^3.2.1",
"escape-string-regexp": "^1.0.5",
"supports-color": "^5.3.0"
},
"engines": {
"node": ">=4"
}
},
"node_modules/@babel/highlight/node_modules/color-convert": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
"dev": true,
"dependencies": {
"color-name": "1.1.3"
}
},
"node_modules/@babel/highlight/node_modules/color-name": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
"integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
"dev": true
},
"node_modules/@babel/highlight/node_modules/escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
"dev": true,
"engines": {
"node": ">=0.8.0"
}
},
"node_modules/@babel/highlight/node_modules/has-flag": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
"dev": true,
"engines": {
"node": ">=4"
}
},
"node_modules/@babel/highlight/node_modules/supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"dev": true,
"dependencies": {
"has-flag": "^3.0.0"
},
"engines": {
"node": ">=4"
}
},
"node_modules/@babel/parser": {
"version": "7.23.0",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz",
"integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==",
"version": "7.27.0",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.0.tgz",
"integrity": "sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/types": "^7.27.0"
},
"bin": {
"parser": "bin/babel-parser.js"
},
@ -932,14 +785,15 @@
}
},
"node_modules/@babel/template": {
"version": "7.22.15",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz",
"integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==",
"version": "7.27.0",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.0.tgz",
"integrity": "sha512-2ncevenBqXI6qRMukPlXwHKHchC7RyMuu4xv5JBXRfOGVcTy1mXCD12qrp7Jsoxll1EV3+9sE4GugBVRjT2jFA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/code-frame": "^7.22.13",
"@babel/parser": "^7.22.15",
"@babel/types": "^7.22.15"
"@babel/code-frame": "^7.26.2",
"@babel/parser": "^7.27.0",
"@babel/types": "^7.27.0"
},
"engines": {
"node": ">=6.9.0"
@ -976,14 +830,14 @@
}
},
"node_modules/@babel/types": {
"version": "7.23.0",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz",
"integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==",
"version": "7.27.0",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.0.tgz",
"integrity": "sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-string-parser": "^7.22.5",
"@babel/helper-validator-identifier": "^7.22.20",
"to-fast-properties": "^2.0.0"
"@babel/helper-string-parser": "^7.25.9",
"@babel/helper-validator-identifier": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@ -1566,6 +1420,7 @@
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz",
"integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==",
"license": "MIT",
"dependencies": {
"@octokit/types": "^6.0.3"
}
@ -1574,6 +1429,7 @@
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.6.0.tgz",
"integrity": "sha512-7RKRKuA4xTjMhY+eG3jthb3hlZCsOwg3rztWh75Xc+ShDWOfDDATWbeZpAHBNRpm4Tv9WgBMOy1zEJYXG6NJ7Q==",
"license": "MIT",
"dependencies": {
"@octokit/auth-token": "^2.4.4",
"@octokit/graphql": "^4.5.8",
@ -1588,6 +1444,7 @@
"version": "6.0.12",
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz",
"integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==",
"license": "MIT",
"dependencies": {
"@octokit/types": "^6.0.3",
"is-plain-object": "^5.0.0",
@ -1598,6 +1455,7 @@
"version": "4.8.0",
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz",
"integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==",
"license": "MIT",
"dependencies": {
"@octokit/request": "^5.6.0",
"@octokit/types": "^6.0.3",
@ -1607,12 +1465,14 @@
"node_modules/@octokit/openapi-types": {
"version": "12.11.0",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-12.11.0.tgz",
"integrity": "sha512-VsXyi8peyRq9PqIz/tpqiL2w3w80OgVMwBHltTml3LmVvXiphgeqmY9mvBw9Wu7e0QWk/fqD37ux8yP5uVekyQ=="
"integrity": "sha512-VsXyi8peyRq9PqIz/tpqiL2w3w80OgVMwBHltTml3LmVvXiphgeqmY9mvBw9Wu7e0QWk/fqD37ux8yP5uVekyQ==",
"license": "MIT"
},
"node_modules/@octokit/plugin-paginate-rest": {
"version": "2.21.3",
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.21.3.tgz",
"integrity": "sha512-aCZTEf0y2h3OLbrgKkrfFdjRL6eSOo8komneVQJnYecAxIej7Bafor2xhuDJOIFau4pk0i/P28/XgtbyPF0ZHw==",
"license": "MIT",
"dependencies": {
"@octokit/types": "^6.40.0"
},
@ -1624,6 +1484,7 @@
"version": "5.16.2",
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.16.2.tgz",
"integrity": "sha512-8QFz29Fg5jDuTPXVtey05BLm7OB+M8fnvE64RNegzX7U+5NUXcOcnpTIK0YfSHBg8gYd0oxIq3IZTe9SfPZiRw==",
"license": "MIT",
"dependencies": {
"@octokit/types": "^6.39.0",
"deprecation": "^2.3.1"
@ -1636,6 +1497,7 @@
"version": "5.6.3",
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.3.tgz",
"integrity": "sha512-bFJl0I1KVc9jYTe9tdGGpAMPy32dLBXXo1dS/YwSCTL/2nd9XeHsY616RE3HPXDVk+a+dBuzyz5YdlXwcDTr2A==",
"license": "MIT",
"dependencies": {
"@octokit/endpoint": "^6.0.1",
"@octokit/request-error": "^2.1.0",
@ -1649,6 +1511,7 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz",
"integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==",
"license": "MIT",
"dependencies": {
"@octokit/types": "^6.0.3",
"deprecation": "^2.0.0",
@ -1659,6 +1522,7 @@
"version": "6.41.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.41.0.tgz",
"integrity": "sha512-eJ2jbzjdijiL3B4PrSQaSjuF2sPEQPVCPzBvTHJD9Nz+9dw2SGH4K4xeQJ77YfTq5bRQ+bD8wT11JbeDPmxmGg==",
"license": "MIT",
"dependencies": {
"@octokit/openapi-types": "^12.11.0"
}
@ -2388,7 +2252,8 @@
"node_modules/before-after-hook": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz",
"integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ=="
"integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==",
"license": "Apache-2.0"
},
"node_modules/brace-expansion": {
"version": "1.1.11",
@ -2716,7 +2581,8 @@
"node_modules/deprecation": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz",
"integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ=="
"integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==",
"license": "ISC"
},
"node_modules/detect-newline": {
"version": "3.1.0",
@ -3650,6 +3516,7 @@
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
@ -4297,7 +4164,8 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
"dev": true
"dev": true,
"license": "MIT"
},
"node_modules/js-yaml": {
"version": "4.1.0",
@ -5321,15 +5189,6 @@
"integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==",
"dev": true
},
"node_modules/to-fast-properties": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
"integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==",
"dev": true,
"engines": {
"node": ">=4"
}
},
"node_modules/to-regex-range": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
@ -5488,9 +5347,10 @@
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="
},
"node_modules/universal-user-agent": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz",
"integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w=="
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.1.tgz",
"integrity": "sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==",
"license": "ISC"
},
"node_modules/update-browserslist-db": {
"version": "1.0.13",

View File

@ -25,7 +25,7 @@
"author": "GitHub",
"license": "MIT",
"dependencies": {
"@actions/cache": "^4.0.2",
"@actions/cache": "^4.0.3",
"@actions/core": "^1.11.1",
"@actions/exec": "^1.1.1",
"@actions/github": "^5.1.1",

View File

@ -24,7 +24,7 @@ export default abstract class BaseDistribution {
});
}
protected abstract getDistributionUrl(): string;
protected abstract getDistributionUrl(mirror: string): string;
public async setupNodeJs() {
let nodeJsVersions: INodeVersion[] | undefined;
@ -97,10 +97,19 @@ export default abstract class BaseDistribution {
}
protected async getNodeJsVersions(): Promise<INodeVersion[]> {
const initialUrl = this.getDistributionUrl();
const initialUrl = this.getDistributionUrl(this.nodeInfo.mirror);
const dataUrl = `${initialUrl}/index.json`;
const response = await this.httpClient.getJson<INodeVersion[]>(dataUrl);
const headers = {};
if (this.nodeInfo.mirrorToken) {
headers['Authorization'] = `Bearer ${this.nodeInfo.mirrorToken}`;
}
const response = await this.httpClient.getJson<INodeVersion[]>(
dataUrl,
headers
);
return response.result || [];
}
@ -117,7 +126,7 @@ export default abstract class BaseDistribution {
? `${fileName}.zip`
: `${fileName}.7z`
: `${fileName}.tar.gz`;
const initialUrl = this.getDistributionUrl();
const initialUrl = this.getDistributionUrl(this.nodeInfo.mirror);
const url = `${initialUrl}/v${version}/${urlFileName}`;
return <INodeVersionInfo>{
@ -134,7 +143,11 @@ export default abstract class BaseDistribution {
`Acquiring ${info.resolvedVersion} - ${info.arch} from ${info.downloadUrl}`
);
try {
downloadPath = await tc.downloadTool(info.downloadUrl);
downloadPath = await tc.downloadTool(
info.downloadUrl,
undefined,
this.nodeInfo.mirrorToken
);
} catch (err) {
if (
err instanceof tc.HTTPError &&
@ -168,7 +181,7 @@ export default abstract class BaseDistribution {
version: string,
arch: string = os.arch()
): Promise<string> {
const initialUrl = this.getDistributionUrl();
const initialUrl = this.getDistributionUrl(this.nodeInfo.mirror);
const osArch: string = this.translateArchToDistUrl(arch);
// Create temporary folder to download to
@ -185,18 +198,34 @@ export default abstract class BaseDistribution {
core.info(`Downloading only node binary from ${exeUrl}`);
const exePath = await tc.downloadTool(exeUrl);
const exePath = await tc.downloadTool(
exeUrl,
undefined,
this.nodeInfo.mirrorToken
);
await io.cp(exePath, path.join(tempDir, 'node.exe'));
const libPath = await tc.downloadTool(libUrl);
const libPath = await tc.downloadTool(
libUrl,
undefined,
this.nodeInfo.mirrorToken
);
await io.cp(libPath, path.join(tempDir, 'node.lib'));
} catch (err) {
if (err instanceof tc.HTTPError && err.httpStatusCode == 404) {
exeUrl = `${initialUrl}/v${version}/node.exe`;
libUrl = `${initialUrl}/v${version}/node.lib`;
const exePath = await tc.downloadTool(exeUrl);
const exePath = await tc.downloadTool(
exeUrl,
undefined,
this.nodeInfo.mirrorToken
);
await io.cp(exePath, path.join(tempDir, 'node.exe'));
const libPath = await tc.downloadTool(libUrl);
const libPath = await tc.downloadTool(
libUrl,
undefined,
this.nodeInfo.mirrorToken
);
await io.cp(libPath, path.join(tempDir, 'node.lib'));
} else {
throw err;

View File

@ -4,6 +4,8 @@ export interface NodeInputs {
auth?: string;
checkLatest: boolean;
stable: boolean;
mirror: string;
mirrorToken: string;
}
export interface INodeVersionInfo {

View File

@ -7,7 +7,8 @@ export default class NightlyNodejs extends BasePrereleaseNodejs {
super(nodeInfo);
}
protected getDistributionUrl(): string {
return 'https://nodejs.org/download/nightly';
protected getDistributionUrl(mirror: string): string {
const url = mirror || 'https://nodejs.org';
return `${url}/download/nightly`;
}
}

View File

@ -84,7 +84,7 @@ export default class OfficialBuilds extends BaseDistribution {
downloadPath = await tc.downloadTool(
versionInfo.downloadUrl,
undefined,
this.nodeInfo.auth
this.nodeInfo.mirror ? this.nodeInfo.mirrorToken : this.nodeInfo.auth
);
if (downloadPath) {
@ -96,7 +96,9 @@ export default class OfficialBuilds extends BaseDistribution {
}
} else {
core.info(
'Not found in manifest. Falling back to download directly from Node'
`Not found in manifest. Falling back to download directly from ${
this.nodeInfo.mirror || 'Node'
}`
);
}
} catch (err) {
@ -176,8 +178,9 @@ export default class OfficialBuilds extends BaseDistribution {
return version;
}
protected getDistributionUrl(): string {
return `https://nodejs.org/dist`;
protected getDistributionUrl(mirror: string): string {
const url = mirror || 'https://nodejs.org';
return `${url}/dist`;
}
private getManifest(): Promise<tc.IToolRelease[]> {
@ -185,7 +188,7 @@ export default class OfficialBuilds extends BaseDistribution {
return tc.getManifestFromRepo(
'actions',
'node-versions',
this.nodeInfo.auth,
this.nodeInfo.mirror ? this.nodeInfo.mirrorToken : this.nodeInfo.auth,
'main'
);
}

View File

@ -6,7 +6,8 @@ export default class RcBuild extends BaseDistribution {
super(nodeInfo);
}
getDistributionUrl(): string {
return 'https://nodejs.org/download/rc';
getDistributionUrl(mirror: string): string {
const url = mirror || 'https://nodejs.org';
return `${url}/download/rc`;
}
}

View File

@ -7,7 +7,8 @@ export default class CanaryBuild extends BasePrereleaseNodejs {
super(nodeInfo);
}
protected getDistributionUrl(): string {
return 'https://nodejs.org/download/v8-canary';
protected getDistributionUrl(mirror: string): string {
const url = mirror || 'https://nodejs.org';
return `${url}/download/v8-canary`;
}
}

View File

@ -36,6 +36,8 @@ export async function run() {
if (version) {
const token = core.getInput('token');
const auth = !token ? undefined : `token ${token}`;
const mirror = core.getInput('mirror');
const mirrorToken = core.getInput('mirror-token');
const stable =
(core.getInput('stable') || 'true').toUpperCase() === 'TRUE';
const checkLatest =
@ -45,7 +47,9 @@ export async function run() {
checkLatest,
auth,
stable,
arch
arch,
mirror,
mirrorToken
};
const nodeDistribution = getNodejsDistribution(nodejsInfo);
await nodeDistribution.setupNodeJs();