Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
eff380d
Fix macos latest check failures (#1041)
HarithaVattikuti May 22, 2024
1e60f62
Bump braces from 3.0.2 to 3.0.3 (#1087)
dependabot[bot] Jun 27, 2024
26961cf
Documentation update in the README file (#1106)
suyashgaonkar Jul 15, 2024
1c7b2db
Fix: windows arm64 setup (#1126)
priyagupta108 Sep 6, 2024
aa363de
Create publish-immutable-action.yml
Jcambass Sep 2, 2024
97ca147
Merge pull request #1125 from actions/add-is-release-workflow
Jcambass Sep 10, 2024
d6ebc7b
Upgrade IA Publish
Jcambass Sep 16, 2024
0a44ba7
Correct version string (#1124)
fulldecent Sep 19, 2024
88de2a3
Resolve High Security Alerts by upgrading Dependencies (#1132)
aparnajyothi-y Sep 24, 2024
aca7b64
Merge pull request #1134 from actions/Jcambass-patch-1
Jcambass Sep 26, 2024
abb238b
Revise `isGhes` logic (#1148)
jww3 Oct 21, 2024
39370e3
fix: add arch to cached path (#843)
pengx17 Oct 24, 2024
48b9067
Add macos-13 to the workflows and upgrade publish-actions from 0.2.2 …
aparnajyothi-y Dec 18, 2024
fbeca22
Update README.md (#1193)
Jan 16, 2025
5eef37b
Create dependabot.yml (#1192)
HarithaVattikuti Jan 16, 2025
8f9cc17
Use the new cache service: upgrade `@actions/cache` to `^4.0.0` (#1191)
priyagupta108 Jan 16, 2025
0bc26de
Bump pnpm/action-setup from 2 to 4 (#1194)
dependabot[bot] Jan 21, 2025
111c4be
Bump actions/publish-immutable-action from 0.0.3 to 0.0.4 (#1195)
dependabot[bot] Jan 21, 2025
260f870
Bump semver from 7.6.0 to 7.6.3 (#1196)
dependabot[bot] Jan 21, 2025
574f09a
Bump @types/jest from 29.5.12 to 29.5.14 (#1201)
dependabot[bot] Jan 21, 2025
1d0ff46
Bump undici from 5.28.4 to 5.28.5 (#1205)
dependabot[bot] Jan 22, 2025
8026329
Bump @actions/glob from 0.4.0 to 0.5.0 (#1200)
dependabot[bot] Jan 27, 2025
a7c2d94
actions/cache upgrade (#1251)
gowridurgad Mar 11, 2025
22c0e74
Bump @vercel/ncc from 0.38.1 to 0.38.3 (#1203)
dependabot[bot] Mar 12, 2025
cdca736
Bump @actions/tool-cache from 2.0.1 to 2.0.2 (#1220)
dependabot[bot] Mar 13, 2025
1ccdddc
Make eslint-compact matcher compatible with Stylelint (#98)
FloEdelmann Mar 24, 2025
40337cb
Add support for indented eslint output (#1245)
fregante Mar 24, 2025
e3ce749
feat: support private mirrors (#1240)
marco-ippolito Apr 2, 2025
49933ea
Bump @action/cache from 4.0.2 to 4.0.3 (#1262)
aparnajyothi-y Apr 2, 2025
08f58d1
Bump @octokit/request-error and @actions/github (#1227)
dependabot[bot] Jun 18, 2025
7e24a65
Bump uuid from 9.0.1 to 11.1.0 (#1273)
dependabot[bot] Jul 15, 2025
66a4515
fix: merge remote-tracking branch 'upstream/main'
mmatl Jul 23, 2025
eba260d
fix: build
mmatl Jul 23, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
feat: support private mirrors (actions#1240)
* feat: support private mirrors

* chore: change fallback message with mirrors
  • Loading branch information
marco-ippolito authored Apr 2, 2025
commit e3ce749e201f52acbab9862647a7b9bd3e37cf76
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 -->

Expand Down
64 changes: 64 additions & 0 deletions __tests__/canary-installer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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', () => {
Expand Down
50 changes: 49 additions & 1 deletion __tests__/nightly-installer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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}`);
});
Expand Down Expand Up @@ -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([
[
Expand Down
79 changes: 79 additions & 0 deletions __tests__/official-installer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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);
});
4 changes: 4 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
Loading