mirror of
https://github.com/actions/setup-node.git
synced 2026-02-22 06:34:44 +08:00
Compare commits
11 Commits
v4.3.0
...
a59a644dc4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a59a644dc4 | ||
|
|
e3ce749e20 | ||
|
|
40337cb8f7 | ||
|
|
1ccdddc9b8 | ||
|
|
7f7a8815ae | ||
|
|
edb404feb0 | ||
|
|
9aee14b09c | ||
|
|
7cfc90cf21 | ||
|
|
9b7fb640b1 | ||
|
|
e4f60bc7fe | ||
|
|
ff0f4b6812 |
2
.github/eslint-compact.json
vendored
2
.github/eslint-compact.json
vendored
@@ -4,7 +4,7 @@
|
|||||||
"owner": "eslint-compact",
|
"owner": "eslint-compact",
|
||||||
"pattern": [
|
"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,
|
"file": 1,
|
||||||
"line": 2,
|
"line": 2,
|
||||||
"column": 3,
|
"column": 3,
|
||||||
|
|||||||
2
.github/eslint-stylish.json
vendored
2
.github/eslint-stylish.json
vendored
@@ -4,7 +4,7 @@
|
|||||||
"owner": "eslint-stylish",
|
"owner": "eslint-stylish",
|
||||||
"pattern": [
|
"pattern": [
|
||||||
{
|
{
|
||||||
"regexp": "^([^\\s].*)$",
|
"regexp": "^\\s*([^\\s].*)$",
|
||||||
"file": 1
|
"file": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
2
.github/workflows/versions.yml
vendored
2
.github/workflows/versions.yml
vendored
@@ -158,7 +158,7 @@ jobs:
|
|||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-latest, windows-latest, macos-latest, macos-13]
|
os: [ubuntu-latest, windows-latest, macos-latest, macos-13]
|
||||||
node-version-file:
|
node-version-file:
|
||||||
[.nvmrc, .tool-versions, .tool-versions-node, package.json]
|
[.nvmrc, .tool-versions, .tool-versions-node, package.json, .npmrc]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- name: Setup node from node version file
|
- name: Setup node from node version file
|
||||||
|
|||||||
17
README.md
17
README.md
@@ -25,7 +25,7 @@ See [action.yml](action.yml)
|
|||||||
# Examples: 12.x, 10.15.1, >=10.15.0, lts/Hydrogen, 16-nightly, latest, node
|
# Examples: 12.x, 10.15.1, >=10.15.0, lts/Hydrogen, 16-nightly, latest, node
|
||||||
node-version: ''
|
node-version: ''
|
||||||
|
|
||||||
# File containing the version Spec of the version to use. Examples: package.json, .nvmrc, .node-version, .tool-versions.
|
# File containing the version Spec of the version to use. Examples: package.json, .nvmrc, .node-version, .tool-versions, .npmrc.
|
||||||
# If node-version and node-version-file are both provided the action will use version from node-version.
|
# If node-version and node-version-file are both provided the action will use version from node-version.
|
||||||
node-version-file: ''
|
node-version-file: ''
|
||||||
|
|
||||||
@@ -76,6 +76,21 @@ See [action.yml](action.yml)
|
|||||||
# Set always-auth option in npmrc file.
|
# Set always-auth option in npmrc file.
|
||||||
# Default: ''
|
# Default: ''
|
||||||
always-auth: ''
|
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 -->
|
<!-- end usage -->
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ Files located in data directory are used only for testing purposes.
|
|||||||
|
|
||||||
|
|
||||||
## Here the list of files in the data directory
|
## Here the list of files in the data directory
|
||||||
- `.nvmrc`, `.tools-versions` and `package.json` are used to test node-version-file logic
|
- `.nvmrc`, `.tools-versions`, `package.json` and `.npmrc` are used to test node-version-file logic
|
||||||
- `package-lock.json`, `pnpm-lock.yaml` and `yarn.lock` are used to test cache logic
|
- `package-lock.json`, `pnpm-lock.yaml` and `yarn.lock` are used to test cache logic
|
||||||
- `versions-manifest.json` is used for unit testing to check downloading Node.js versions from the node-versions repository.
|
- `versions-manifest.json` is used for unit testing to check downloading Node.js versions from the node-versions repository.
|
||||||
- `node-dist-index.json` is used for unit testing to check downloading Node.js versions from the official site. The file was constructed from https://nodejs.org/dist/index.json
|
- `node-dist-index.json` is used for unit testing to check downloading Node.js versions from the official site. The file was constructed from https://nodejs.org/dist/index.json
|
||||||
|
|||||||
@@ -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', () => {
|
describe('setup-node v8 canary tests', () => {
|
||||||
|
|||||||
1
__tests__/data/.npmrc
Normal file
1
__tests__/data/.npmrc
Normal file
@@ -0,0 +1 @@
|
|||||||
|
use-node-version=20.0.0
|
||||||
@@ -103,10 +103,14 @@ describe('main tests', () => {
|
|||||||
${''} | ${''}
|
${''} | ${''}
|
||||||
${'unknown format'} | ${'unknown format'}
|
${'unknown format'} | ${'unknown format'}
|
||||||
${' 14.1.0 '} | ${'14.1.0'}
|
${' 14.1.0 '} | ${'14.1.0'}
|
||||||
|
${'use-node-version=lts/iron'} | ${'lts/iron'}
|
||||||
|
${'use-node-version=23.10.0'} | ${'23.10.0'}
|
||||||
${'{"volta": {"node": ">=14.0.0 <=17.0.0"}}'}| ${'>=14.0.0 <=17.0.0'}
|
${'{"volta": {"node": ">=14.0.0 <=17.0.0"}}'}| ${'>=14.0.0 <=17.0.0'}
|
||||||
${'{"volta": {"extends": "./package.json"}}'}| ${'18.0.0'}
|
${'{"volta": {"extends": "./package.json"}}'}| ${'18.0.0'}
|
||||||
${'{"engines": {"node": "17.0.0"}}'} | ${'17.0.0'}
|
${'{"engines": {"node": "17.0.0"}}'} | ${'17.0.0'}
|
||||||
${'{}'} | ${null}
|
${'{}'} | ${null}
|
||||||
|
${'[section]use-node-version=16'} | ${null}
|
||||||
|
${'[section]\nuse-node-version=20'} | ${null}
|
||||||
`.it('parses "$contents"', ({contents, expected}) => {
|
`.it('parses "$contents"', ({contents, expected}) => {
|
||||||
const existsSpy = jest.spyOn(fs, 'existsSync');
|
const existsSpy = jest.spyOn(fs, 'existsSync');
|
||||||
existsSpy.mockImplementation(() => true);
|
existsSpy.mockImplementation(() => true);
|
||||||
|
|||||||
@@ -315,7 +315,7 @@ describe('setup-node', () => {
|
|||||||
await main.run();
|
await main.run();
|
||||||
|
|
||||||
workingUrls.forEach(url => {
|
workingUrls.forEach(url => {
|
||||||
expect(dlSpy).toHaveBeenCalledWith(url);
|
expect(dlSpy).toHaveBeenCalledWith(url, undefined, undefined);
|
||||||
});
|
});
|
||||||
expect(cnSpy).toHaveBeenCalledWith(`::add-path::${toolPath}${osm.EOL}`);
|
expect(cnSpy).toHaveBeenCalledWith(`::add-path::${toolPath}${osm.EOL}`);
|
||||||
});
|
});
|
||||||
@@ -449,6 +449,54 @@ describe('setup-node', () => {
|
|||||||
}
|
}
|
||||||
}, 100000);
|
}, 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', () => {
|
describe('nightly versions', () => {
|
||||||
it.each([
|
it.each([
|
||||||
[
|
[
|
||||||
|
|||||||
@@ -282,6 +282,43 @@ describe('setup-node', () => {
|
|||||||
expect(cnSpy).toHaveBeenCalledWith(`::add-path::${expPath}${osm.EOL}`);
|
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 () => {
|
it('falls back to a version from node dist', async () => {
|
||||||
os.platform = 'linux';
|
os.platform = 'linux';
|
||||||
os.arch = 'x64';
|
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);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ inputs:
|
|||||||
node-version:
|
node-version:
|
||||||
description: 'Version Spec of the version to use. Examples: 12.x, 10.15.1, >=10.15.0.'
|
description: 'Version Spec of the version to use. Examples: 12.x, 10.15.1, >=10.15.0.'
|
||||||
node-version-file:
|
node-version-file:
|
||||||
description: 'File containing the version Spec of the version to use. Examples: package.json, .nvmrc, .node-version, .tool-versions.'
|
description: 'File containing the version Spec of the version to use. Examples: package.json, .nvmrc, .node-version, .tool-versions, .npmrc.'
|
||||||
architecture:
|
architecture:
|
||||||
description: 'Target architecture for Node to use. Examples: x86, x64. Will use system architecture by default.'
|
description: 'Target architecture for Node to use. Examples: x86, x64. Will use system architecture by default.'
|
||||||
check-latest:
|
check-latest:
|
||||||
@@ -25,6 +25,10 @@ inputs:
|
|||||||
description: 'Used to specify a package manager for caching in the default directory. Supported values: npm, yarn, pnpm.'
|
description: 'Used to specify a package manager for caching in the default directory. Supported values: npm, yarn, pnpm.'
|
||||||
cache-dependency-path:
|
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.'
|
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.
|
# 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
|
# escape valve for someone having issues or needing the absolute latest which isn't cached yet
|
||||||
outputs:
|
outputs:
|
||||||
|
|||||||
304
dist/cache-save/index.js
vendored
304
dist/cache-save/index.js
vendored
@@ -53213,6 +53213,293 @@ DelayedStream.prototype._checkIfMaxDataSizeExceeded = function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 5756:
|
||||||
|
/***/ ((module) => {
|
||||||
|
|
||||||
|
const { hasOwnProperty } = Object.prototype
|
||||||
|
|
||||||
|
const encode = (obj, opt = {}) => {
|
||||||
|
if (typeof opt === 'string') {
|
||||||
|
opt = { section: opt }
|
||||||
|
}
|
||||||
|
opt.align = opt.align === true
|
||||||
|
opt.newline = opt.newline === true
|
||||||
|
opt.sort = opt.sort === true
|
||||||
|
opt.whitespace = opt.whitespace === true || opt.align === true
|
||||||
|
// The `typeof` check is required because accessing the `process` directly fails on browsers.
|
||||||
|
/* istanbul ignore next */
|
||||||
|
opt.platform = opt.platform || (typeof process !== 'undefined' && process.platform)
|
||||||
|
opt.bracketedArray = opt.bracketedArray !== false
|
||||||
|
|
||||||
|
/* istanbul ignore next */
|
||||||
|
const eol = opt.platform === 'win32' ? '\r\n' : '\n'
|
||||||
|
const separator = opt.whitespace ? ' = ' : '='
|
||||||
|
const children = []
|
||||||
|
|
||||||
|
const keys = opt.sort ? Object.keys(obj).sort() : Object.keys(obj)
|
||||||
|
|
||||||
|
let padToChars = 0
|
||||||
|
// If aligning on the separator, then padToChars is determined as follows:
|
||||||
|
// 1. Get the keys
|
||||||
|
// 2. Exclude keys pointing to objects unless the value is null or an array
|
||||||
|
// 3. Add `[]` to array keys
|
||||||
|
// 4. Ensure non empty set of keys
|
||||||
|
// 5. Reduce the set to the longest `safe` key
|
||||||
|
// 6. Get the `safe` length
|
||||||
|
if (opt.align) {
|
||||||
|
padToChars = safe(
|
||||||
|
(
|
||||||
|
keys
|
||||||
|
.filter(k => obj[k] === null || Array.isArray(obj[k]) || typeof obj[k] !== 'object')
|
||||||
|
.map(k => Array.isArray(obj[k]) ? `${k}[]` : k)
|
||||||
|
)
|
||||||
|
.concat([''])
|
||||||
|
.reduce((a, b) => safe(a).length >= safe(b).length ? a : b)
|
||||||
|
).length
|
||||||
|
}
|
||||||
|
|
||||||
|
let out = ''
|
||||||
|
const arraySuffix = opt.bracketedArray ? '[]' : ''
|
||||||
|
|
||||||
|
for (const k of keys) {
|
||||||
|
const val = obj[k]
|
||||||
|
if (val && Array.isArray(val)) {
|
||||||
|
for (const item of val) {
|
||||||
|
out += safe(`${k}${arraySuffix}`).padEnd(padToChars, ' ') + separator + safe(item) + eol
|
||||||
|
}
|
||||||
|
} else if (val && typeof val === 'object') {
|
||||||
|
children.push(k)
|
||||||
|
} else {
|
||||||
|
out += safe(k).padEnd(padToChars, ' ') + separator + safe(val) + eol
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opt.section && out.length) {
|
||||||
|
out = '[' + safe(opt.section) + ']' + (opt.newline ? eol + eol : eol) + out
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const k of children) {
|
||||||
|
const nk = splitSections(k, '.').join('\\.')
|
||||||
|
const section = (opt.section ? opt.section + '.' : '') + nk
|
||||||
|
const child = encode(obj[k], {
|
||||||
|
...opt,
|
||||||
|
section,
|
||||||
|
})
|
||||||
|
if (out.length && child.length) {
|
||||||
|
out += eol
|
||||||
|
}
|
||||||
|
|
||||||
|
out += child
|
||||||
|
}
|
||||||
|
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
function splitSections (str, separator) {
|
||||||
|
var lastMatchIndex = 0
|
||||||
|
var lastSeparatorIndex = 0
|
||||||
|
var nextIndex = 0
|
||||||
|
var sections = []
|
||||||
|
|
||||||
|
do {
|
||||||
|
nextIndex = str.indexOf(separator, lastMatchIndex)
|
||||||
|
|
||||||
|
if (nextIndex !== -1) {
|
||||||
|
lastMatchIndex = nextIndex + separator.length
|
||||||
|
|
||||||
|
if (nextIndex > 0 && str[nextIndex - 1] === '\\') {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
sections.push(str.slice(lastSeparatorIndex, nextIndex))
|
||||||
|
lastSeparatorIndex = nextIndex + separator.length
|
||||||
|
}
|
||||||
|
} while (nextIndex !== -1)
|
||||||
|
|
||||||
|
sections.push(str.slice(lastSeparatorIndex))
|
||||||
|
|
||||||
|
return sections
|
||||||
|
}
|
||||||
|
|
||||||
|
const decode = (str, opt = {}) => {
|
||||||
|
opt.bracketedArray = opt.bracketedArray !== false
|
||||||
|
const out = Object.create(null)
|
||||||
|
let p = out
|
||||||
|
let section = null
|
||||||
|
// section |key = value
|
||||||
|
const re = /^\[([^\]]*)\]\s*$|^([^=]+)(=(.*))?$/i
|
||||||
|
const lines = str.split(/[\r\n]+/g)
|
||||||
|
const duplicates = {}
|
||||||
|
|
||||||
|
for (const line of lines) {
|
||||||
|
if (!line || line.match(/^\s*[;#]/) || line.match(/^\s*$/)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
const match = line.match(re)
|
||||||
|
if (!match) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if (match[1] !== undefined) {
|
||||||
|
section = unsafe(match[1])
|
||||||
|
if (section === '__proto__') {
|
||||||
|
// not allowed
|
||||||
|
// keep parsing the section, but don't attach it.
|
||||||
|
p = Object.create(null)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
p = out[section] = out[section] || Object.create(null)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
const keyRaw = unsafe(match[2])
|
||||||
|
let isArray
|
||||||
|
if (opt.bracketedArray) {
|
||||||
|
isArray = keyRaw.length > 2 && keyRaw.slice(-2) === '[]'
|
||||||
|
} else {
|
||||||
|
duplicates[keyRaw] = (duplicates?.[keyRaw] || 0) + 1
|
||||||
|
isArray = duplicates[keyRaw] > 1
|
||||||
|
}
|
||||||
|
const key = isArray && keyRaw.endsWith('[]')
|
||||||
|
? keyRaw.slice(0, -2) : keyRaw
|
||||||
|
|
||||||
|
if (key === '__proto__') {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
const valueRaw = match[3] ? unsafe(match[4]) : true
|
||||||
|
const value = valueRaw === 'true' ||
|
||||||
|
valueRaw === 'false' ||
|
||||||
|
valueRaw === 'null' ? JSON.parse(valueRaw)
|
||||||
|
: valueRaw
|
||||||
|
|
||||||
|
// Convert keys with '[]' suffix to an array
|
||||||
|
if (isArray) {
|
||||||
|
if (!hasOwnProperty.call(p, key)) {
|
||||||
|
p[key] = []
|
||||||
|
} else if (!Array.isArray(p[key])) {
|
||||||
|
p[key] = [p[key]]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// safeguard against resetting a previously defined
|
||||||
|
// array by accidentally forgetting the brackets
|
||||||
|
if (Array.isArray(p[key])) {
|
||||||
|
p[key].push(value)
|
||||||
|
} else {
|
||||||
|
p[key] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// {a:{y:1},"a.b":{x:2}} --> {a:{y:1,b:{x:2}}}
|
||||||
|
// use a filter to return the keys that have to be deleted.
|
||||||
|
const remove = []
|
||||||
|
for (const k of Object.keys(out)) {
|
||||||
|
if (!hasOwnProperty.call(out, k) ||
|
||||||
|
typeof out[k] !== 'object' ||
|
||||||
|
Array.isArray(out[k])) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// see if the parent section is also an object.
|
||||||
|
// if so, add it to that, and mark this one for deletion
|
||||||
|
const parts = splitSections(k, '.')
|
||||||
|
p = out
|
||||||
|
const l = parts.pop()
|
||||||
|
const nl = l.replace(/\\\./g, '.')
|
||||||
|
for (const part of parts) {
|
||||||
|
if (part === '__proto__') {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if (!hasOwnProperty.call(p, part) || typeof p[part] !== 'object') {
|
||||||
|
p[part] = Object.create(null)
|
||||||
|
}
|
||||||
|
p = p[part]
|
||||||
|
}
|
||||||
|
if (p === out && nl === l) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
p[nl] = out[k]
|
||||||
|
remove.push(k)
|
||||||
|
}
|
||||||
|
for (const del of remove) {
|
||||||
|
delete out[del]
|
||||||
|
}
|
||||||
|
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
const isQuoted = val => {
|
||||||
|
return (val.startsWith('"') && val.endsWith('"')) ||
|
||||||
|
(val.startsWith("'") && val.endsWith("'"))
|
||||||
|
}
|
||||||
|
|
||||||
|
const safe = val => {
|
||||||
|
if (
|
||||||
|
typeof val !== 'string' ||
|
||||||
|
val.match(/[=\r\n]/) ||
|
||||||
|
val.match(/^\[/) ||
|
||||||
|
(val.length > 1 && isQuoted(val)) ||
|
||||||
|
val !== val.trim()
|
||||||
|
) {
|
||||||
|
return JSON.stringify(val)
|
||||||
|
}
|
||||||
|
return val.split(';').join('\\;').split('#').join('\\#')
|
||||||
|
}
|
||||||
|
|
||||||
|
const unsafe = val => {
|
||||||
|
val = (val || '').trim()
|
||||||
|
if (isQuoted(val)) {
|
||||||
|
// remove the single quotes before calling JSON.parse
|
||||||
|
if (val.charAt(0) === "'") {
|
||||||
|
val = val.slice(1, -1)
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
val = JSON.parse(val)
|
||||||
|
} catch {
|
||||||
|
// ignore errors
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// walk the val to find the first not-escaped ; character
|
||||||
|
let esc = false
|
||||||
|
let unesc = ''
|
||||||
|
for (let i = 0, l = val.length; i < l; i++) {
|
||||||
|
const c = val.charAt(i)
|
||||||
|
if (esc) {
|
||||||
|
if ('\\;#'.indexOf(c) !== -1) {
|
||||||
|
unesc += c
|
||||||
|
} else {
|
||||||
|
unesc += '\\' + c
|
||||||
|
}
|
||||||
|
|
||||||
|
esc = false
|
||||||
|
} else if (';#'.indexOf(c) !== -1) {
|
||||||
|
break
|
||||||
|
} else if (c === '\\') {
|
||||||
|
esc = true
|
||||||
|
} else {
|
||||||
|
unesc += c
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (esc) {
|
||||||
|
unesc += '\\'
|
||||||
|
}
|
||||||
|
|
||||||
|
return unesc.trim()
|
||||||
|
}
|
||||||
|
return val
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
parse: decode,
|
||||||
|
decode,
|
||||||
|
stringify: encode,
|
||||||
|
encode,
|
||||||
|
safe,
|
||||||
|
unsafe,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|
||||||
/***/ 9829:
|
/***/ 9829:
|
||||||
@@ -88244,6 +88531,7 @@ const core = __importStar(__nccwpck_require__(7484));
|
|||||||
const exec = __importStar(__nccwpck_require__(5236));
|
const exec = __importStar(__nccwpck_require__(5236));
|
||||||
const io = __importStar(__nccwpck_require__(4994));
|
const io = __importStar(__nccwpck_require__(4994));
|
||||||
const fs_1 = __importDefault(__nccwpck_require__(9896));
|
const fs_1 = __importDefault(__nccwpck_require__(9896));
|
||||||
|
const INI = __importStar(__nccwpck_require__(5756));
|
||||||
const path_1 = __importDefault(__nccwpck_require__(6928));
|
const path_1 = __importDefault(__nccwpck_require__(6928));
|
||||||
function getNodeVersionFromFile(versionFilePath) {
|
function getNodeVersionFromFile(versionFilePath) {
|
||||||
var _a, _b, _c, _d, _e;
|
var _a, _b, _c, _d, _e;
|
||||||
@@ -88286,6 +88574,22 @@ function getNodeVersionFromFile(versionFilePath) {
|
|||||||
catch (_f) {
|
catch (_f) {
|
||||||
core.info('Node version file is not JSON file');
|
core.info('Node version file is not JSON file');
|
||||||
}
|
}
|
||||||
|
// Try parsing the file as an NPM `.npmrc` file.
|
||||||
|
//
|
||||||
|
// If the file contents contain the use-node-version key, we conclude it's an
|
||||||
|
// `.npmrc` file.
|
||||||
|
if (contents.match(/use-node-version *=/)) {
|
||||||
|
const manifest = INI.parse(contents);
|
||||||
|
const key = 'use-node-version';
|
||||||
|
if (key in manifest && typeof manifest[key] === 'string') {
|
||||||
|
const version = manifest[key];
|
||||||
|
core.info(`Using node version ${version} from global INI ${key}`);
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
// We didn't find the key `use-node-version` in the global scope of the
|
||||||
|
// `.npmrc` file, so we return.
|
||||||
|
return null;
|
||||||
|
}
|
||||||
const found = contents.match(/^(?:node(js)?\s+)?v?(?<version>[^\s]+)$/m);
|
const found = contents.match(/^(?:node(js)?\s+)?v?(?<version>[^\s]+)$/m);
|
||||||
return (_e = (_d = found === null || found === void 0 ? void 0 : found.groups) === null || _d === void 0 ? void 0 : _d.version) !== null && _e !== void 0 ? _e : contents.trim();
|
return (_e = (_d = found === null || found === void 0 ? void 0 : found.groups) === null || _d === void 0 ? void 0 : _d.version) !== null && _e !== void 0 ? _e : contents.trim();
|
||||||
}
|
}
|
||||||
|
|||||||
358
dist/setup/index.js
vendored
358
dist/setup/index.js
vendored
@@ -58557,6 +58557,293 @@ class Deprecation extends Error {
|
|||||||
exports.Deprecation = Deprecation;
|
exports.Deprecation = Deprecation;
|
||||||
|
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 5756:
|
||||||
|
/***/ ((module) => {
|
||||||
|
|
||||||
|
const { hasOwnProperty } = Object.prototype
|
||||||
|
|
||||||
|
const encode = (obj, opt = {}) => {
|
||||||
|
if (typeof opt === 'string') {
|
||||||
|
opt = { section: opt }
|
||||||
|
}
|
||||||
|
opt.align = opt.align === true
|
||||||
|
opt.newline = opt.newline === true
|
||||||
|
opt.sort = opt.sort === true
|
||||||
|
opt.whitespace = opt.whitespace === true || opt.align === true
|
||||||
|
// The `typeof` check is required because accessing the `process` directly fails on browsers.
|
||||||
|
/* istanbul ignore next */
|
||||||
|
opt.platform = opt.platform || (typeof process !== 'undefined' && process.platform)
|
||||||
|
opt.bracketedArray = opt.bracketedArray !== false
|
||||||
|
|
||||||
|
/* istanbul ignore next */
|
||||||
|
const eol = opt.platform === 'win32' ? '\r\n' : '\n'
|
||||||
|
const separator = opt.whitespace ? ' = ' : '='
|
||||||
|
const children = []
|
||||||
|
|
||||||
|
const keys = opt.sort ? Object.keys(obj).sort() : Object.keys(obj)
|
||||||
|
|
||||||
|
let padToChars = 0
|
||||||
|
// If aligning on the separator, then padToChars is determined as follows:
|
||||||
|
// 1. Get the keys
|
||||||
|
// 2. Exclude keys pointing to objects unless the value is null or an array
|
||||||
|
// 3. Add `[]` to array keys
|
||||||
|
// 4. Ensure non empty set of keys
|
||||||
|
// 5. Reduce the set to the longest `safe` key
|
||||||
|
// 6. Get the `safe` length
|
||||||
|
if (opt.align) {
|
||||||
|
padToChars = safe(
|
||||||
|
(
|
||||||
|
keys
|
||||||
|
.filter(k => obj[k] === null || Array.isArray(obj[k]) || typeof obj[k] !== 'object')
|
||||||
|
.map(k => Array.isArray(obj[k]) ? `${k}[]` : k)
|
||||||
|
)
|
||||||
|
.concat([''])
|
||||||
|
.reduce((a, b) => safe(a).length >= safe(b).length ? a : b)
|
||||||
|
).length
|
||||||
|
}
|
||||||
|
|
||||||
|
let out = ''
|
||||||
|
const arraySuffix = opt.bracketedArray ? '[]' : ''
|
||||||
|
|
||||||
|
for (const k of keys) {
|
||||||
|
const val = obj[k]
|
||||||
|
if (val && Array.isArray(val)) {
|
||||||
|
for (const item of val) {
|
||||||
|
out += safe(`${k}${arraySuffix}`).padEnd(padToChars, ' ') + separator + safe(item) + eol
|
||||||
|
}
|
||||||
|
} else if (val && typeof val === 'object') {
|
||||||
|
children.push(k)
|
||||||
|
} else {
|
||||||
|
out += safe(k).padEnd(padToChars, ' ') + separator + safe(val) + eol
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opt.section && out.length) {
|
||||||
|
out = '[' + safe(opt.section) + ']' + (opt.newline ? eol + eol : eol) + out
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const k of children) {
|
||||||
|
const nk = splitSections(k, '.').join('\\.')
|
||||||
|
const section = (opt.section ? opt.section + '.' : '') + nk
|
||||||
|
const child = encode(obj[k], {
|
||||||
|
...opt,
|
||||||
|
section,
|
||||||
|
})
|
||||||
|
if (out.length && child.length) {
|
||||||
|
out += eol
|
||||||
|
}
|
||||||
|
|
||||||
|
out += child
|
||||||
|
}
|
||||||
|
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
function splitSections (str, separator) {
|
||||||
|
var lastMatchIndex = 0
|
||||||
|
var lastSeparatorIndex = 0
|
||||||
|
var nextIndex = 0
|
||||||
|
var sections = []
|
||||||
|
|
||||||
|
do {
|
||||||
|
nextIndex = str.indexOf(separator, lastMatchIndex)
|
||||||
|
|
||||||
|
if (nextIndex !== -1) {
|
||||||
|
lastMatchIndex = nextIndex + separator.length
|
||||||
|
|
||||||
|
if (nextIndex > 0 && str[nextIndex - 1] === '\\') {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
sections.push(str.slice(lastSeparatorIndex, nextIndex))
|
||||||
|
lastSeparatorIndex = nextIndex + separator.length
|
||||||
|
}
|
||||||
|
} while (nextIndex !== -1)
|
||||||
|
|
||||||
|
sections.push(str.slice(lastSeparatorIndex))
|
||||||
|
|
||||||
|
return sections
|
||||||
|
}
|
||||||
|
|
||||||
|
const decode = (str, opt = {}) => {
|
||||||
|
opt.bracketedArray = opt.bracketedArray !== false
|
||||||
|
const out = Object.create(null)
|
||||||
|
let p = out
|
||||||
|
let section = null
|
||||||
|
// section |key = value
|
||||||
|
const re = /^\[([^\]]*)\]\s*$|^([^=]+)(=(.*))?$/i
|
||||||
|
const lines = str.split(/[\r\n]+/g)
|
||||||
|
const duplicates = {}
|
||||||
|
|
||||||
|
for (const line of lines) {
|
||||||
|
if (!line || line.match(/^\s*[;#]/) || line.match(/^\s*$/)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
const match = line.match(re)
|
||||||
|
if (!match) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if (match[1] !== undefined) {
|
||||||
|
section = unsafe(match[1])
|
||||||
|
if (section === '__proto__') {
|
||||||
|
// not allowed
|
||||||
|
// keep parsing the section, but don't attach it.
|
||||||
|
p = Object.create(null)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
p = out[section] = out[section] || Object.create(null)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
const keyRaw = unsafe(match[2])
|
||||||
|
let isArray
|
||||||
|
if (opt.bracketedArray) {
|
||||||
|
isArray = keyRaw.length > 2 && keyRaw.slice(-2) === '[]'
|
||||||
|
} else {
|
||||||
|
duplicates[keyRaw] = (duplicates?.[keyRaw] || 0) + 1
|
||||||
|
isArray = duplicates[keyRaw] > 1
|
||||||
|
}
|
||||||
|
const key = isArray && keyRaw.endsWith('[]')
|
||||||
|
? keyRaw.slice(0, -2) : keyRaw
|
||||||
|
|
||||||
|
if (key === '__proto__') {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
const valueRaw = match[3] ? unsafe(match[4]) : true
|
||||||
|
const value = valueRaw === 'true' ||
|
||||||
|
valueRaw === 'false' ||
|
||||||
|
valueRaw === 'null' ? JSON.parse(valueRaw)
|
||||||
|
: valueRaw
|
||||||
|
|
||||||
|
// Convert keys with '[]' suffix to an array
|
||||||
|
if (isArray) {
|
||||||
|
if (!hasOwnProperty.call(p, key)) {
|
||||||
|
p[key] = []
|
||||||
|
} else if (!Array.isArray(p[key])) {
|
||||||
|
p[key] = [p[key]]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// safeguard against resetting a previously defined
|
||||||
|
// array by accidentally forgetting the brackets
|
||||||
|
if (Array.isArray(p[key])) {
|
||||||
|
p[key].push(value)
|
||||||
|
} else {
|
||||||
|
p[key] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// {a:{y:1},"a.b":{x:2}} --> {a:{y:1,b:{x:2}}}
|
||||||
|
// use a filter to return the keys that have to be deleted.
|
||||||
|
const remove = []
|
||||||
|
for (const k of Object.keys(out)) {
|
||||||
|
if (!hasOwnProperty.call(out, k) ||
|
||||||
|
typeof out[k] !== 'object' ||
|
||||||
|
Array.isArray(out[k])) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// see if the parent section is also an object.
|
||||||
|
// if so, add it to that, and mark this one for deletion
|
||||||
|
const parts = splitSections(k, '.')
|
||||||
|
p = out
|
||||||
|
const l = parts.pop()
|
||||||
|
const nl = l.replace(/\\\./g, '.')
|
||||||
|
for (const part of parts) {
|
||||||
|
if (part === '__proto__') {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if (!hasOwnProperty.call(p, part) || typeof p[part] !== 'object') {
|
||||||
|
p[part] = Object.create(null)
|
||||||
|
}
|
||||||
|
p = p[part]
|
||||||
|
}
|
||||||
|
if (p === out && nl === l) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
p[nl] = out[k]
|
||||||
|
remove.push(k)
|
||||||
|
}
|
||||||
|
for (const del of remove) {
|
||||||
|
delete out[del]
|
||||||
|
}
|
||||||
|
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
const isQuoted = val => {
|
||||||
|
return (val.startsWith('"') && val.endsWith('"')) ||
|
||||||
|
(val.startsWith("'") && val.endsWith("'"))
|
||||||
|
}
|
||||||
|
|
||||||
|
const safe = val => {
|
||||||
|
if (
|
||||||
|
typeof val !== 'string' ||
|
||||||
|
val.match(/[=\r\n]/) ||
|
||||||
|
val.match(/^\[/) ||
|
||||||
|
(val.length > 1 && isQuoted(val)) ||
|
||||||
|
val !== val.trim()
|
||||||
|
) {
|
||||||
|
return JSON.stringify(val)
|
||||||
|
}
|
||||||
|
return val.split(';').join('\\;').split('#').join('\\#')
|
||||||
|
}
|
||||||
|
|
||||||
|
const unsafe = val => {
|
||||||
|
val = (val || '').trim()
|
||||||
|
if (isQuoted(val)) {
|
||||||
|
// remove the single quotes before calling JSON.parse
|
||||||
|
if (val.charAt(0) === "'") {
|
||||||
|
val = val.slice(1, -1)
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
val = JSON.parse(val)
|
||||||
|
} catch {
|
||||||
|
// ignore errors
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// walk the val to find the first not-escaped ; character
|
||||||
|
let esc = false
|
||||||
|
let unesc = ''
|
||||||
|
for (let i = 0, l = val.length; i < l; i++) {
|
||||||
|
const c = val.charAt(i)
|
||||||
|
if (esc) {
|
||||||
|
if ('\\;#'.indexOf(c) !== -1) {
|
||||||
|
unesc += c
|
||||||
|
} else {
|
||||||
|
unesc += '\\' + c
|
||||||
|
}
|
||||||
|
|
||||||
|
esc = false
|
||||||
|
} else if (';#'.indexOf(c) !== -1) {
|
||||||
|
break
|
||||||
|
} else if (c === '\\') {
|
||||||
|
esc = true
|
||||||
|
} else {
|
||||||
|
unesc += c
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (esc) {
|
||||||
|
unesc += '\\'
|
||||||
|
}
|
||||||
|
|
||||||
|
return unesc.trim()
|
||||||
|
}
|
||||||
|
return val
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
parse: decode,
|
||||||
|
decode,
|
||||||
|
stringify: encode,
|
||||||
|
encode,
|
||||||
|
safe,
|
||||||
|
unsafe,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|
||||||
/***/ 3407:
|
/***/ 3407:
|
||||||
@@ -97211,9 +97498,13 @@ class BaseDistribution {
|
|||||||
}
|
}
|
||||||
getNodeJsVersions() {
|
getNodeJsVersions() {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
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 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 || [];
|
return response.result || [];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -97228,7 +97519,7 @@ class BaseDistribution {
|
|||||||
? `${fileName}.zip`
|
? `${fileName}.zip`
|
||||||
: `${fileName}.7z`
|
: `${fileName}.7z`
|
||||||
: `${fileName}.tar.gz`;
|
: `${fileName}.tar.gz`;
|
||||||
const initialUrl = this.getDistributionUrl();
|
const initialUrl = this.getDistributionUrl(this.nodeInfo.mirror);
|
||||||
const url = `${initialUrl}/v${version}/${urlFileName}`;
|
const url = `${initialUrl}/v${version}/${urlFileName}`;
|
||||||
return {
|
return {
|
||||||
downloadUrl: url,
|
downloadUrl: url,
|
||||||
@@ -97242,7 +97533,7 @@ class BaseDistribution {
|
|||||||
let downloadPath = '';
|
let downloadPath = '';
|
||||||
core.info(`Acquiring ${info.resolvedVersion} - ${info.arch} from ${info.downloadUrl}`);
|
core.info(`Acquiring ${info.resolvedVersion} - ${info.arch} from ${info.downloadUrl}`);
|
||||||
try {
|
try {
|
||||||
downloadPath = yield tc.downloadTool(info.downloadUrl);
|
downloadPath = yield tc.downloadTool(info.downloadUrl, undefined, this.nodeInfo.mirrorToken);
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
if (err instanceof tc.HTTPError &&
|
if (err instanceof tc.HTTPError &&
|
||||||
@@ -97266,7 +97557,7 @@ class BaseDistribution {
|
|||||||
}
|
}
|
||||||
acquireWindowsNodeFromFallbackLocation(version_1) {
|
acquireWindowsNodeFromFallbackLocation(version_1) {
|
||||||
return __awaiter(this, arguments, void 0, function* (version, arch = os_1.default.arch()) {
|
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);
|
const osArch = this.translateArchToDistUrl(arch);
|
||||||
// Create temporary folder to download to
|
// Create temporary folder to download to
|
||||||
const tempDownloadFolder = `temp_${(0, uuid_1.v4)()}`;
|
const tempDownloadFolder = `temp_${(0, uuid_1.v4)()}`;
|
||||||
@@ -97280,18 +97571,18 @@ class BaseDistribution {
|
|||||||
exeUrl = `${initialUrl}/v${version}/win-${osArch}/node.exe`;
|
exeUrl = `${initialUrl}/v${version}/win-${osArch}/node.exe`;
|
||||||
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}`);
|
||||||
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'));
|
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'));
|
yield io.cp(libPath, path.join(tempDir, 'node.lib'));
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
if (err instanceof tc.HTTPError && err.httpStatusCode == 404) {
|
if (err instanceof tc.HTTPError && err.httpStatusCode == 404) {
|
||||||
exeUrl = `${initialUrl}/v${version}/node.exe`;
|
exeUrl = `${initialUrl}/v${version}/node.exe`;
|
||||||
libUrl = `${initialUrl}/v${version}/node.lib`;
|
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'));
|
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'));
|
yield io.cp(libPath, path.join(tempDir, 'node.lib'));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -97454,8 +97745,9 @@ class NightlyNodejs extends base_distribution_prerelease_1.default {
|
|||||||
super(nodeInfo);
|
super(nodeInfo);
|
||||||
this.distribution = 'nightly';
|
this.distribution = 'nightly';
|
||||||
}
|
}
|
||||||
getDistributionUrl() {
|
getDistributionUrl(mirror) {
|
||||||
return 'https://nodejs.org/download/nightly';
|
const url = mirror || 'https://nodejs.org';
|
||||||
|
return `${url}/download/nightly`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exports["default"] = NightlyNodejs;
|
exports["default"] = NightlyNodejs;
|
||||||
@@ -97553,13 +97845,13 @@ class OfficialBuilds extends base_distribution_1.default {
|
|||||||
const versionInfo = yield this.getInfoFromManifest(this.nodeInfo.versionSpec, this.nodeInfo.stable, osArch, manifest);
|
const versionInfo = yield this.getInfoFromManifest(this.nodeInfo.versionSpec, this.nodeInfo.stable, osArch, manifest);
|
||||||
if (versionInfo) {
|
if (versionInfo) {
|
||||||
core.info(`Acquiring ${versionInfo.resolvedVersion} - ${versionInfo.arch} from ${versionInfo.downloadUrl}`);
|
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) {
|
if (downloadPath) {
|
||||||
toolPath = yield this.extractArchive(downloadPath, versionInfo, false);
|
toolPath = yield this.extractArchive(downloadPath, versionInfo, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
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) {
|
catch (err) {
|
||||||
@@ -97621,12 +97913,13 @@ class OfficialBuilds extends base_distribution_1.default {
|
|||||||
version = super.evaluateVersions(versions);
|
version = super.evaluateVersions(versions);
|
||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
getDistributionUrl() {
|
getDistributionUrl(mirror) {
|
||||||
return `https://nodejs.org/dist`;
|
const url = mirror || 'https://nodejs.org';
|
||||||
|
return `${url}/dist`;
|
||||||
}
|
}
|
||||||
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.mirror ? this.nodeInfo.mirrorToken : this.nodeInfo.auth, 'main');
|
||||||
}
|
}
|
||||||
resolveLtsAliasFromManifest(versionSpec, stable, manifest) {
|
resolveLtsAliasFromManifest(versionSpec, stable, manifest) {
|
||||||
var _a;
|
var _a;
|
||||||
@@ -97709,8 +98002,9 @@ class RcBuild extends base_distribution_1.default {
|
|||||||
constructor(nodeInfo) {
|
constructor(nodeInfo) {
|
||||||
super(nodeInfo);
|
super(nodeInfo);
|
||||||
}
|
}
|
||||||
getDistributionUrl() {
|
getDistributionUrl(mirror) {
|
||||||
return 'https://nodejs.org/download/rc';
|
const url = mirror || 'https://nodejs.org';
|
||||||
|
return `${url}/download/rc`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exports["default"] = RcBuild;
|
exports["default"] = RcBuild;
|
||||||
@@ -97733,8 +98027,9 @@ class CanaryBuild extends base_distribution_prerelease_1.default {
|
|||||||
super(nodeInfo);
|
super(nodeInfo);
|
||||||
this.distribution = 'v8-canary';
|
this.distribution = 'v8-canary';
|
||||||
}
|
}
|
||||||
getDistributionUrl() {
|
getDistributionUrl(mirror) {
|
||||||
return 'https://nodejs.org/download/v8-canary';
|
const url = mirror || 'https://nodejs.org';
|
||||||
|
return `${url}/download/v8-canary`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exports["default"] = CanaryBuild;
|
exports["default"] = CanaryBuild;
|
||||||
@@ -97814,6 +98109,8 @@ function run() {
|
|||||||
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}`;
|
||||||
|
const mirror = core.getInput('mirror');
|
||||||
|
const mirrorToken = core.getInput('mirror-token');
|
||||||
const stable = (core.getInput('stable') || 'true').toUpperCase() === 'TRUE';
|
const stable = (core.getInput('stable') || 'true').toUpperCase() === 'TRUE';
|
||||||
const checkLatest = (core.getInput('check-latest') || 'false').toUpperCase() === 'TRUE';
|
const checkLatest = (core.getInput('check-latest') || 'false').toUpperCase() === 'TRUE';
|
||||||
const nodejsInfo = {
|
const nodejsInfo = {
|
||||||
@@ -97821,7 +98118,9 @@ function run() {
|
|||||||
checkLatest,
|
checkLatest,
|
||||||
auth,
|
auth,
|
||||||
stable,
|
stable,
|
||||||
arch
|
arch,
|
||||||
|
mirror,
|
||||||
|
mirrorToken
|
||||||
};
|
};
|
||||||
const nodeDistribution = (0, installer_factory_1.getNodejsDistribution)(nodejsInfo);
|
const nodeDistribution = (0, installer_factory_1.getNodejsDistribution)(nodejsInfo);
|
||||||
yield nodeDistribution.setupNodeJs();
|
yield nodeDistribution.setupNodeJs();
|
||||||
@@ -97920,6 +98219,7 @@ const core = __importStar(__nccwpck_require__(7484));
|
|||||||
const exec = __importStar(__nccwpck_require__(5236));
|
const exec = __importStar(__nccwpck_require__(5236));
|
||||||
const io = __importStar(__nccwpck_require__(4994));
|
const io = __importStar(__nccwpck_require__(4994));
|
||||||
const fs_1 = __importDefault(__nccwpck_require__(9896));
|
const fs_1 = __importDefault(__nccwpck_require__(9896));
|
||||||
|
const INI = __importStar(__nccwpck_require__(5756));
|
||||||
const path_1 = __importDefault(__nccwpck_require__(6928));
|
const path_1 = __importDefault(__nccwpck_require__(6928));
|
||||||
function getNodeVersionFromFile(versionFilePath) {
|
function getNodeVersionFromFile(versionFilePath) {
|
||||||
var _a, _b, _c, _d, _e;
|
var _a, _b, _c, _d, _e;
|
||||||
@@ -97962,6 +98262,22 @@ function getNodeVersionFromFile(versionFilePath) {
|
|||||||
catch (_f) {
|
catch (_f) {
|
||||||
core.info('Node version file is not JSON file');
|
core.info('Node version file is not JSON file');
|
||||||
}
|
}
|
||||||
|
// Try parsing the file as an NPM `.npmrc` file.
|
||||||
|
//
|
||||||
|
// If the file contents contain the use-node-version key, we conclude it's an
|
||||||
|
// `.npmrc` file.
|
||||||
|
if (contents.match(/use-node-version *=/)) {
|
||||||
|
const manifest = INI.parse(contents);
|
||||||
|
const key = 'use-node-version';
|
||||||
|
if (key in manifest && typeof manifest[key] === 'string') {
|
||||||
|
const version = manifest[key];
|
||||||
|
core.info(`Using node version ${version} from global INI ${key}`);
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
// We didn't find the key `use-node-version` in the global scope of the
|
||||||
|
// `.npmrc` file, so we return.
|
||||||
|
return null;
|
||||||
|
}
|
||||||
const found = contents.match(/^(?:node(js)?\s+)?v?(?<version>[^\s]+)$/m);
|
const found = contents.match(/^(?:node(js)?\s+)?v?(?<version>[^\s]+)$/m);
|
||||||
return (_e = (_d = found === null || found === void 0 ? void 0 : found.groups) === null || _d === void 0 ? void 0 : _d.version) !== null && _e !== void 0 ? _e : contents.trim();
|
return (_e = (_d = found === null || found === void 0 ? void 0 : found.groups) === null || _d === void 0 ? void 0 : _d.version) !== null && _e !== void 0 ? _e : contents.trim();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ steps:
|
|||||||
|
|
||||||
## Node version file
|
## Node version file
|
||||||
|
|
||||||
The `node-version-file` input accepts a path to a file containing the version of Node.js to be used by a project, for example `.nvmrc`, `.node-version`, `.tool-versions`, or `package.json`. If both the `node-version` and the `node-version-file` inputs are provided then the `node-version` input is used.
|
The `node-version-file` input accepts a path to a file containing the version of Node.js to be used by a project, for example `.nvmrc`, `.node-version`, `.tool-versions`, `package.json`, or `.npmrc`. If both the `node-version` and the `node-version-file` inputs are provided then the `node-version` input is used.
|
||||||
See [supported version syntax](https://github.com/actions/setup-node#supported-version-syntax).
|
See [supported version syntax](https://github.com/actions/setup-node#supported-version-syntax).
|
||||||
|
|
||||||
> The action will search for the node version file relative to the repository root.
|
> The action will search for the node version file relative to the repository root.
|
||||||
@@ -418,3 +418,18 @@ Please refer to the [Ensuring workflow access to your package - Configuring a pa
|
|||||||
|
|
||||||
### always-auth input
|
### 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.
|
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'
|
||||||
|
```
|
||||||
|
|||||||
17
package-lock.json
generated
17
package-lock.json
generated
@@ -17,6 +17,8 @@
|
|||||||
"@actions/http-client": "^2.2.1",
|
"@actions/http-client": "^2.2.1",
|
||||||
"@actions/io": "^1.0.2",
|
"@actions/io": "^1.0.2",
|
||||||
"@actions/tool-cache": "^2.0.2",
|
"@actions/tool-cache": "^2.0.2",
|
||||||
|
"@types/ini": "^4.1.1",
|
||||||
|
"ini": "^5.0.0",
|
||||||
"semver": "^7.6.3",
|
"semver": "^7.6.3",
|
||||||
"uuid": "^9.0.1"
|
"uuid": "^9.0.1"
|
||||||
},
|
},
|
||||||
@@ -1822,6 +1824,12 @@
|
|||||||
"@types/node": "*"
|
"@types/node": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/ini": {
|
||||||
|
"version": "4.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/ini/-/ini-4.1.1.tgz",
|
||||||
|
"integrity": "sha512-MIyNUZipBTbyUNnhvuXJTY7B6qNI78meck9Jbv3wk0OgNwRyOOVEKDutAkOs1snB/tx0FafyR6/SN4Ps0hZPeg==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/@types/istanbul-lib-coverage": {
|
"node_modules/@types/istanbul-lib-coverage": {
|
||||||
"version": "2.0.5",
|
"version": "2.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz",
|
||||||
@@ -3571,6 +3579,15 @@
|
|||||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
|
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/ini": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ini/-/ini-5.0.0.tgz",
|
||||||
|
"integrity": "sha512-+N0ngpO3e7cRUWOJAS7qw0IZIVc6XPrW4MlFBdD066F2L4k1L6ker3hLqSq7iXxU5tgS4WGkIUElWn5vogAEnw==",
|
||||||
|
"license": "ISC",
|
||||||
|
"engines": {
|
||||||
|
"node": "^18.17.0 || >=20.5.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/is-arrayish": {
|
"node_modules/is-arrayish": {
|
||||||
"version": "0.2.1",
|
"version": "0.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
|
||||||
|
|||||||
@@ -33,6 +33,8 @@
|
|||||||
"@actions/http-client": "^2.2.1",
|
"@actions/http-client": "^2.2.1",
|
||||||
"@actions/io": "^1.0.2",
|
"@actions/io": "^1.0.2",
|
||||||
"@actions/tool-cache": "^2.0.2",
|
"@actions/tool-cache": "^2.0.2",
|
||||||
|
"ini": "^5.0.0",
|
||||||
|
"@types/ini": "^4.1.1",
|
||||||
"semver": "^7.6.3",
|
"semver": "^7.6.3",
|
||||||
"uuid": "^9.0.1"
|
"uuid": "^9.0.1"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ export default abstract class BaseDistribution {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract getDistributionUrl(): string;
|
protected abstract getDistributionUrl(mirror: string): string;
|
||||||
|
|
||||||
public async setupNodeJs() {
|
public async setupNodeJs() {
|
||||||
let nodeJsVersions: INodeVersion[] | undefined;
|
let nodeJsVersions: INodeVersion[] | undefined;
|
||||||
@@ -97,10 +97,19 @@ export default abstract class BaseDistribution {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected async getNodeJsVersions(): Promise<INodeVersion[]> {
|
protected async getNodeJsVersions(): Promise<INodeVersion[]> {
|
||||||
const initialUrl = this.getDistributionUrl();
|
const initialUrl = this.getDistributionUrl(this.nodeInfo.mirror);
|
||||||
const dataUrl = `${initialUrl}/index.json`;
|
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 || [];
|
return response.result || [];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,7 +126,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.getDistributionUrl(this.nodeInfo.mirror);
|
||||||
const url = `${initialUrl}/v${version}/${urlFileName}`;
|
const url = `${initialUrl}/v${version}/${urlFileName}`;
|
||||||
|
|
||||||
return <INodeVersionInfo>{
|
return <INodeVersionInfo>{
|
||||||
@@ -134,7 +143,11 @@ export default abstract class BaseDistribution {
|
|||||||
`Acquiring ${info.resolvedVersion} - ${info.arch} from ${info.downloadUrl}`
|
`Acquiring ${info.resolvedVersion} - ${info.arch} from ${info.downloadUrl}`
|
||||||
);
|
);
|
||||||
try {
|
try {
|
||||||
downloadPath = await tc.downloadTool(info.downloadUrl);
|
downloadPath = await tc.downloadTool(
|
||||||
|
info.downloadUrl,
|
||||||
|
undefined,
|
||||||
|
this.nodeInfo.mirrorToken
|
||||||
|
);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (
|
if (
|
||||||
err instanceof tc.HTTPError &&
|
err instanceof tc.HTTPError &&
|
||||||
@@ -168,7 +181,7 @@ export default abstract class BaseDistribution {
|
|||||||
version: string,
|
version: string,
|
||||||
arch: string = os.arch()
|
arch: string = os.arch()
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
const initialUrl = this.getDistributionUrl();
|
const initialUrl = this.getDistributionUrl(this.nodeInfo.mirror);
|
||||||
const osArch: string = this.translateArchToDistUrl(arch);
|
const osArch: string = this.translateArchToDistUrl(arch);
|
||||||
|
|
||||||
// Create temporary folder to download to
|
// Create temporary folder to download to
|
||||||
@@ -185,18 +198,34 @@ export default abstract class BaseDistribution {
|
|||||||
|
|
||||||
core.info(`Downloading only node binary from ${exeUrl}`);
|
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'));
|
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'));
|
await io.cp(libPath, path.join(tempDir, 'node.lib'));
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err instanceof tc.HTTPError && err.httpStatusCode == 404) {
|
if (err instanceof tc.HTTPError && err.httpStatusCode == 404) {
|
||||||
exeUrl = `${initialUrl}/v${version}/node.exe`;
|
exeUrl = `${initialUrl}/v${version}/node.exe`;
|
||||||
libUrl = `${initialUrl}/v${version}/node.lib`;
|
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'));
|
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'));
|
await io.cp(libPath, path.join(tempDir, 'node.lib'));
|
||||||
} else {
|
} else {
|
||||||
throw err;
|
throw err;
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ export interface NodeInputs {
|
|||||||
auth?: string;
|
auth?: string;
|
||||||
checkLatest: boolean;
|
checkLatest: boolean;
|
||||||
stable: boolean;
|
stable: boolean;
|
||||||
|
mirror: string;
|
||||||
|
mirrorToken: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface INodeVersionInfo {
|
export interface INodeVersionInfo {
|
||||||
|
|||||||
@@ -7,7 +7,8 @@ export default class NightlyNodejs extends BasePrereleaseNodejs {
|
|||||||
super(nodeInfo);
|
super(nodeInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected getDistributionUrl(): string {
|
protected getDistributionUrl(mirror: string): string {
|
||||||
return 'https://nodejs.org/download/nightly';
|
const url = mirror || 'https://nodejs.org';
|
||||||
|
return `${url}/download/nightly`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ export default class OfficialBuilds extends BaseDistribution {
|
|||||||
downloadPath = await tc.downloadTool(
|
downloadPath = await tc.downloadTool(
|
||||||
versionInfo.downloadUrl,
|
versionInfo.downloadUrl,
|
||||||
undefined,
|
undefined,
|
||||||
this.nodeInfo.auth
|
this.nodeInfo.mirror ? this.nodeInfo.mirrorToken : this.nodeInfo.auth
|
||||||
);
|
);
|
||||||
|
|
||||||
if (downloadPath) {
|
if (downloadPath) {
|
||||||
@@ -96,7 +96,9 @@ export default class OfficialBuilds extends BaseDistribution {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
core.info(
|
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) {
|
} catch (err) {
|
||||||
@@ -176,8 +178,9 @@ export default class OfficialBuilds extends BaseDistribution {
|
|||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected getDistributionUrl(): string {
|
protected getDistributionUrl(mirror: string): string {
|
||||||
return `https://nodejs.org/dist`;
|
const url = mirror || 'https://nodejs.org';
|
||||||
|
return `${url}/dist`;
|
||||||
}
|
}
|
||||||
|
|
||||||
private getManifest(): Promise<tc.IToolRelease[]> {
|
private getManifest(): Promise<tc.IToolRelease[]> {
|
||||||
@@ -185,7 +188,7 @@ export default class OfficialBuilds extends BaseDistribution {
|
|||||||
return tc.getManifestFromRepo(
|
return tc.getManifestFromRepo(
|
||||||
'actions',
|
'actions',
|
||||||
'node-versions',
|
'node-versions',
|
||||||
this.nodeInfo.auth,
|
this.nodeInfo.mirror ? this.nodeInfo.mirrorToken : this.nodeInfo.auth,
|
||||||
'main'
|
'main'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,8 @@ export default class RcBuild extends BaseDistribution {
|
|||||||
super(nodeInfo);
|
super(nodeInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
getDistributionUrl(): string {
|
getDistributionUrl(mirror: string): string {
|
||||||
return 'https://nodejs.org/download/rc';
|
const url = mirror || 'https://nodejs.org';
|
||||||
|
return `${url}/download/rc`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,8 @@ export default class CanaryBuild extends BasePrereleaseNodejs {
|
|||||||
super(nodeInfo);
|
super(nodeInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected getDistributionUrl(): string {
|
protected getDistributionUrl(mirror: string): string {
|
||||||
return 'https://nodejs.org/download/v8-canary';
|
const url = mirror || 'https://nodejs.org';
|
||||||
|
return `${url}/download/v8-canary`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,6 +36,8 @@ export async function run() {
|
|||||||
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}`;
|
||||||
|
const mirror = core.getInput('mirror');
|
||||||
|
const mirrorToken = core.getInput('mirror-token');
|
||||||
const stable =
|
const stable =
|
||||||
(core.getInput('stable') || 'true').toUpperCase() === 'TRUE';
|
(core.getInput('stable') || 'true').toUpperCase() === 'TRUE';
|
||||||
const checkLatest =
|
const checkLatest =
|
||||||
@@ -45,7 +47,9 @@ export async function run() {
|
|||||||
checkLatest,
|
checkLatest,
|
||||||
auth,
|
auth,
|
||||||
stable,
|
stable,
|
||||||
arch
|
arch,
|
||||||
|
mirror,
|
||||||
|
mirrorToken
|
||||||
};
|
};
|
||||||
const nodeDistribution = getNodejsDistribution(nodejsInfo);
|
const nodeDistribution = getNodejsDistribution(nodejsInfo);
|
||||||
await nodeDistribution.setupNodeJs();
|
await nodeDistribution.setupNodeJs();
|
||||||
|
|||||||
20
src/util.ts
20
src/util.ts
@@ -3,6 +3,7 @@ import * as exec from '@actions/exec';
|
|||||||
import * as io from '@actions/io';
|
import * as io from '@actions/io';
|
||||||
|
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
|
import * as INI from 'ini';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
|
|
||||||
export function getNodeVersionFromFile(versionFilePath: string): string | null {
|
export function getNodeVersionFromFile(versionFilePath: string): string | null {
|
||||||
@@ -56,6 +57,25 @@ export function getNodeVersionFromFile(versionFilePath: string): string | null {
|
|||||||
core.info('Node version file is not JSON file');
|
core.info('Node version file is not JSON file');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Try parsing the file as an NPM `.npmrc` file.
|
||||||
|
//
|
||||||
|
// If the file contents contain the use-node-version key, we conclude it's an
|
||||||
|
// `.npmrc` file.
|
||||||
|
if (contents.match(/use-node-version *=/)) {
|
||||||
|
const manifest = INI.parse(contents);
|
||||||
|
const key = 'use-node-version';
|
||||||
|
|
||||||
|
if (key in manifest && typeof manifest[key] === 'string') {
|
||||||
|
const version = manifest[key];
|
||||||
|
core.info(`Using node version ${version} from global INI ${key}`);
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We didn't find the key `use-node-version` in the global scope of the
|
||||||
|
// `.npmrc` file, so we return.
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const found = contents.match(/^(?:node(js)?\s+)?v?(?<version>[^\s]+)$/m);
|
const found = contents.match(/^(?:node(js)?\s+)?v?(?<version>[^\s]+)$/m);
|
||||||
return found?.groups?.version ?? contents.trim();
|
return found?.groups?.version ?? contents.trim();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user