mirror of
				https://github.com/actions/setup-node.git
				synced 2025-11-04 13:29:12 +08:00 
			
		
		
		
	Add support for v8-canary, nightly and rc (#655)
This commit is contained in:
		
							
								
								
									
										20
									
								
								.github/workflows/versions.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										20
									
								
								.github/workflows/versions.yml
									
									
									
									
										vendored
									
									
								
							@@ -51,6 +51,26 @@ jobs:
 | 
				
			|||||||
          __tests__/verify-node.sh "${BASH_REMATCH[1]}"
 | 
					          __tests__/verify-node.sh "${BASH_REMATCH[1]}"
 | 
				
			||||||
        shell: bash
 | 
					        shell: bash
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  v8-canary-syntax:
 | 
				
			||||||
 | 
					    runs-on: ${{ matrix.os }}
 | 
				
			||||||
 | 
					    strategy:
 | 
				
			||||||
 | 
					      fail-fast: false
 | 
				
			||||||
 | 
					      matrix:
 | 
				
			||||||
 | 
					        os: [ubuntu-latest, windows-latest, macos-latest]
 | 
				
			||||||
 | 
					        node-version: ['20-v8-canary', '20.0.0-v8-canary','20.0.0-v8-canary20221103f7e2421e91']
 | 
				
			||||||
 | 
					    steps:
 | 
				
			||||||
 | 
					      - uses: actions/checkout@v3
 | 
				
			||||||
 | 
					      - name: Setup Node
 | 
				
			||||||
 | 
					        uses: ./
 | 
				
			||||||
 | 
					        with:
 | 
				
			||||||
 | 
					          node-version: ${{ matrix.node-version }}
 | 
				
			||||||
 | 
					      - name: Verify node and npm
 | 
				
			||||||
 | 
					        run: |
 | 
				
			||||||
 | 
					          canaryVersion="${{ matrix.node-version }}"
 | 
				
			||||||
 | 
					          majorVersion=$(echo $canaryVersion | cut -d- -f1)
 | 
				
			||||||
 | 
					          __tests__/verify-node.sh "$majorVersion"
 | 
				
			||||||
 | 
					        shell: bash
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  nightly-syntax:
 | 
					  nightly-syntax:
 | 
				
			||||||
    runs-on: ${{ matrix.os }}
 | 
					    runs-on: ${{ matrix.os }}
 | 
				
			||||||
    strategy:
 | 
					    strategy:
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										21
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								README.md
									
									
									
									
									
								
							@@ -128,16 +128,17 @@ If the runner is not able to access github.com, any Nodejs versions requested du
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
## Advanced usage
 | 
					## Advanced usage
 | 
				
			||||||
 | 
					
 | 
				
			||||||
1. [Check latest version](docs/advanced-usage.md#check-latest-version)
 | 
					 - [Check latest version](docs/advanced-usage.md#check-latest-version)
 | 
				
			||||||
2. [Using a node version file](docs/advanced-usage.md#node-version-file)
 | 
					 - [Using a node version file](docs/advanced-usage.md#node-version-file)
 | 
				
			||||||
3. [Using different architectures](docs/advanced-usage.md#architecture)
 | 
					 - [Using different architectures](docs/advanced-usage.md#architecture)
 | 
				
			||||||
4. [Using nightly versions](docs/advanced-usage.md#nightly-versions)
 | 
					 - [Using v8 canary versions](docs/advanced-usage.md#v8-canary-versions)
 | 
				
			||||||
5. [Using rc versions](docs/advanced-usage.md#rc-versions)
 | 
					 - [Using nigthly versions](docs/advanced-usage.md#nightly-versions)
 | 
				
			||||||
6. [Caching packages data](docs/advanced-usage.md#caching-packages-data)
 | 
					 - [Using rc versions](docs/advanced-usage.md#rc-versions)
 | 
				
			||||||
7. [Using multiple operating systems and architectures](docs/advanced-usage.md#multiple-operating-systems-and-architectures)
 | 
					 - [Caching packages data](docs/advanced-usage.md#caching-packages-data)
 | 
				
			||||||
8. [Publishing to npmjs and GPR with npm](docs/advanced-usage.md#publish-to-npmjs-and-gpr-with-npm)
 | 
					 - [Using multiple operating systems and architectures](docs/advanced-usage.md#multiple-operating-systems-and-architectures)
 | 
				
			||||||
9. [Publishing to npmjs and GPR with yarn](docs/advanced-usage.md#publish-to-npmjs-and-gpr-with-yarn)
 | 
					 - [Publishing to npmjs and GPR with npm](docs/advanced-usage.md#publish-to-npmjs-and-gpr-with-npm)
 | 
				
			||||||
10. [Using private packages](docs/advanced-usage.md#use-private-packages)
 | 
					 - [Publishing to npmjs and GPR with yarn](docs/advanced-usage.md#publish-to-npmjs-and-gpr-with-yarn)
 | 
				
			||||||
 | 
					 - [Using private packages](docs/advanced-usage.md#use-private-packages)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## License
 | 
					## License
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										531
									
								
								__tests__/canary-installer.test.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										531
									
								
								__tests__/canary-installer.test.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,531 @@
 | 
				
			|||||||
 | 
					import * as core from '@actions/core';
 | 
				
			||||||
 | 
					import * as io from '@actions/io';
 | 
				
			||||||
 | 
					import * as tc from '@actions/tool-cache';
 | 
				
			||||||
 | 
					import * as httpm from '@actions/http-client';
 | 
				
			||||||
 | 
					import * as exec from '@actions/exec';
 | 
				
			||||||
 | 
					import * as cache from '@actions/cache';
 | 
				
			||||||
 | 
					import fs from 'fs';
 | 
				
			||||||
 | 
					import cp from 'child_process';
 | 
				
			||||||
 | 
					import osm from 'os';
 | 
				
			||||||
 | 
					import path from 'path';
 | 
				
			||||||
 | 
					import * as main from '../src/main';
 | 
				
			||||||
 | 
					import * as auth from '../src/authutil';
 | 
				
			||||||
 | 
					import {INodeVersion} from '../src/distributions/base-models';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const nodeTestManifest = require('./data/versions-manifest.json');
 | 
				
			||||||
 | 
					const nodeTestDist = require('./data/node-dist-index.json');
 | 
				
			||||||
 | 
					const nodeTestDistNightly = require('./data/node-nightly-index.json');
 | 
				
			||||||
 | 
					const nodeTestDistRc = require('./data/node-rc-index.json');
 | 
				
			||||||
 | 
					const nodeV8CanaryTestDist = require('./data/v8-canary-dist-index.json');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					describe('setup-node', () => {
 | 
				
			||||||
 | 
					  let inputs = {} as any;
 | 
				
			||||||
 | 
					  let os = {} as any;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let inSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let findSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let findAllVersionsSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let cnSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let logSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let warningSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let getManifestSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let getDistSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let platSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let archSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let dlSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let exSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let cacheSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let dbgSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let whichSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let existsSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let readFileSyncSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let mkdirpSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let execSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let authSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let parseNodeVersionSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let isCacheActionAvailable: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let getExecOutputSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let getJsonSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  beforeEach(() => {
 | 
				
			||||||
 | 
					    // @actions/core
 | 
				
			||||||
 | 
					    console.log('::stop-commands::stoptoken'); // Disable executing of runner commands when running tests in actions
 | 
				
			||||||
 | 
					    process.env['GITHUB_PATH'] = ''; // Stub out ENV file functionality so we can verify it writes to standard out
 | 
				
			||||||
 | 
					    process.env['GITHUB_OUTPUT'] = ''; // Stub out ENV file functionality so we can verify it writes to standard out
 | 
				
			||||||
 | 
					    inputs = {};
 | 
				
			||||||
 | 
					    inSpy = jest.spyOn(core, 'getInput');
 | 
				
			||||||
 | 
					    inSpy.mockImplementation(name => inputs[name]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // node
 | 
				
			||||||
 | 
					    os = {};
 | 
				
			||||||
 | 
					    platSpy = jest.spyOn(osm, 'platform');
 | 
				
			||||||
 | 
					    platSpy.mockImplementation(() => os['platform']);
 | 
				
			||||||
 | 
					    archSpy = jest.spyOn(osm, 'arch');
 | 
				
			||||||
 | 
					    archSpy.mockImplementation(() => os['arch']);
 | 
				
			||||||
 | 
					    execSpy = jest.spyOn(cp, 'execSync');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // @actions/tool-cache
 | 
				
			||||||
 | 
					    findSpy = jest.spyOn(tc, 'find');
 | 
				
			||||||
 | 
					    findAllVersionsSpy = jest.spyOn(tc, 'findAllVersions');
 | 
				
			||||||
 | 
					    dlSpy = jest.spyOn(tc, 'downloadTool');
 | 
				
			||||||
 | 
					    exSpy = jest.spyOn(tc, 'extractTar');
 | 
				
			||||||
 | 
					    cacheSpy = jest.spyOn(tc, 'cacheDir');
 | 
				
			||||||
 | 
					    getManifestSpy = jest.spyOn(tc, 'getManifestFromRepo');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // http-client
 | 
				
			||||||
 | 
					    getJsonSpy = jest.spyOn(httpm.HttpClient.prototype, 'getJson');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // io
 | 
				
			||||||
 | 
					    whichSpy = jest.spyOn(io, 'which');
 | 
				
			||||||
 | 
					    existsSpy = jest.spyOn(fs, 'existsSync');
 | 
				
			||||||
 | 
					    mkdirpSpy = jest.spyOn(io, 'mkdirP');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // @actions/tool-cache
 | 
				
			||||||
 | 
					    isCacheActionAvailable = jest.spyOn(cache, 'isFeatureAvailable');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // disable authentication portion for installer tests
 | 
				
			||||||
 | 
					    authSpy = jest.spyOn(auth, 'configAuthentication');
 | 
				
			||||||
 | 
					    authSpy.mockImplementation(() => {});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // gets
 | 
				
			||||||
 | 
					    getManifestSpy.mockImplementation(
 | 
				
			||||||
 | 
					      () => <tc.IToolRelease[]>nodeTestManifest
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    getJsonSpy.mockImplementation(url => {
 | 
				
			||||||
 | 
					      let res: any;
 | 
				
			||||||
 | 
					      if (url.includes('/rc')) {
 | 
				
			||||||
 | 
					        res = <INodeVersion>nodeTestDistRc;
 | 
				
			||||||
 | 
					      } else if (url.includes('/nightly')) {
 | 
				
			||||||
 | 
					        res = <INodeVersion>nodeTestDistNightly;
 | 
				
			||||||
 | 
					      } else if (url.includes('/v8-canary')) {
 | 
				
			||||||
 | 
					        res = <INodeVersion>nodeV8CanaryTestDist;
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        res = <INodeVersion>nodeTestDist;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      return {result: res};
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // writes
 | 
				
			||||||
 | 
					    cnSpy = jest.spyOn(process.stdout, 'write');
 | 
				
			||||||
 | 
					    logSpy = jest.spyOn(core, 'info');
 | 
				
			||||||
 | 
					    dbgSpy = jest.spyOn(core, 'debug');
 | 
				
			||||||
 | 
					    warningSpy = jest.spyOn(core, 'warning');
 | 
				
			||||||
 | 
					    cnSpy.mockImplementation(line => {
 | 
				
			||||||
 | 
					      // uncomment to debug
 | 
				
			||||||
 | 
					      // process.stderr.write('write:' + line + '\n');
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    logSpy.mockImplementation(line => {
 | 
				
			||||||
 | 
					      // uncomment to debug
 | 
				
			||||||
 | 
					      // process.stderr.write('log:' + line + '\n');
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    dbgSpy.mockImplementation(msg => {
 | 
				
			||||||
 | 
					      // uncomment to see debug output
 | 
				
			||||||
 | 
					      // process.stderr.write(msg + '\n');
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    warningSpy.mockImplementation(msg => {
 | 
				
			||||||
 | 
					      // uncomment to debug
 | 
				
			||||||
 | 
					      // process.stderr.write('log:' + msg + '\n');
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // @actions/exec
 | 
				
			||||||
 | 
					    getExecOutputSpy = jest.spyOn(exec, 'getExecOutput');
 | 
				
			||||||
 | 
					    getExecOutputSpy.mockImplementation(() => 'v16.15.0');
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  afterEach(() => {
 | 
				
			||||||
 | 
					    jest.resetAllMocks();
 | 
				
			||||||
 | 
					    jest.clearAllMocks();
 | 
				
			||||||
 | 
					    //jest.restoreAllMocks();
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  afterAll(async () => {
 | 
				
			||||||
 | 
					    console.log('::stoptoken::'); // Re-enable executing of runner commands when running tests in actions
 | 
				
			||||||
 | 
					    jest.restoreAllMocks();
 | 
				
			||||||
 | 
					  }, 100000);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  //--------------------------------------------------
 | 
				
			||||||
 | 
					  // Found in cache tests
 | 
				
			||||||
 | 
					  //--------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  it('finds version in cache with stable true', async () => {
 | 
				
			||||||
 | 
					    inputs['node-version'] = '20-v8-canary';
 | 
				
			||||||
 | 
					    os['arch'] = 'x64';
 | 
				
			||||||
 | 
					    inputs.stable = 'true';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let toolPath = path.normalize(
 | 
				
			||||||
 | 
					      '/cache/node/20.0.0-v8-canary20221103f7e2421e91/x64'
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    findSpy.mockImplementation(() => toolPath);
 | 
				
			||||||
 | 
					    findAllVersionsSpy.mockImplementation(() => [
 | 
				
			||||||
 | 
					      '20.0.0-v8-canary20221103f7e2421e91',
 | 
				
			||||||
 | 
					      '20.0.0-v8-canary20221030fefe1c0879',
 | 
				
			||||||
 | 
					      '19.0.0-v8-canary202210172ec229fc56',
 | 
				
			||||||
 | 
					      '20.0.0-v8-canary2022102310ff1e5a8d'
 | 
				
			||||||
 | 
					    ]);
 | 
				
			||||||
 | 
					    await main.run();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    expect(findSpy).toHaveBeenCalledWith(
 | 
				
			||||||
 | 
					      'node',
 | 
				
			||||||
 | 
					      '20.0.0-v8-canary20221103f7e2421e91',
 | 
				
			||||||
 | 
					      'x64'
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    expect(logSpy).toHaveBeenCalledWith(`Found in cache @ ${toolPath}`);
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  it('finds version in cache and adds it to the path', async () => {
 | 
				
			||||||
 | 
					    inputs['node-version'] = '20-v8-canary';
 | 
				
			||||||
 | 
					    os['arch'] = 'x64';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    inSpy.mockImplementation(name => inputs[name]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let toolPath = path.normalize(
 | 
				
			||||||
 | 
					      '/cache/node/20.0.0-v8-canary20221103f7e2421e91/x64'
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    findSpy.mockImplementation(() => toolPath);
 | 
				
			||||||
 | 
					    findAllVersionsSpy.mockImplementation(() => [
 | 
				
			||||||
 | 
					      '20.0.0-v8-canary20221103f7e2421e91',
 | 
				
			||||||
 | 
					      '20.0.0-v8-canary20221030fefe1c0879',
 | 
				
			||||||
 | 
					      '19.0.0-v8-canary202210172ec229fc56',
 | 
				
			||||||
 | 
					      '20.0.0-v8-canary2022102310ff1e5a8d'
 | 
				
			||||||
 | 
					    ]);
 | 
				
			||||||
 | 
					    await main.run();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let expPath = path.join(toolPath, 'bin');
 | 
				
			||||||
 | 
					    expect(cnSpy).toHaveBeenCalledWith(`::add-path::${expPath}${osm.EOL}`);
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  it('handles unhandled find error and reports error', async () => {
 | 
				
			||||||
 | 
					    os.platform = 'linux';
 | 
				
			||||||
 | 
					    let errMsg = 'unhandled error message';
 | 
				
			||||||
 | 
					    inputs['node-version'] = '20.0.0-v8-canary20221103f7e2421e91';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    findSpy.mockImplementation(() => {
 | 
				
			||||||
 | 
					      throw new Error(errMsg);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    findAllVersionsSpy.mockImplementation(() => [
 | 
				
			||||||
 | 
					      '20.0.0-v8-canary20221103f7e2421e91',
 | 
				
			||||||
 | 
					      '20.0.0-v8-canary20221030fefe1c0879',
 | 
				
			||||||
 | 
					      '19.0.0-v8-canary202210172ec229fc56',
 | 
				
			||||||
 | 
					      '20.0.0-v8-canary2022102310ff1e5a8d'
 | 
				
			||||||
 | 
					    ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    await main.run();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    expect(cnSpy).toHaveBeenCalledWith('::error::' + errMsg + osm.EOL);
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  //--------------------------------------------------
 | 
				
			||||||
 | 
					  // Manifest tests
 | 
				
			||||||
 | 
					  //--------------------------------------------------
 | 
				
			||||||
 | 
					  it('falls back to a version from node dist', async () => {
 | 
				
			||||||
 | 
					    os.platform = 'linux';
 | 
				
			||||||
 | 
					    os.arch = 'x64';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // a version which is not in the manifest but is in node dist
 | 
				
			||||||
 | 
					    let versionSpec = '11.15.0';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    inputs['node-version'] = versionSpec;
 | 
				
			||||||
 | 
					    inputs['always-auth'] = false;
 | 
				
			||||||
 | 
					    inputs['token'] = 'faketoken';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // ... but not in the local cache
 | 
				
			||||||
 | 
					    findSpy.mockImplementation(() => '');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dlSpy.mockImplementation(async () => '/some/temp/path');
 | 
				
			||||||
 | 
					    let toolPath = path.normalize('/cache/node/11.11.0/x64');
 | 
				
			||||||
 | 
					    exSpy.mockImplementation(async () => '/some/other/temp/path');
 | 
				
			||||||
 | 
					    cacheSpy.mockImplementation(async () => toolPath);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    await main.run();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let expPath = path.join(toolPath, 'bin');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    expect(dlSpy).toHaveBeenCalled();
 | 
				
			||||||
 | 
					    expect(exSpy).toHaveBeenCalled();
 | 
				
			||||||
 | 
					    expect(logSpy).toHaveBeenCalledWith(
 | 
				
			||||||
 | 
					      'Not found in manifest. Falling back to download directly from Node'
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    expect(logSpy).toHaveBeenCalledWith(
 | 
				
			||||||
 | 
					      `Attempting to download ${versionSpec}...`
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    expect(cnSpy).toHaveBeenCalledWith(`::add-path::${expPath}${osm.EOL}`);
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  it('does not find a version that does not exist', async () => {
 | 
				
			||||||
 | 
					    os.platform = 'linux';
 | 
				
			||||||
 | 
					    os.arch = 'x64';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let versionSpec = '23.0.0-v8-canary20221103f7e2421e91';
 | 
				
			||||||
 | 
					    inputs['node-version'] = versionSpec;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    findSpy.mockImplementation(() => '');
 | 
				
			||||||
 | 
					    findAllVersionsSpy.mockImplementation(() => [
 | 
				
			||||||
 | 
					      '20.0.0-v8-canary20221103f7e2421e91',
 | 
				
			||||||
 | 
					      '20.0.0-v8-canary20221030fefe1c0879',
 | 
				
			||||||
 | 
					      '19.0.0-v8-canary202210172ec229fc56',
 | 
				
			||||||
 | 
					      '20.0.0-v8-canary2022102310ff1e5a8d'
 | 
				
			||||||
 | 
					    ]);
 | 
				
			||||||
 | 
					    await main.run();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    expect(cnSpy).toHaveBeenCalledWith(
 | 
				
			||||||
 | 
					      `::error::Unable to find Node version '${versionSpec}' for platform ${os.platform} and architecture ${os.arch}.${osm.EOL}`
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  it('reports a failed download', async () => {
 | 
				
			||||||
 | 
					    let errMsg = 'unhandled download message';
 | 
				
			||||||
 | 
					    os.platform = 'linux';
 | 
				
			||||||
 | 
					    os.arch = 'x64';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // a version which is in the manifest
 | 
				
			||||||
 | 
					    let versionSpec = '19.0.0-v8-canary';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    inputs['node-version'] = versionSpec;
 | 
				
			||||||
 | 
					    inputs['always-auth'] = false;
 | 
				
			||||||
 | 
					    inputs['token'] = 'faketoken';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    findSpy.mockImplementation(() => '');
 | 
				
			||||||
 | 
					    findAllVersionsSpy.mockImplementation(() => [
 | 
				
			||||||
 | 
					      '20.0.0-v8-canary20221103f7e2421e91',
 | 
				
			||||||
 | 
					      '20.0.0-v8-canary20221030fefe1c0879',
 | 
				
			||||||
 | 
					      '20.0.0-v8-canary2022102310ff1e5a8d'
 | 
				
			||||||
 | 
					    ]);
 | 
				
			||||||
 | 
					    dlSpy.mockImplementation(() => {
 | 
				
			||||||
 | 
					      throw new Error(errMsg);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    await main.run();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    expect(cnSpy).toHaveBeenCalledWith(`::error::${errMsg}${osm.EOL}`);
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  it('acquires specified architecture of node', async () => {
 | 
				
			||||||
 | 
					    for (const {arch, version, osSpec} of [
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        arch: 'x86',
 | 
				
			||||||
 | 
					        version: '20.0.0-v8-canary20221022e83bcb6c41',
 | 
				
			||||||
 | 
					        osSpec: 'win32'
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        arch: 'x86',
 | 
				
			||||||
 | 
					        version: '20.0.0-v8-canary20221103f7e2421e91',
 | 
				
			||||||
 | 
					        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';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      let expectedUrl = `https://nodejs.org/download/v8-canary/v${version}/node-v${version}-${platform}-${arch}.${fileExtension}`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // ... but not in the local cache
 | 
				
			||||||
 | 
					      findSpy.mockImplementation(() => '');
 | 
				
			||||||
 | 
					      findAllVersionsSpy.mockImplementation(() => []);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      dlSpy.mockImplementation(async () => '/some/temp/path');
 | 
				
			||||||
 | 
					      let 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([
 | 
				
			||||||
 | 
					      [
 | 
				
			||||||
 | 
					        '20.0.0-v8-canary',
 | 
				
			||||||
 | 
					        '20.0.0-v8-canary20221103f7e2421e91',
 | 
				
			||||||
 | 
					        'https://nodejs.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',
 | 
				
			||||||
 | 
					        'https://nodejs.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',
 | 
				
			||||||
 | 
					        'https://nodejs.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',
 | 
				
			||||||
 | 
					        'https://nodejs.org/download/v8-canary/v19.0.0-v8-canary202210187d6960f23f/node-v19.0.0-v8-canary202210187d6960f23f-linux-x64.tar.gz'
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					      [
 | 
				
			||||||
 | 
					        '19.0.0-v8-canary202210187d6960f23f',
 | 
				
			||||||
 | 
					        '19.0.0-v8-canary202210187d6960f23f',
 | 
				
			||||||
 | 
					        'https://nodejs.org/download/v8-canary/v19.0.0-v8-canary202210187d6960f23f/node-v19.0.0-v8-canary202210187d6960f23f-linux-x64.tar.gz'
 | 
				
			||||||
 | 
					      ]
 | 
				
			||||||
 | 
					    ])(
 | 
				
			||||||
 | 
					      'finds the versions in the index.json and installs it',
 | 
				
			||||||
 | 
					      async (input, expectedVersion, expectedUrl) => {
 | 
				
			||||||
 | 
					        const toolPath = path.normalize(`/cache/node/${expectedVersion}/x64`);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        findSpy.mockImplementation(() => '');
 | 
				
			||||||
 | 
					        findAllVersionsSpy.mockImplementation(() => []);
 | 
				
			||||||
 | 
					        dlSpy.mockImplementation(async () => '/some/temp/path');
 | 
				
			||||||
 | 
					        exSpy.mockImplementation(async () => '/some/other/temp/path');
 | 
				
			||||||
 | 
					        cacheSpy.mockImplementation(async () => toolPath);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        inputs['node-version'] = input;
 | 
				
			||||||
 | 
					        os['arch'] = 'x64';
 | 
				
			||||||
 | 
					        os['platform'] = 'linux';
 | 
				
			||||||
 | 
					        // act
 | 
				
			||||||
 | 
					        await main.run();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // assert
 | 
				
			||||||
 | 
					        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}`
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it.each([
 | 
				
			||||||
 | 
					      [
 | 
				
			||||||
 | 
					        '20.0.0-v8-canary20221103f7e2421e91',
 | 
				
			||||||
 | 
					        '20.0.0-v8-canary20221103f7e2421e91'
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					      ['20.0.0-v8-canary', '20.0.0-v8-canary20221103f7e2421e91'],
 | 
				
			||||||
 | 
					      ['20-v8-canary', '20.0.0-v8-canary20221103f7e2421e91']
 | 
				
			||||||
 | 
					    ])(
 | 
				
			||||||
 | 
					      'finds the %s version in the hostedToolcache',
 | 
				
			||||||
 | 
					      async (input, expectedVersion) => {
 | 
				
			||||||
 | 
					        const toolPath = path.normalize(`/cache/node/${expectedVersion}/x64`);
 | 
				
			||||||
 | 
					        findSpy.mockReturnValue(toolPath);
 | 
				
			||||||
 | 
					        findAllVersionsSpy.mockReturnValue([
 | 
				
			||||||
 | 
					          '20.0.0-v8-canary20221103f7e2421e91',
 | 
				
			||||||
 | 
					          '20.0.0-v8-canary20221030fefe1c0879',
 | 
				
			||||||
 | 
					          '19.0.0-v8-canary202210172ec229fc56',
 | 
				
			||||||
 | 
					          '20.0.0-v8-canary2022102310ff1e5a8d'
 | 
				
			||||||
 | 
					        ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        inputs['node-version'] = input;
 | 
				
			||||||
 | 
					        os['arch'] = 'x64';
 | 
				
			||||||
 | 
					        os['platform'] = 'linux';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // act
 | 
				
			||||||
 | 
					        await main.run();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // assert
 | 
				
			||||||
 | 
					        expect(findAllVersionsSpy).toHaveBeenCalled();
 | 
				
			||||||
 | 
					        expect(logSpy).toHaveBeenCalledWith(`Found in cache @ ${toolPath}`);
 | 
				
			||||||
 | 
					        expect(cnSpy).toHaveBeenCalledWith(
 | 
				
			||||||
 | 
					          `::add-path::${path.join(toolPath, 'bin')}${osm.EOL}`
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it.each([
 | 
				
			||||||
 | 
					      [
 | 
				
			||||||
 | 
					        '20.0.0-v8-canary',
 | 
				
			||||||
 | 
					        '20.0.0-v8-canary20221103f7e2421e91',
 | 
				
			||||||
 | 
					        '20.0.0-v8-canary20221030fefe1c0879',
 | 
				
			||||||
 | 
					        'https://nodejs.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://nodejs.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://nodejs.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://nodejs.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';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        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', () => {
 | 
				
			||||||
 | 
					    it('v8 canary setup node flow with cached', async () => {
 | 
				
			||||||
 | 
					      let versionSpec = 'v20-v8-canary';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      inputs['node-version'] = versionSpec;
 | 
				
			||||||
 | 
					      inputs['always-auth'] = false;
 | 
				
			||||||
 | 
					      inputs['token'] = 'faketoken';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      os.platform = 'linux';
 | 
				
			||||||
 | 
					      os.arch = 'x64';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      const versionExpected = 'v20.0.0-v8-canary20221103f7e2421e91';
 | 
				
			||||||
 | 
					      findAllVersionsSpy.mockImplementation(() => [versionExpected]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      const toolPath = path.normalize(`/cache/node/${versionExpected}/x64`);
 | 
				
			||||||
 | 
					      findSpy.mockImplementation(version => toolPath);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      await main.run();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      expect(cnSpy).toHaveBeenCalledWith(
 | 
				
			||||||
 | 
					        `::add-path::${toolPath}${path.sep}bin${osm.EOL}`
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      expect(dlSpy).not.toHaveBeenCalled();
 | 
				
			||||||
 | 
					      expect(exSpy).not.toHaveBeenCalled();
 | 
				
			||||||
 | 
					      expect(cacheSpy).not.toHaveBeenCalled();
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
							
								
								
									
										537
									
								
								__tests__/data/v8-canary-dist-index.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										537
									
								
								__tests__/data/v8-canary-dist-index.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,537 @@
 | 
				
			|||||||
 | 
					[
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    "version": "v20.0.0-v8-canary20221103f7e2421e91",
 | 
				
			||||||
 | 
					    "date": "2022-11-03",
 | 
				
			||||||
 | 
					    "files": [
 | 
				
			||||||
 | 
					      "headers",
 | 
				
			||||||
 | 
					      "linux-arm64",
 | 
				
			||||||
 | 
					      "linux-armv7l",
 | 
				
			||||||
 | 
					      "linux-ppc64le",
 | 
				
			||||||
 | 
					      "linux-s390x",
 | 
				
			||||||
 | 
					      "linux-x64",
 | 
				
			||||||
 | 
					      "osx-arm64-tar",
 | 
				
			||||||
 | 
					      "osx-x64-pkg",
 | 
				
			||||||
 | 
					      "osx-x64-tar",
 | 
				
			||||||
 | 
					      "src",
 | 
				
			||||||
 | 
					      "win-x64-7z",
 | 
				
			||||||
 | 
					      "win-x64-exe",
 | 
				
			||||||
 | 
					      "win-x64-msi",
 | 
				
			||||||
 | 
					      "win-x64-zip",
 | 
				
			||||||
 | 
					      "win-x86-7z",
 | 
				
			||||||
 | 
					      "win-x86-exe",
 | 
				
			||||||
 | 
					      "win-x86-msi",
 | 
				
			||||||
 | 
					      "win-x86-zip"
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "npm": "8.19.2",
 | 
				
			||||||
 | 
					    "v8": "10.9.138.0",
 | 
				
			||||||
 | 
					    "uv": "1.43.0",
 | 
				
			||||||
 | 
					    "zlib": "1.2.11",
 | 
				
			||||||
 | 
					    "openssl": "3.0.5+quic",
 | 
				
			||||||
 | 
					    "modules": "112",
 | 
				
			||||||
 | 
					    "lts": false,
 | 
				
			||||||
 | 
					    "security": false
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    "version": "v20.0.0-v8-canary202211026bf85d0fb4",
 | 
				
			||||||
 | 
					    "date": "2022-11-02",
 | 
				
			||||||
 | 
					    "files": [
 | 
				
			||||||
 | 
					      "headers",
 | 
				
			||||||
 | 
					      "linux-arm64",
 | 
				
			||||||
 | 
					      "linux-armv7l",
 | 
				
			||||||
 | 
					      "linux-ppc64le",
 | 
				
			||||||
 | 
					      "linux-s390x",
 | 
				
			||||||
 | 
					      "linux-x64",
 | 
				
			||||||
 | 
					      "osx-arm64-tar",
 | 
				
			||||||
 | 
					      "osx-x64-pkg",
 | 
				
			||||||
 | 
					      "osx-x64-tar",
 | 
				
			||||||
 | 
					      "src",
 | 
				
			||||||
 | 
					      "win-x64-7z",
 | 
				
			||||||
 | 
					      "win-x64-exe",
 | 
				
			||||||
 | 
					      "win-x64-msi",
 | 
				
			||||||
 | 
					      "win-x64-zip",
 | 
				
			||||||
 | 
					      "win-x86-7z",
 | 
				
			||||||
 | 
					      "win-x86-exe",
 | 
				
			||||||
 | 
					      "win-x86-msi",
 | 
				
			||||||
 | 
					      "win-x86-zip"
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "npm": "8.19.2",
 | 
				
			||||||
 | 
					    "v8": "10.9.130.0",
 | 
				
			||||||
 | 
					    "uv": "1.43.0",
 | 
				
			||||||
 | 
					    "zlib": "1.2.11",
 | 
				
			||||||
 | 
					    "openssl": "3.0.5+quic",
 | 
				
			||||||
 | 
					    "modules": "112",
 | 
				
			||||||
 | 
					    "lts": false,
 | 
				
			||||||
 | 
					    "security": false
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    "version": "v20.0.0-v8-canary20221101e50e45c9f8",
 | 
				
			||||||
 | 
					    "date": "2022-11-01",
 | 
				
			||||||
 | 
					    "files": [
 | 
				
			||||||
 | 
					      "headers",
 | 
				
			||||||
 | 
					      "linux-arm64",
 | 
				
			||||||
 | 
					      "linux-armv7l",
 | 
				
			||||||
 | 
					      "linux-ppc64le",
 | 
				
			||||||
 | 
					      "linux-s390x",
 | 
				
			||||||
 | 
					      "linux-x64",
 | 
				
			||||||
 | 
					      "osx-arm64-tar",
 | 
				
			||||||
 | 
					      "osx-x64-tar",
 | 
				
			||||||
 | 
					      "src",
 | 
				
			||||||
 | 
					      "win-x64-7z",
 | 
				
			||||||
 | 
					      "win-x64-exe",
 | 
				
			||||||
 | 
					      "win-x64-msi",
 | 
				
			||||||
 | 
					      "win-x64-zip",
 | 
				
			||||||
 | 
					      "win-x86-7z",
 | 
				
			||||||
 | 
					      "win-x86-exe",
 | 
				
			||||||
 | 
					      "win-x86-msi",
 | 
				
			||||||
 | 
					      "win-x86-zip"
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "npm": "8.19.2",
 | 
				
			||||||
 | 
					    "v8": "10.9.129.0",
 | 
				
			||||||
 | 
					    "uv": "1.43.0",
 | 
				
			||||||
 | 
					    "zlib": "1.2.11",
 | 
				
			||||||
 | 
					    "openssl": "3.0.5+quic",
 | 
				
			||||||
 | 
					    "modules": "112",
 | 
				
			||||||
 | 
					    "lts": false,
 | 
				
			||||||
 | 
					    "security": false
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    "version": "v20.0.0-v8-canary202210311b1e675ad0",
 | 
				
			||||||
 | 
					    "date": "2022-10-31",
 | 
				
			||||||
 | 
					    "files": [
 | 
				
			||||||
 | 
					      "headers",
 | 
				
			||||||
 | 
					      "linux-arm64",
 | 
				
			||||||
 | 
					      "linux-armv7l",
 | 
				
			||||||
 | 
					      "linux-ppc64le",
 | 
				
			||||||
 | 
					      "linux-s390x",
 | 
				
			||||||
 | 
					      "linux-x64",
 | 
				
			||||||
 | 
					      "osx-arm64-tar",
 | 
				
			||||||
 | 
					      "osx-x64-tar",
 | 
				
			||||||
 | 
					      "src",
 | 
				
			||||||
 | 
					      "win-x64-7z",
 | 
				
			||||||
 | 
					      "win-x64-exe",
 | 
				
			||||||
 | 
					      "win-x64-msi",
 | 
				
			||||||
 | 
					      "win-x64-zip",
 | 
				
			||||||
 | 
					      "win-x86-7z",
 | 
				
			||||||
 | 
					      "win-x86-exe",
 | 
				
			||||||
 | 
					      "win-x86-msi",
 | 
				
			||||||
 | 
					      "win-x86-zip"
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "npm": "8.19.2",
 | 
				
			||||||
 | 
					    "v8": "10.9.125.0",
 | 
				
			||||||
 | 
					    "uv": "1.43.0",
 | 
				
			||||||
 | 
					    "zlib": "1.2.11",
 | 
				
			||||||
 | 
					    "openssl": "3.0.5+quic",
 | 
				
			||||||
 | 
					    "modules": "112",
 | 
				
			||||||
 | 
					    "lts": false,
 | 
				
			||||||
 | 
					    "security": false
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    "version": "v20.0.0-v8-canary20221030fefe1c0879",
 | 
				
			||||||
 | 
					    "date": "2022-10-30",
 | 
				
			||||||
 | 
					    "files": [
 | 
				
			||||||
 | 
					      "headers",
 | 
				
			||||||
 | 
					      "linux-arm64",
 | 
				
			||||||
 | 
					      "linux-armv7l",
 | 
				
			||||||
 | 
					      "linux-ppc64le",
 | 
				
			||||||
 | 
					      "linux-s390x",
 | 
				
			||||||
 | 
					      "linux-x64",
 | 
				
			||||||
 | 
					      "osx-arm64-tar",
 | 
				
			||||||
 | 
					      "osx-x64-pkg",
 | 
				
			||||||
 | 
					      "osx-x64-tar",
 | 
				
			||||||
 | 
					      "src",
 | 
				
			||||||
 | 
					      "win-x64-7z",
 | 
				
			||||||
 | 
					      "win-x64-exe",
 | 
				
			||||||
 | 
					      "win-x64-msi",
 | 
				
			||||||
 | 
					      "win-x64-zip",
 | 
				
			||||||
 | 
					      "win-x86-7z",
 | 
				
			||||||
 | 
					      "win-x86-exe",
 | 
				
			||||||
 | 
					      "win-x86-msi",
 | 
				
			||||||
 | 
					      "win-x86-zip"
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "npm": "8.19.2",
 | 
				
			||||||
 | 
					    "v8": "10.9.125.0",
 | 
				
			||||||
 | 
					    "uv": "1.43.0",
 | 
				
			||||||
 | 
					    "zlib": "1.2.11",
 | 
				
			||||||
 | 
					    "openssl": "3.0.5+quic",
 | 
				
			||||||
 | 
					    "modules": "112",
 | 
				
			||||||
 | 
					    "lts": false,
 | 
				
			||||||
 | 
					    "security": false
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    "version": "v20.0.0-v8-canary202210293881e51ba2",
 | 
				
			||||||
 | 
					    "date": "2022-10-29",
 | 
				
			||||||
 | 
					    "files": [
 | 
				
			||||||
 | 
					      "headers",
 | 
				
			||||||
 | 
					      "linux-arm64",
 | 
				
			||||||
 | 
					      "linux-armv7l",
 | 
				
			||||||
 | 
					      "linux-ppc64le",
 | 
				
			||||||
 | 
					      "linux-s390x",
 | 
				
			||||||
 | 
					      "linux-x64",
 | 
				
			||||||
 | 
					      "osx-arm64-tar",
 | 
				
			||||||
 | 
					      "osx-x64-pkg",
 | 
				
			||||||
 | 
					      "osx-x64-tar",
 | 
				
			||||||
 | 
					      "src",
 | 
				
			||||||
 | 
					      "win-x64-7z",
 | 
				
			||||||
 | 
					      "win-x64-exe",
 | 
				
			||||||
 | 
					      "win-x64-msi",
 | 
				
			||||||
 | 
					      "win-x64-zip",
 | 
				
			||||||
 | 
					      "win-x86-7z",
 | 
				
			||||||
 | 
					      "win-x86-exe",
 | 
				
			||||||
 | 
					      "win-x86-msi",
 | 
				
			||||||
 | 
					      "win-x86-zip"
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "npm": "8.19.2",
 | 
				
			||||||
 | 
					    "v8": "10.9.122.0",
 | 
				
			||||||
 | 
					    "uv": "1.43.0",
 | 
				
			||||||
 | 
					    "zlib": "1.2.11",
 | 
				
			||||||
 | 
					    "openssl": "3.0.5+quic",
 | 
				
			||||||
 | 
					    "modules": "112",
 | 
				
			||||||
 | 
					    "lts": false,
 | 
				
			||||||
 | 
					    "security": false
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    "version": "v20.0.0-v8-canary202210286fe49d2a49",
 | 
				
			||||||
 | 
					    "date": "2022-10-28",
 | 
				
			||||||
 | 
					    "files": [
 | 
				
			||||||
 | 
					      "osx-arm64-tar",
 | 
				
			||||||
 | 
					      "osx-x64-pkg",
 | 
				
			||||||
 | 
					      "osx-x64-tar",
 | 
				
			||||||
 | 
					      "win-x64-7z",
 | 
				
			||||||
 | 
					      "win-x64-exe",
 | 
				
			||||||
 | 
					      "win-x64-msi",
 | 
				
			||||||
 | 
					      "win-x64-zip",
 | 
				
			||||||
 | 
					      "win-x86-7z",
 | 
				
			||||||
 | 
					      "win-x86-exe",
 | 
				
			||||||
 | 
					      "win-x86-msi",
 | 
				
			||||||
 | 
					      "win-x86-zip"
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "npm": "8.19.2",
 | 
				
			||||||
 | 
					    "v8": "10.9.112.0",
 | 
				
			||||||
 | 
					    "uv": "1.43.0",
 | 
				
			||||||
 | 
					    "zlib": "1.2.11",
 | 
				
			||||||
 | 
					    "openssl": "3.0.5+quic",
 | 
				
			||||||
 | 
					    "modules": "112",
 | 
				
			||||||
 | 
					    "lts": false,
 | 
				
			||||||
 | 
					    "security": false
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    "version": "v20.0.0-v8-canary20221027c470b3108c",
 | 
				
			||||||
 | 
					    "date": "2022-10-27",
 | 
				
			||||||
 | 
					    "files": [
 | 
				
			||||||
 | 
					      "headers",
 | 
				
			||||||
 | 
					      "linux-arm64",
 | 
				
			||||||
 | 
					      "linux-armv7l",
 | 
				
			||||||
 | 
					      "linux-ppc64le",
 | 
				
			||||||
 | 
					      "linux-s390x",
 | 
				
			||||||
 | 
					      "linux-x64",
 | 
				
			||||||
 | 
					      "osx-arm64-tar",
 | 
				
			||||||
 | 
					      "osx-x64-pkg",
 | 
				
			||||||
 | 
					      "osx-x64-tar",
 | 
				
			||||||
 | 
					      "src",
 | 
				
			||||||
 | 
					      "win-x64-7z",
 | 
				
			||||||
 | 
					      "win-x64-exe",
 | 
				
			||||||
 | 
					      "win-x64-msi",
 | 
				
			||||||
 | 
					      "win-x64-zip",
 | 
				
			||||||
 | 
					      "win-x86-7z",
 | 
				
			||||||
 | 
					      "win-x86-exe",
 | 
				
			||||||
 | 
					      "win-x86-msi",
 | 
				
			||||||
 | 
					      "win-x86-zip"
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "npm": "8.19.2",
 | 
				
			||||||
 | 
					    "v8": "10.9.101.0",
 | 
				
			||||||
 | 
					    "uv": "1.43.0",
 | 
				
			||||||
 | 
					    "zlib": "1.2.11",
 | 
				
			||||||
 | 
					    "openssl": "3.0.5+quic",
 | 
				
			||||||
 | 
					    "modules": "112",
 | 
				
			||||||
 | 
					    "lts": false,
 | 
				
			||||||
 | 
					    "security": false
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    "version": "v20.0.0-v8-canary20221026c24f7d1e4a",
 | 
				
			||||||
 | 
					    "date": "2022-10-26",
 | 
				
			||||||
 | 
					    "files": [
 | 
				
			||||||
 | 
					      "headers",
 | 
				
			||||||
 | 
					      "linux-arm64",
 | 
				
			||||||
 | 
					      "linux-armv7l",
 | 
				
			||||||
 | 
					      "linux-ppc64le",
 | 
				
			||||||
 | 
					      "linux-s390x",
 | 
				
			||||||
 | 
					      "linux-x64",
 | 
				
			||||||
 | 
					      "osx-arm64-tar",
 | 
				
			||||||
 | 
					      "osx-x64-pkg",
 | 
				
			||||||
 | 
					      "osx-x64-tar",
 | 
				
			||||||
 | 
					      "src",
 | 
				
			||||||
 | 
					      "win-x64-7z",
 | 
				
			||||||
 | 
					      "win-x64-exe",
 | 
				
			||||||
 | 
					      "win-x64-msi",
 | 
				
			||||||
 | 
					      "win-x64-zip",
 | 
				
			||||||
 | 
					      "win-x86-7z",
 | 
				
			||||||
 | 
					      "win-x86-exe",
 | 
				
			||||||
 | 
					      "win-x86-msi",
 | 
				
			||||||
 | 
					      "win-x86-zip"
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "npm": "8.19.2",
 | 
				
			||||||
 | 
					    "v8": "10.9.88.0",
 | 
				
			||||||
 | 
					    "uv": "1.43.0",
 | 
				
			||||||
 | 
					    "zlib": "1.2.11",
 | 
				
			||||||
 | 
					    "openssl": "3.0.5+quic",
 | 
				
			||||||
 | 
					    "modules": "112",
 | 
				
			||||||
 | 
					    "lts": false,
 | 
				
			||||||
 | 
					    "security": false
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    "version": "v20.0.0-v8-canary20221025b063237e20",
 | 
				
			||||||
 | 
					    "date": "2022-10-25",
 | 
				
			||||||
 | 
					    "files": [
 | 
				
			||||||
 | 
					      "headers",
 | 
				
			||||||
 | 
					      "linux-arm64",
 | 
				
			||||||
 | 
					      "linux-armv7l",
 | 
				
			||||||
 | 
					      "linux-ppc64le",
 | 
				
			||||||
 | 
					      "linux-x64",
 | 
				
			||||||
 | 
					      "osx-arm64-tar",
 | 
				
			||||||
 | 
					      "osx-x64-pkg",
 | 
				
			||||||
 | 
					      "osx-x64-tar",
 | 
				
			||||||
 | 
					      "src",
 | 
				
			||||||
 | 
					      "win-x64-7z",
 | 
				
			||||||
 | 
					      "win-x64-exe",
 | 
				
			||||||
 | 
					      "win-x64-msi",
 | 
				
			||||||
 | 
					      "win-x64-zip",
 | 
				
			||||||
 | 
					      "win-x86-7z",
 | 
				
			||||||
 | 
					      "win-x86-exe",
 | 
				
			||||||
 | 
					      "win-x86-msi",
 | 
				
			||||||
 | 
					      "win-x86-zip"
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "npm": "8.19.2",
 | 
				
			||||||
 | 
					    "v8": "10.9.73.0",
 | 
				
			||||||
 | 
					    "uv": "1.43.0",
 | 
				
			||||||
 | 
					    "zlib": "1.2.11",
 | 
				
			||||||
 | 
					    "openssl": "3.0.5+quic",
 | 
				
			||||||
 | 
					    "modules": "112",
 | 
				
			||||||
 | 
					    "lts": false,
 | 
				
			||||||
 | 
					    "security": false
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    "version": "v20.0.0-v8-canary2022102454996f930f",
 | 
				
			||||||
 | 
					    "date": "2022-10-24",
 | 
				
			||||||
 | 
					    "files": [
 | 
				
			||||||
 | 
					      "headers",
 | 
				
			||||||
 | 
					      "linux-arm64",
 | 
				
			||||||
 | 
					      "linux-armv7l",
 | 
				
			||||||
 | 
					      "linux-ppc64le",
 | 
				
			||||||
 | 
					      "linux-x64",
 | 
				
			||||||
 | 
					      "osx-arm64-tar",
 | 
				
			||||||
 | 
					      "osx-x64-pkg",
 | 
				
			||||||
 | 
					      "osx-x64-tar",
 | 
				
			||||||
 | 
					      "src",
 | 
				
			||||||
 | 
					      "win-x64-7z",
 | 
				
			||||||
 | 
					      "win-x64-exe",
 | 
				
			||||||
 | 
					      "win-x64-msi",
 | 
				
			||||||
 | 
					      "win-x64-zip",
 | 
				
			||||||
 | 
					      "win-x86-7z",
 | 
				
			||||||
 | 
					      "win-x86-exe",
 | 
				
			||||||
 | 
					      "win-x86-msi",
 | 
				
			||||||
 | 
					      "win-x86-zip"
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "npm": "8.19.2",
 | 
				
			||||||
 | 
					    "v8": "10.9.61.0",
 | 
				
			||||||
 | 
					    "uv": "1.43.0",
 | 
				
			||||||
 | 
					    "zlib": "1.2.11",
 | 
				
			||||||
 | 
					    "openssl": "3.0.5+quic",
 | 
				
			||||||
 | 
					    "modules": "112",
 | 
				
			||||||
 | 
					    "lts": false,
 | 
				
			||||||
 | 
					    "security": false
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    "version": "v20.0.0-v8-canary2022102310ff1e5a8d",
 | 
				
			||||||
 | 
					    "date": "2022-10-23",
 | 
				
			||||||
 | 
					    "files": [
 | 
				
			||||||
 | 
					      "headers",
 | 
				
			||||||
 | 
					      "linux-arm64",
 | 
				
			||||||
 | 
					      "linux-armv7l",
 | 
				
			||||||
 | 
					      "linux-ppc64le",
 | 
				
			||||||
 | 
					      "linux-x64",
 | 
				
			||||||
 | 
					      "osx-arm64-tar",
 | 
				
			||||||
 | 
					      "osx-x64-tar",
 | 
				
			||||||
 | 
					      "src",
 | 
				
			||||||
 | 
					      "win-x64-7z",
 | 
				
			||||||
 | 
					      "win-x64-exe",
 | 
				
			||||||
 | 
					      "win-x64-msi",
 | 
				
			||||||
 | 
					      "win-x64-zip",
 | 
				
			||||||
 | 
					      "win-x86-7z",
 | 
				
			||||||
 | 
					      "win-x86-exe",
 | 
				
			||||||
 | 
					      "win-x86-msi",
 | 
				
			||||||
 | 
					      "win-x86-zip"
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "npm": "8.19.2",
 | 
				
			||||||
 | 
					    "v8": "10.9.61.0",
 | 
				
			||||||
 | 
					    "uv": "1.43.0",
 | 
				
			||||||
 | 
					    "zlib": "1.2.11",
 | 
				
			||||||
 | 
					    "openssl": "3.0.5+quic",
 | 
				
			||||||
 | 
					    "modules": "112",
 | 
				
			||||||
 | 
					    "lts": false,
 | 
				
			||||||
 | 
					    "security": false
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    "version": "v20.0.0-v8-canary20221022e83bcb6c41",
 | 
				
			||||||
 | 
					    "date": "2022-10-22",
 | 
				
			||||||
 | 
					    "files": [
 | 
				
			||||||
 | 
					      "headers",
 | 
				
			||||||
 | 
					      "linux-arm64",
 | 
				
			||||||
 | 
					      "linux-armv7l",
 | 
				
			||||||
 | 
					      "linux-x64",
 | 
				
			||||||
 | 
					      "osx-arm64-tar",
 | 
				
			||||||
 | 
					      "osx-x64-tar",
 | 
				
			||||||
 | 
					      "src",
 | 
				
			||||||
 | 
					      "win-x64-7z",
 | 
				
			||||||
 | 
					      "win-x64-exe",
 | 
				
			||||||
 | 
					      "win-x64-msi",
 | 
				
			||||||
 | 
					      "win-x64-zip",
 | 
				
			||||||
 | 
					      "win-x86-7z",
 | 
				
			||||||
 | 
					      "win-x86-exe",
 | 
				
			||||||
 | 
					      "win-x86-msi",
 | 
				
			||||||
 | 
					      "win-x86-zip"
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "npm": "8.19.2",
 | 
				
			||||||
 | 
					    "v8": "10.9.60.0",
 | 
				
			||||||
 | 
					    "uv": "1.43.0",
 | 
				
			||||||
 | 
					    "zlib": "1.2.11",
 | 
				
			||||||
 | 
					    "openssl": "3.0.5+quic",
 | 
				
			||||||
 | 
					    "modules": "112",
 | 
				
			||||||
 | 
					    "lts": false,
 | 
				
			||||||
 | 
					    "security": false
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    "version": "v20.0.0-v8-canary20221021f6d5f347fa",
 | 
				
			||||||
 | 
					    "date": "2022-10-21",
 | 
				
			||||||
 | 
					    "files": [
 | 
				
			||||||
 | 
					      "headers",
 | 
				
			||||||
 | 
					      "linux-arm64",
 | 
				
			||||||
 | 
					      "linux-armv7l",
 | 
				
			||||||
 | 
					      "linux-x64",
 | 
				
			||||||
 | 
					      "osx-arm64-tar",
 | 
				
			||||||
 | 
					      "osx-x64-tar",
 | 
				
			||||||
 | 
					      "src",
 | 
				
			||||||
 | 
					      "win-x64-7z",
 | 
				
			||||||
 | 
					      "win-x64-exe",
 | 
				
			||||||
 | 
					      "win-x64-msi",
 | 
				
			||||||
 | 
					      "win-x64-zip"
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "npm": "8.19.2",
 | 
				
			||||||
 | 
					    "v8": "10.9.48.0",
 | 
				
			||||||
 | 
					    "uv": "1.43.0",
 | 
				
			||||||
 | 
					    "zlib": "1.2.11",
 | 
				
			||||||
 | 
					    "openssl": "3.0.5+quic",
 | 
				
			||||||
 | 
					    "modules": "112",
 | 
				
			||||||
 | 
					    "lts": false,
 | 
				
			||||||
 | 
					    "security": false
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    "version": "v20.0.0-v8-canary20221020f78c149307",
 | 
				
			||||||
 | 
					    "date": "2022-10-20",
 | 
				
			||||||
 | 
					    "files": [
 | 
				
			||||||
 | 
					      "headers",
 | 
				
			||||||
 | 
					      "linux-arm64",
 | 
				
			||||||
 | 
					      "linux-armv7l",
 | 
				
			||||||
 | 
					      "linux-x64",
 | 
				
			||||||
 | 
					      "osx-arm64-tar",
 | 
				
			||||||
 | 
					      "osx-x64-pkg",
 | 
				
			||||||
 | 
					      "osx-x64-tar",
 | 
				
			||||||
 | 
					      "src",
 | 
				
			||||||
 | 
					      "win-x64-7z",
 | 
				
			||||||
 | 
					      "win-x64-exe",
 | 
				
			||||||
 | 
					      "win-x64-msi",
 | 
				
			||||||
 | 
					      "win-x64-zip"
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "npm": "8.19.2",
 | 
				
			||||||
 | 
					    "v8": "10.9.38.0",
 | 
				
			||||||
 | 
					    "uv": "1.43.0",
 | 
				
			||||||
 | 
					    "zlib": "1.2.11",
 | 
				
			||||||
 | 
					    "openssl": "3.0.5+quic",
 | 
				
			||||||
 | 
					    "modules": "112",
 | 
				
			||||||
 | 
					    "lts": false,
 | 
				
			||||||
 | 
					    "security": false
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    "version": "v20.0.0-v8-canary20221019d52c76f76e",
 | 
				
			||||||
 | 
					    "date": "2022-10-19",
 | 
				
			||||||
 | 
					    "files": [
 | 
				
			||||||
 | 
					      "aix-ppc64",
 | 
				
			||||||
 | 
					      "headers",
 | 
				
			||||||
 | 
					      "linux-arm64",
 | 
				
			||||||
 | 
					      "linux-armv7l",
 | 
				
			||||||
 | 
					      "linux-ppc64le",
 | 
				
			||||||
 | 
					      "linux-x64",
 | 
				
			||||||
 | 
					      "osx-arm64-tar",
 | 
				
			||||||
 | 
					      "osx-x64-pkg",
 | 
				
			||||||
 | 
					      "osx-x64-tar",
 | 
				
			||||||
 | 
					      "src",
 | 
				
			||||||
 | 
					      "win-x64-7z",
 | 
				
			||||||
 | 
					      "win-x64-exe",
 | 
				
			||||||
 | 
					      "win-x64-msi",
 | 
				
			||||||
 | 
					      "win-x64-zip"
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "npm": "8.19.2",
 | 
				
			||||||
 | 
					    "v8": "10.9.27.0",
 | 
				
			||||||
 | 
					    "uv": "1.43.0",
 | 
				
			||||||
 | 
					    "zlib": "1.2.11",
 | 
				
			||||||
 | 
					    "openssl": "3.0.5+quic",
 | 
				
			||||||
 | 
					    "modules": "112",
 | 
				
			||||||
 | 
					    "lts": false,
 | 
				
			||||||
 | 
					    "security": false
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    "version": "v19.0.0-v8-canary202210187d6960f23f",
 | 
				
			||||||
 | 
					    "date": "2022-10-18",
 | 
				
			||||||
 | 
					    "files": [
 | 
				
			||||||
 | 
					      "aix-ppc64",
 | 
				
			||||||
 | 
					      "headers",
 | 
				
			||||||
 | 
					      "linux-arm64",
 | 
				
			||||||
 | 
					      "linux-armv7l",
 | 
				
			||||||
 | 
					      "linux-ppc64le",
 | 
				
			||||||
 | 
					      "linux-s390x",
 | 
				
			||||||
 | 
					      "linux-x64",
 | 
				
			||||||
 | 
					      "osx-arm64-tar",
 | 
				
			||||||
 | 
					      "osx-x64-tar",
 | 
				
			||||||
 | 
					      "src",
 | 
				
			||||||
 | 
					      "win-x64-7z",
 | 
				
			||||||
 | 
					      "win-x64-exe",
 | 
				
			||||||
 | 
					      "win-x64-msi",
 | 
				
			||||||
 | 
					      "win-x64-zip"
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "npm": "8.19.2",
 | 
				
			||||||
 | 
					    "v8": "10.9.12.0",
 | 
				
			||||||
 | 
					    "uv": "1.43.0",
 | 
				
			||||||
 | 
					    "zlib": "1.2.11",
 | 
				
			||||||
 | 
					    "openssl": "3.0.5+quic",
 | 
				
			||||||
 | 
					    "modules": "112",
 | 
				
			||||||
 | 
					    "lts": false,
 | 
				
			||||||
 | 
					    "security": false
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    "version": "v19.0.0-v8-canary202210172ec229fc56",
 | 
				
			||||||
 | 
					    "date": "2022-10-17",
 | 
				
			||||||
 | 
					    "files": [
 | 
				
			||||||
 | 
					      "aix-ppc64",
 | 
				
			||||||
 | 
					      "headers",
 | 
				
			||||||
 | 
					      "linux-arm64",
 | 
				
			||||||
 | 
					      "linux-armv7l",
 | 
				
			||||||
 | 
					      "linux-ppc64le",
 | 
				
			||||||
 | 
					      "linux-s390x",
 | 
				
			||||||
 | 
					      "linux-x64",
 | 
				
			||||||
 | 
					      "osx-arm64-tar",
 | 
				
			||||||
 | 
					      "osx-x64-tar",
 | 
				
			||||||
 | 
					      "src",
 | 
				
			||||||
 | 
					      "win-x64-7z",
 | 
				
			||||||
 | 
					      "win-x64-exe",
 | 
				
			||||||
 | 
					      "win-x64-msi",
 | 
				
			||||||
 | 
					      "win-x64-zip"
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "npm": "8.19.2",
 | 
				
			||||||
 | 
					    "v8": "10.9.6.0",
 | 
				
			||||||
 | 
					    "uv": "1.43.0",
 | 
				
			||||||
 | 
					    "zlib": "1.2.11",
 | 
				
			||||||
 | 
					    "openssl": "3.0.5+quic",
 | 
				
			||||||
 | 
					    "modules": "112",
 | 
				
			||||||
 | 
					    "lts": false,
 | 
				
			||||||
 | 
					    "security": false
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
							
								
								
									
										303
									
								
								__tests__/main.test.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										303
									
								
								__tests__/main.test.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,303 @@
 | 
				
			|||||||
 | 
					import * as core from '@actions/core';
 | 
				
			||||||
 | 
					import * as exec from '@actions/exec';
 | 
				
			||||||
 | 
					import * as tc from '@actions/tool-cache';
 | 
				
			||||||
 | 
					import * as cache from '@actions/cache';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import fs from 'fs';
 | 
				
			||||||
 | 
					import path from 'path';
 | 
				
			||||||
 | 
					import osm from 'os';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import each from 'jest-each';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import * as main from '../src/main';
 | 
				
			||||||
 | 
					import * as util from '../src/util';
 | 
				
			||||||
 | 
					import OfficialBuilds from '../src/distributions/official_builds/official_builds';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					describe('main tests', () => {
 | 
				
			||||||
 | 
					  let inputs = {} as any;
 | 
				
			||||||
 | 
					  let os = {} as any;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let infoSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let warningSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let inSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let setOutputSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let startGroupSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let endGroupSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let existsSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let getExecOutputSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let parseNodeVersionSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let cnSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let findSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let isCacheActionAvailable: jest.SpyInstance;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let setupNodeJsSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  beforeEach(() => {
 | 
				
			||||||
 | 
					    inputs = {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // node
 | 
				
			||||||
 | 
					    os = {};
 | 
				
			||||||
 | 
					    console.log('::stop-commands::stoptoken');
 | 
				
			||||||
 | 
					    process.env['GITHUB_PATH'] = ''; // Stub out ENV file functionality so we can verify it writes to standard out
 | 
				
			||||||
 | 
					    process.env['GITHUB_OUTPUT'] = ''; // Stub out ENV file functionality so we can verify it writes to standard out
 | 
				
			||||||
 | 
					    infoSpy = jest.spyOn(core, 'info');
 | 
				
			||||||
 | 
					    infoSpy.mockImplementation(() => {});
 | 
				
			||||||
 | 
					    setOutputSpy = jest.spyOn(core, 'setOutput');
 | 
				
			||||||
 | 
					    setOutputSpy.mockImplementation(() => {});
 | 
				
			||||||
 | 
					    warningSpy = jest.spyOn(core, 'warning');
 | 
				
			||||||
 | 
					    warningSpy.mockImplementation(() => {});
 | 
				
			||||||
 | 
					    startGroupSpy = jest.spyOn(core, 'startGroup');
 | 
				
			||||||
 | 
					    startGroupSpy.mockImplementation(() => {});
 | 
				
			||||||
 | 
					    endGroupSpy = jest.spyOn(core, 'endGroup');
 | 
				
			||||||
 | 
					    endGroupSpy.mockImplementation(() => {});
 | 
				
			||||||
 | 
					    inSpy = jest.spyOn(core, 'getInput');
 | 
				
			||||||
 | 
					    inSpy.mockImplementation(name => inputs[name]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    getExecOutputSpy = jest.spyOn(exec, 'getExecOutput');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    findSpy = jest.spyOn(tc, 'find');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    isCacheActionAvailable = jest.spyOn(cache, 'isFeatureAvailable');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    existsSpy = jest.spyOn(fs, 'existsSync');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cnSpy = jest.spyOn(process.stdout, 'write');
 | 
				
			||||||
 | 
					    cnSpy.mockImplementation(line => {
 | 
				
			||||||
 | 
					      // uncomment to debug
 | 
				
			||||||
 | 
					      // process.stderr.write('write:' + line + '\n');
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    setupNodeJsSpy = jest.spyOn(OfficialBuilds.prototype, 'setupNodeJs');
 | 
				
			||||||
 | 
					    setupNodeJsSpy.mockImplementation(() => {});
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  afterEach(() => {
 | 
				
			||||||
 | 
					    jest.resetAllMocks();
 | 
				
			||||||
 | 
					    jest.clearAllMocks();
 | 
				
			||||||
 | 
					    //jest.restoreAllMocks();
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  afterAll(async () => {
 | 
				
			||||||
 | 
					    console.log('::stoptoken::');
 | 
				
			||||||
 | 
					    jest.restoreAllMocks();
 | 
				
			||||||
 | 
					  }, 100000);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  describe('parseNodeVersionFile', () => {
 | 
				
			||||||
 | 
					    each`
 | 
				
			||||||
 | 
					      contents                                     | expected
 | 
				
			||||||
 | 
					      ${'12'}                                      | ${'12'}
 | 
				
			||||||
 | 
					      ${'12.3'}                                    | ${'12.3'}
 | 
				
			||||||
 | 
					      ${'12.3.4'}                                  | ${'12.3.4'}
 | 
				
			||||||
 | 
					      ${'v12.3.4'}                                 | ${'12.3.4'}
 | 
				
			||||||
 | 
					      ${'lts/erbium'}                              | ${'lts/erbium'}
 | 
				
			||||||
 | 
					      ${'lts/*'}                                   | ${'lts/*'}
 | 
				
			||||||
 | 
					      ${'nodejs 12.3.4'}                           | ${'12.3.4'}
 | 
				
			||||||
 | 
					      ${'ruby 2.3.4\nnodejs 12.3.4\npython 3.4.5'} | ${'12.3.4'}
 | 
				
			||||||
 | 
					      ${''}                                        | ${''}
 | 
				
			||||||
 | 
					      ${'unknown format'}                          | ${'unknown format'}
 | 
				
			||||||
 | 
					      ${'  14.1.0  '}                              | ${'14.1.0'}
 | 
				
			||||||
 | 
					      ${'{"volta": {"node": ">=14.0.0 <=17.0.0"}}'}| ${'>=14.0.0 <=17.0.0'}
 | 
				
			||||||
 | 
					      ${'{"engines": {"node": "17.0.0"}}'}         | ${'17.0.0'}
 | 
				
			||||||
 | 
					    `.it('parses "$contents"', ({contents, expected}) => {
 | 
				
			||||||
 | 
					      expect(util.parseNodeVersionFile(contents)).toBe(expected);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  describe('printEnvDetailsAndSetOutput', () => {
 | 
				
			||||||
 | 
					    it.each([
 | 
				
			||||||
 | 
					      [{node: '12.0.2', npm: '6.3.3', yarn: '1.22.11'}],
 | 
				
			||||||
 | 
					      [{node: '16.0.2', npm: '7.3.3', yarn: '2.22.11'}],
 | 
				
			||||||
 | 
					      [{node: '14.0.1', npm: '8.1.0', yarn: '3.2.1'}],
 | 
				
			||||||
 | 
					      [{node: '17.0.2', npm: '6.3.3', yarn: ''}]
 | 
				
			||||||
 | 
					    ])('Tools versions %p', async obj => {
 | 
				
			||||||
 | 
					      getExecOutputSpy.mockImplementation(async command => {
 | 
				
			||||||
 | 
					        if (Reflect.has(obj, command) && !obj[command]) {
 | 
				
			||||||
 | 
					          return {
 | 
				
			||||||
 | 
					            stdout: '',
 | 
				
			||||||
 | 
					            stderr: `${command} does not exist`,
 | 
				
			||||||
 | 
					            exitCode: 1
 | 
				
			||||||
 | 
					          };
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return {stdout: obj[command], stderr: '', exitCode: 0};
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      await util.printEnvDetailsAndSetOutput();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      expect(setOutputSpy).toHaveBeenCalledWith('node-version', obj['node']);
 | 
				
			||||||
 | 
					      Object.getOwnPropertyNames(obj).forEach(name => {
 | 
				
			||||||
 | 
					        if (!obj[name]) {
 | 
				
			||||||
 | 
					          expect(infoSpy).toHaveBeenCalledWith(
 | 
				
			||||||
 | 
					            `[warning]${name} does not exist`
 | 
				
			||||||
 | 
					          );
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        expect(infoSpy).toHaveBeenCalledWith(`${name}: ${obj[name]}`);
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  describe('node-version-file flag', () => {
 | 
				
			||||||
 | 
					    beforeEach(() => {
 | 
				
			||||||
 | 
					      parseNodeVersionSpy = jest.spyOn(util, 'parseNodeVersionFile');
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it('not used if node-version is provided', async () => {
 | 
				
			||||||
 | 
					      // Arrange
 | 
				
			||||||
 | 
					      inputs['node-version'] = '12';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Act
 | 
				
			||||||
 | 
					      await main.run();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Assert
 | 
				
			||||||
 | 
					      expect(parseNodeVersionSpy).toHaveBeenCalledTimes(0);
 | 
				
			||||||
 | 
					    }, 10000);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it('not used if node-version-file not provided', async () => {
 | 
				
			||||||
 | 
					      // Act
 | 
				
			||||||
 | 
					      await main.run();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Assert
 | 
				
			||||||
 | 
					      expect(parseNodeVersionSpy).toHaveBeenCalledTimes(0);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it('reads node-version-file if provided', async () => {
 | 
				
			||||||
 | 
					      // Arrange
 | 
				
			||||||
 | 
					      const versionSpec = 'v14';
 | 
				
			||||||
 | 
					      const versionFile = '.nvmrc';
 | 
				
			||||||
 | 
					      const expectedVersionSpec = '14';
 | 
				
			||||||
 | 
					      process.env['GITHUB_WORKSPACE'] = path.join(__dirname, 'data');
 | 
				
			||||||
 | 
					      inputs['node-version-file'] = versionFile;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      parseNodeVersionSpy.mockImplementation(() => expectedVersionSpec);
 | 
				
			||||||
 | 
					      existsSpy.mockImplementationOnce(
 | 
				
			||||||
 | 
					        input => input === path.join(__dirname, 'data', versionFile)
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Act
 | 
				
			||||||
 | 
					      await main.run();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Assert
 | 
				
			||||||
 | 
					      expect(existsSpy).toHaveBeenCalledTimes(1);
 | 
				
			||||||
 | 
					      expect(existsSpy).toHaveReturnedWith(true);
 | 
				
			||||||
 | 
					      expect(parseNodeVersionSpy).toHaveBeenCalledWith(versionSpec);
 | 
				
			||||||
 | 
					      expect(infoSpy).toHaveBeenCalledWith(
 | 
				
			||||||
 | 
					        `Resolved ${versionFile} as ${expectedVersionSpec}`
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					    }, 10000);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it('reads package.json as node-version-file if provided', async () => {
 | 
				
			||||||
 | 
					      // Arrange
 | 
				
			||||||
 | 
					      const versionSpec = fs.readFileSync(
 | 
				
			||||||
 | 
					        path.join(__dirname, 'data/package.json'),
 | 
				
			||||||
 | 
					        'utf-8'
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					      const versionFile = 'package.json';
 | 
				
			||||||
 | 
					      const expectedVersionSpec = '14';
 | 
				
			||||||
 | 
					      process.env['GITHUB_WORKSPACE'] = path.join(__dirname, 'data');
 | 
				
			||||||
 | 
					      inputs['node-version-file'] = versionFile;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      parseNodeVersionSpy.mockImplementation(() => expectedVersionSpec);
 | 
				
			||||||
 | 
					      existsSpy.mockImplementationOnce(
 | 
				
			||||||
 | 
					        input => input === path.join(__dirname, 'data', versionFile)
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					      // Act
 | 
				
			||||||
 | 
					      await main.run();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Assert
 | 
				
			||||||
 | 
					      expect(existsSpy).toHaveBeenCalledTimes(1);
 | 
				
			||||||
 | 
					      expect(existsSpy).toHaveReturnedWith(true);
 | 
				
			||||||
 | 
					      expect(parseNodeVersionSpy).toHaveBeenCalledWith(versionSpec);
 | 
				
			||||||
 | 
					      expect(infoSpy).toHaveBeenCalledWith(
 | 
				
			||||||
 | 
					        `Resolved ${versionFile} as ${expectedVersionSpec}`
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					    }, 10000);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it('both node-version-file and node-version are provided', async () => {
 | 
				
			||||||
 | 
					      inputs['node-version'] = '12';
 | 
				
			||||||
 | 
					      const versionSpec = 'v14';
 | 
				
			||||||
 | 
					      const versionFile = '.nvmrc';
 | 
				
			||||||
 | 
					      const expectedVersionSpec = '14';
 | 
				
			||||||
 | 
					      process.env['GITHUB_WORKSPACE'] = path.join(__dirname, '..');
 | 
				
			||||||
 | 
					      inputs['node-version-file'] = versionFile;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      parseNodeVersionSpy.mockImplementation(() => expectedVersionSpec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Act
 | 
				
			||||||
 | 
					      await main.run();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Assert
 | 
				
			||||||
 | 
					      expect(existsSpy).toHaveBeenCalledTimes(0);
 | 
				
			||||||
 | 
					      expect(parseNodeVersionSpy).not.toHaveBeenCalled();
 | 
				
			||||||
 | 
					      expect(warningSpy).toHaveBeenCalledWith(
 | 
				
			||||||
 | 
					        'Both node-version and node-version-file inputs are specified, only node-version will be used'
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it('should throw an error if node-version-file is not found', async () => {
 | 
				
			||||||
 | 
					      const versionFile = '.nvmrc';
 | 
				
			||||||
 | 
					      const versionFilePath = path.join(__dirname, '..', versionFile);
 | 
				
			||||||
 | 
					      inputs['node-version-file'] = versionFile;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      inSpy.mockImplementation(name => inputs[name]);
 | 
				
			||||||
 | 
					      existsSpy.mockImplementationOnce(
 | 
				
			||||||
 | 
					        input => input === path.join(__dirname, 'data', versionFile)
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Act
 | 
				
			||||||
 | 
					      await main.run();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Assert
 | 
				
			||||||
 | 
					      expect(existsSpy).toHaveBeenCalled();
 | 
				
			||||||
 | 
					      expect(existsSpy).toHaveReturnedWith(false);
 | 
				
			||||||
 | 
					      expect(parseNodeVersionSpy).not.toHaveBeenCalled();
 | 
				
			||||||
 | 
					      expect(cnSpy).toHaveBeenCalledWith(
 | 
				
			||||||
 | 
					        `::error::The specified node version file at: ${versionFilePath} does not exist${osm.EOL}`
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  describe('cache on GHES', () => {
 | 
				
			||||||
 | 
					    it('Should throw an error, because cache is not supported', async () => {
 | 
				
			||||||
 | 
					      inputs['node-version'] = '12';
 | 
				
			||||||
 | 
					      inputs['cache'] = 'npm';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      inSpy.mockImplementation(name => inputs[name]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      let toolPath = path.normalize('/cache/node/12.16.1/x64');
 | 
				
			||||||
 | 
					      findSpy.mockImplementation(() => toolPath);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // expect(logSpy).toHaveBeenCalledWith(`Found in cache @ ${toolPath}`);
 | 
				
			||||||
 | 
					      process.env['GITHUB_SERVER_URL'] = 'https://www.test.com';
 | 
				
			||||||
 | 
					      isCacheActionAvailable.mockImplementation(() => false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      await main.run();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      expect(warningSpy).toHaveBeenCalledWith(
 | 
				
			||||||
 | 
					        `Cache action is only supported on GHES version >= 3.5. If you are on version >=3.5 Please check with GHES admin if Actions cache service is enabled or not.`
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it('Should throw an internal error', async () => {
 | 
				
			||||||
 | 
					      inputs['node-version'] = '12';
 | 
				
			||||||
 | 
					      inputs['cache'] = 'npm';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      inSpy.mockImplementation(name => inputs[name]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      let toolPath = path.normalize('/cache/node/12.16.1/x64');
 | 
				
			||||||
 | 
					      findSpy.mockImplementation(() => toolPath);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // expect(logSpy).toHaveBeenCalledWith(`Found in cache @ ${toolPath}`);
 | 
				
			||||||
 | 
					      process.env['GITHUB_SERVER_URL'] = '';
 | 
				
			||||||
 | 
					      isCacheActionAvailable.mockImplementation(() => false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      await main.run();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      expect(warningSpy).toHaveBeenCalledWith(
 | 
				
			||||||
 | 
					        'The runner was not able to contact the cache service. Caching will be skipped'
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
							
								
								
									
										517
									
								
								__tests__/nightly-installer.test.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										517
									
								
								__tests__/nightly-installer.test.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,517 @@
 | 
				
			|||||||
 | 
					import * as core from '@actions/core';
 | 
				
			||||||
 | 
					import * as io from '@actions/io';
 | 
				
			||||||
 | 
					import * as tc from '@actions/tool-cache';
 | 
				
			||||||
 | 
					import * as httpm from '@actions/http-client';
 | 
				
			||||||
 | 
					import * as exec from '@actions/exec';
 | 
				
			||||||
 | 
					import * as cache from '@actions/cache';
 | 
				
			||||||
 | 
					import fs from 'fs';
 | 
				
			||||||
 | 
					import cp from 'child_process';
 | 
				
			||||||
 | 
					import osm from 'os';
 | 
				
			||||||
 | 
					import path from 'path';
 | 
				
			||||||
 | 
					import * as main from '../src/main';
 | 
				
			||||||
 | 
					import * as auth from '../src/authutil';
 | 
				
			||||||
 | 
					import {INodeVersion} from '../src/distributions/base-models';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const nodeTestManifest = require('./data/versions-manifest.json');
 | 
				
			||||||
 | 
					const nodeTestDist = require('./data/node-dist-index.json');
 | 
				
			||||||
 | 
					const nodeTestDistNightly = require('./data/node-nightly-index.json');
 | 
				
			||||||
 | 
					const nodeTestDistRc = require('./data/node-rc-index.json');
 | 
				
			||||||
 | 
					const nodeV8CanaryTestDist = require('./data/v8-canary-dist-index.json');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					describe('setup-node', () => {
 | 
				
			||||||
 | 
					  let inputs = {} as any;
 | 
				
			||||||
 | 
					  let os = {} as any;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let inSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let findSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let findAllVersionsSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let cnSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let logSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let warningSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let getManifestSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let getDistSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let platSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let archSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let dlSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let exSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let cacheSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let dbgSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let whichSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let existsSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let mkdirpSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let execSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let authSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let parseNodeVersionSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let isCacheActionAvailable: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let getExecOutputSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let getJsonSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  beforeEach(() => {
 | 
				
			||||||
 | 
					    // @actions/core
 | 
				
			||||||
 | 
					    console.log('::stop-commands::stoptoken'); // Disable executing of runner commands when running tests in actions
 | 
				
			||||||
 | 
					    process.env['GITHUB_PATH'] = ''; // Stub out ENV file functionality so we can verify it writes to standard out
 | 
				
			||||||
 | 
					    process.env['GITHUB_OUTPUT'] = ''; // Stub out ENV file functionality so we can verify it writes to standard out
 | 
				
			||||||
 | 
					    inputs = {};
 | 
				
			||||||
 | 
					    inSpy = jest.spyOn(core, 'getInput');
 | 
				
			||||||
 | 
					    inSpy.mockImplementation(name => inputs[name]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // node
 | 
				
			||||||
 | 
					    os = {};
 | 
				
			||||||
 | 
					    platSpy = jest.spyOn(osm, 'platform');
 | 
				
			||||||
 | 
					    platSpy.mockImplementation(() => os['platform']);
 | 
				
			||||||
 | 
					    archSpy = jest.spyOn(osm, 'arch');
 | 
				
			||||||
 | 
					    archSpy.mockImplementation(() => os['arch']);
 | 
				
			||||||
 | 
					    execSpy = jest.spyOn(cp, 'execSync');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // @actions/tool-cache
 | 
				
			||||||
 | 
					    findSpy = jest.spyOn(tc, 'find');
 | 
				
			||||||
 | 
					    findAllVersionsSpy = jest.spyOn(tc, 'findAllVersions');
 | 
				
			||||||
 | 
					    dlSpy = jest.spyOn(tc, 'downloadTool');
 | 
				
			||||||
 | 
					    exSpy = jest.spyOn(tc, 'extractTar');
 | 
				
			||||||
 | 
					    cacheSpy = jest.spyOn(tc, 'cacheDir');
 | 
				
			||||||
 | 
					    getManifestSpy = jest.spyOn(tc, 'getManifestFromRepo');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // http-client
 | 
				
			||||||
 | 
					    getJsonSpy = jest.spyOn(httpm.HttpClient.prototype, 'getJson');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // io
 | 
				
			||||||
 | 
					    whichSpy = jest.spyOn(io, 'which');
 | 
				
			||||||
 | 
					    existsSpy = jest.spyOn(fs, 'existsSync');
 | 
				
			||||||
 | 
					    mkdirpSpy = jest.spyOn(io, 'mkdirP');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // @actions/tool-cache
 | 
				
			||||||
 | 
					    isCacheActionAvailable = jest.spyOn(cache, 'isFeatureAvailable');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // disable authentication portion for installer tests
 | 
				
			||||||
 | 
					    authSpy = jest.spyOn(auth, 'configAuthentication');
 | 
				
			||||||
 | 
					    authSpy.mockImplementation(() => {});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    getJsonSpy.mockImplementation(url => {
 | 
				
			||||||
 | 
					      let res: any;
 | 
				
			||||||
 | 
					      if (url.includes('/rc')) {
 | 
				
			||||||
 | 
					        res = <INodeVersion>nodeTestDistRc;
 | 
				
			||||||
 | 
					      } else if (url.includes('/nightly')) {
 | 
				
			||||||
 | 
					        res = <INodeVersion>nodeTestDistNightly;
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        res = <INodeVersion>nodeTestDist;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      return {result: res};
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // writes
 | 
				
			||||||
 | 
					    cnSpy = jest.spyOn(process.stdout, 'write');
 | 
				
			||||||
 | 
					    logSpy = jest.spyOn(core, 'info');
 | 
				
			||||||
 | 
					    dbgSpy = jest.spyOn(core, 'debug');
 | 
				
			||||||
 | 
					    warningSpy = jest.spyOn(core, 'warning');
 | 
				
			||||||
 | 
					    cnSpy.mockImplementation(line => {
 | 
				
			||||||
 | 
					      // uncomment to debug
 | 
				
			||||||
 | 
					      // process.stderr.write('write:' + line + '\n');
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    logSpy.mockImplementation(line => {
 | 
				
			||||||
 | 
					      // uncomment to debug
 | 
				
			||||||
 | 
					      // process.stderr.write('log:' + line + '\n');
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    dbgSpy.mockImplementation(msg => {
 | 
				
			||||||
 | 
					      // uncomment to see debug output
 | 
				
			||||||
 | 
					      // process.stderr.write(msg + '\n');
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    warningSpy.mockImplementation(msg => {
 | 
				
			||||||
 | 
					      // uncomment to debug
 | 
				
			||||||
 | 
					      // process.stderr.write('log:' + msg + '\n');
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // @actions/exec
 | 
				
			||||||
 | 
					    getExecOutputSpy = jest.spyOn(exec, 'getExecOutput');
 | 
				
			||||||
 | 
					    getExecOutputSpy.mockImplementation(() => 'v16.15.0');
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  afterEach(() => {
 | 
				
			||||||
 | 
					    jest.resetAllMocks();
 | 
				
			||||||
 | 
					    jest.clearAllMocks();
 | 
				
			||||||
 | 
					    //jest.restoreAllMocks();
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  afterAll(async () => {
 | 
				
			||||||
 | 
					    console.log('::stoptoken::'); // Re-enable executing of runner commands when running tests in actions
 | 
				
			||||||
 | 
					    jest.restoreAllMocks();
 | 
				
			||||||
 | 
					  }, 100000);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  //--------------------------------------------------
 | 
				
			||||||
 | 
					  // Found in cache tests
 | 
				
			||||||
 | 
					  //--------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  it('finds version in cache with stable true', async () => {
 | 
				
			||||||
 | 
					    inputs['node-version'] = '16-nightly';
 | 
				
			||||||
 | 
					    os['arch'] = 'x64';
 | 
				
			||||||
 | 
					    inputs.stable = 'true';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let toolPath = path.normalize(
 | 
				
			||||||
 | 
					      '/cache/node/16.0.0-nightly20210417bc31dc0e0f/x64'
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    findSpy.mockImplementation(() => toolPath);
 | 
				
			||||||
 | 
					    findAllVersionsSpy.mockImplementation(() => [
 | 
				
			||||||
 | 
					      '12.0.1',
 | 
				
			||||||
 | 
					      '16.0.0-nightly20210415c3a5e15ebe',
 | 
				
			||||||
 | 
					      '16.0.0-nightly20210417bc31dc0e0f',
 | 
				
			||||||
 | 
					      '16.1.3'
 | 
				
			||||||
 | 
					    ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    await main.run();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    expect(findSpy).toHaveBeenCalledWith(
 | 
				
			||||||
 | 
					      'node',
 | 
				
			||||||
 | 
					      '16.0.0-nightly20210417bc31dc0e0f',
 | 
				
			||||||
 | 
					      'x64'
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    expect(logSpy).toHaveBeenCalledWith(`Found in cache @ ${toolPath}`);
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  it('finds version in cache with stable false', async () => {
 | 
				
			||||||
 | 
					    inputs['node-version'] = '16.0.0-nightly20210415c3a5e15ebe';
 | 
				
			||||||
 | 
					    os['arch'] = 'x64';
 | 
				
			||||||
 | 
					    inputs.stable = 'false';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let toolPath = path.normalize(
 | 
				
			||||||
 | 
					      '/cache/node/16.0.0-nightly20210415c3a5e15ebe/x64'
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    findSpy.mockImplementation(() => toolPath);
 | 
				
			||||||
 | 
					    findAllVersionsSpy.mockImplementation(() => [
 | 
				
			||||||
 | 
					      '12.0.1',
 | 
				
			||||||
 | 
					      '16.0.0-nightly20210415c3a5e15ebe',
 | 
				
			||||||
 | 
					      '16.0.0-nightly20210417bc31dc0e0f',
 | 
				
			||||||
 | 
					      '16.1.3'
 | 
				
			||||||
 | 
					    ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    await main.run();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    expect(findSpy).toHaveBeenCalledWith(
 | 
				
			||||||
 | 
					      'node',
 | 
				
			||||||
 | 
					      '16.0.0-nightly20210415c3a5e15ebe',
 | 
				
			||||||
 | 
					      'x64'
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    expect(logSpy).toHaveBeenCalledWith(`Found in cache @ ${toolPath}`);
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  it('finds version in cache and adds it to the path', async () => {
 | 
				
			||||||
 | 
					    inputs['node-version'] = '16-nightly';
 | 
				
			||||||
 | 
					    os['arch'] = 'x64';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    inSpy.mockImplementation(name => inputs[name]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let toolPath = path.normalize(
 | 
				
			||||||
 | 
					      '/cache/node/16.0.0-nightly20210417bc31dc0e0f/x64'
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    findSpy.mockImplementation(() => toolPath);
 | 
				
			||||||
 | 
					    findAllVersionsSpy.mockImplementation(() => [
 | 
				
			||||||
 | 
					      '12.0.1',
 | 
				
			||||||
 | 
					      '16.0.0-nightly20210415c3a5e15ebe',
 | 
				
			||||||
 | 
					      '16.0.0-nightly20210417bc31dc0e0f',
 | 
				
			||||||
 | 
					      '16.1.3'
 | 
				
			||||||
 | 
					    ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    await main.run();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    expect(findSpy).toHaveBeenCalledWith(
 | 
				
			||||||
 | 
					      'node',
 | 
				
			||||||
 | 
					      '16.0.0-nightly20210417bc31dc0e0f',
 | 
				
			||||||
 | 
					      'x64'
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let expPath = path.join(toolPath, 'bin');
 | 
				
			||||||
 | 
					    expect(cnSpy).toHaveBeenCalledWith(`::add-path::${expPath}${osm.EOL}`);
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  it('handles unhandled find error and reports error', async () => {
 | 
				
			||||||
 | 
					    let errMsg = 'unhandled error message';
 | 
				
			||||||
 | 
					    inputs['node-version'] = '16.0.0-nightly20210417bc31dc0e0f';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    findAllVersionsSpy.mockImplementation(() => [
 | 
				
			||||||
 | 
					      '12.0.1',
 | 
				
			||||||
 | 
					      '16.0.0-nightly20210415c3a5e15ebe',
 | 
				
			||||||
 | 
					      '16.0.0-nightly20210417bc31dc0e0f',
 | 
				
			||||||
 | 
					      '16.1.3'
 | 
				
			||||||
 | 
					    ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    findSpy.mockImplementation(() => {
 | 
				
			||||||
 | 
					      throw new Error(errMsg);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    await main.run();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    expect(cnSpy).toHaveBeenCalledWith('::error::' + errMsg + osm.EOL);
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  it('falls back to a version from node dist', async () => {
 | 
				
			||||||
 | 
					    os.platform = 'linux';
 | 
				
			||||||
 | 
					    os.arch = 'x64';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // a version which is not in the manifest but is in node dist
 | 
				
			||||||
 | 
					    let versionSpec = '13.13.1-nightly20200415947ddec091';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    inputs['node-version'] = versionSpec;
 | 
				
			||||||
 | 
					    inputs['always-auth'] = false;
 | 
				
			||||||
 | 
					    inputs['token'] = 'faketoken';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // ... but not in the local cache
 | 
				
			||||||
 | 
					    findSpy.mockImplementation(() => '');
 | 
				
			||||||
 | 
					    findAllVersionsSpy.mockImplementation(() => []);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dlSpy.mockImplementation(async () => '/some/temp/path');
 | 
				
			||||||
 | 
					    let toolPath = path.normalize(
 | 
				
			||||||
 | 
					      '/cache/node/13.13.1-nightly20200415947ddec091/x64'
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    exSpy.mockImplementation(async () => '/some/other/temp/path');
 | 
				
			||||||
 | 
					    cacheSpy.mockImplementation(async () => toolPath);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    await main.run();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let expPath = path.join(toolPath, 'bin');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    expect(dlSpy).toHaveBeenCalled();
 | 
				
			||||||
 | 
					    expect(exSpy).toHaveBeenCalled();
 | 
				
			||||||
 | 
					    expect(cnSpy).toHaveBeenCalledWith(`::add-path::${expPath}${osm.EOL}`);
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  it('does not find a version that does not exist', async () => {
 | 
				
			||||||
 | 
					    os.platform = 'linux';
 | 
				
			||||||
 | 
					    os.arch = 'x64';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let versionSpec = '10.13.1-nightly20200415947ddec091';
 | 
				
			||||||
 | 
					    inputs['node-version'] = versionSpec;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    findSpy.mockImplementation(() => '');
 | 
				
			||||||
 | 
					    findAllVersionsSpy.mockImplementation(() => []);
 | 
				
			||||||
 | 
					    await main.run();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    expect(cnSpy).toHaveBeenCalledWith(
 | 
				
			||||||
 | 
					      `::error::Unable to find Node version '${versionSpec}' for platform ${os.platform} and architecture ${os.arch}.${osm.EOL}`
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  it('reports a failed download', async () => {
 | 
				
			||||||
 | 
					    let errMsg = 'unhandled download message';
 | 
				
			||||||
 | 
					    os.platform = 'linux';
 | 
				
			||||||
 | 
					    os.arch = 'x64';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // a version which is in the manifest
 | 
				
			||||||
 | 
					    let versionSpec = '18.0.0-nightly202204180699150267';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    inputs['node-version'] = versionSpec;
 | 
				
			||||||
 | 
					    inputs['always-auth'] = false;
 | 
				
			||||||
 | 
					    inputs['token'] = 'faketoken';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    findSpy.mockImplementation(() => '');
 | 
				
			||||||
 | 
					    findAllVersionsSpy.mockImplementation(() => []);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dlSpy.mockImplementation(() => {
 | 
				
			||||||
 | 
					      throw new Error(errMsg);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    await main.run();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    expect(cnSpy).toHaveBeenCalledWith(`::error::${errMsg}${osm.EOL}`);
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  it('acquires specified architecture of node', 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';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      let expectedUrl = `https://nodejs.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');
 | 
				
			||||||
 | 
					      let 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([
 | 
				
			||||||
 | 
					      [
 | 
				
			||||||
 | 
					        '17.5.0-nightly',
 | 
				
			||||||
 | 
					        '17.5.0-nightly20220209e43808936a',
 | 
				
			||||||
 | 
					        'https://nodejs.org/download/nightly/v17.5.0-nightly20220209e43808936a/node-v17.5.0-nightly20220209e43808936a-linux-x64.tar.gz'
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					      [
 | 
				
			||||||
 | 
					        '17-nightly',
 | 
				
			||||||
 | 
					        '17.5.0-nightly20220209e43808936a',
 | 
				
			||||||
 | 
					        'https://nodejs.org/download/nightly/v17.5.0-nightly20220209e43808936a/node-v17.5.0-nightly20220209e43808936a-linux-x64.tar.gz'
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					      [
 | 
				
			||||||
 | 
					        '18.0.0-nightly',
 | 
				
			||||||
 | 
					        '18.0.0-nightly20220419bde889bd4e',
 | 
				
			||||||
 | 
					        'https://nodejs.org/download/nightly/v18.0.0-nightly20220419bde889bd4e/node-v18.0.0-nightly20220419bde889bd4e-linux-x64.tar.gz'
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					      [
 | 
				
			||||||
 | 
					        '18-nightly',
 | 
				
			||||||
 | 
					        '18.0.0-nightly20220419bde889bd4e',
 | 
				
			||||||
 | 
					        'https://nodejs.org/download/nightly/v18.0.0-nightly20220419bde889bd4e/node-v18.0.0-nightly20220419bde889bd4e-linux-x64.tar.gz'
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					      [
 | 
				
			||||||
 | 
					        '20.0.0-nightly',
 | 
				
			||||||
 | 
					        '20.0.0-nightly2022101987cdf7d412',
 | 
				
			||||||
 | 
					        'https://nodejs.org/download/nightly/v20.0.0-nightly2022101987cdf7d412/node-v20.0.0-nightly2022101987cdf7d412-linux-x64.tar.gz'
 | 
				
			||||||
 | 
					      ]
 | 
				
			||||||
 | 
					    ])(
 | 
				
			||||||
 | 
					      'finds the versions in the index.json and installs it',
 | 
				
			||||||
 | 
					      async (input, expectedVersion, expectedUrl) => {
 | 
				
			||||||
 | 
					        const toolPath = path.normalize(`/cache/node/${expectedVersion}/x64`);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        findSpy.mockImplementation(() => '');
 | 
				
			||||||
 | 
					        findAllVersionsSpy.mockImplementation(() => []);
 | 
				
			||||||
 | 
					        dlSpy.mockImplementation(async () => '/some/temp/path');
 | 
				
			||||||
 | 
					        exSpy.mockImplementation(async () => '/some/other/temp/path');
 | 
				
			||||||
 | 
					        cacheSpy.mockImplementation(async () => toolPath);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        inputs['node-version'] = input;
 | 
				
			||||||
 | 
					        os['arch'] = 'x64';
 | 
				
			||||||
 | 
					        os['platform'] = 'linux';
 | 
				
			||||||
 | 
					        // act
 | 
				
			||||||
 | 
					        await main.run();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // assert
 | 
				
			||||||
 | 
					        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}`
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it.each([
 | 
				
			||||||
 | 
					      ['17.5.0-nightly', '17.5.0-nightly20220209e43808936a'],
 | 
				
			||||||
 | 
					      ['17-nightly', '17.5.0-nightly20220209e43808936a'],
 | 
				
			||||||
 | 
					      ['20.0.0-nightly', '20.0.0-nightly2022101987cdf7d412']
 | 
				
			||||||
 | 
					    ])(
 | 
				
			||||||
 | 
					      'finds the %s version in the hostedToolcache',
 | 
				
			||||||
 | 
					      async (input, expectedVersion) => {
 | 
				
			||||||
 | 
					        const toolPath = path.normalize(`/cache/node/${expectedVersion}/x64`);
 | 
				
			||||||
 | 
					        findSpy.mockReturnValue(toolPath);
 | 
				
			||||||
 | 
					        findAllVersionsSpy.mockReturnValue([
 | 
				
			||||||
 | 
					          '17.5.0-nightly20220209e43808936a',
 | 
				
			||||||
 | 
					          '17.5.0-nightly20220209e43808935a',
 | 
				
			||||||
 | 
					          '20.0.0-nightly2022101987cdf7d412',
 | 
				
			||||||
 | 
					          '20.0.0-nightly2022101987cdf7d411'
 | 
				
			||||||
 | 
					        ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        inputs['node-version'] = input;
 | 
				
			||||||
 | 
					        os['arch'] = 'x64';
 | 
				
			||||||
 | 
					        os['platform'] = 'linux';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // act
 | 
				
			||||||
 | 
					        await main.run();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // assert
 | 
				
			||||||
 | 
					        expect(findAllVersionsSpy).toHaveBeenCalled();
 | 
				
			||||||
 | 
					        expect(logSpy).toHaveBeenCalledWith(`Found in cache @ ${toolPath}`);
 | 
				
			||||||
 | 
					        expect(cnSpy).toHaveBeenCalledWith(
 | 
				
			||||||
 | 
					          `::add-path::${path.join(toolPath, 'bin')}${osm.EOL}`
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it.each([
 | 
				
			||||||
 | 
					      [
 | 
				
			||||||
 | 
					        '17.5.0-nightly',
 | 
				
			||||||
 | 
					        '17.5.0-nightly20220209e43808936a',
 | 
				
			||||||
 | 
					        '17.0.0-nightly202110193f11666dc7',
 | 
				
			||||||
 | 
					        'https://nodejs.org/download/nightly/v17.5.0-nightly20220209e43808936a/node-v17.5.0-nightly20220209e43808936a-linux-x64.tar.gz'
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					      [
 | 
				
			||||||
 | 
					        '17-nightly',
 | 
				
			||||||
 | 
					        '17.5.0-nightly20220209e43808936a',
 | 
				
			||||||
 | 
					        '17.0.0-nightly202110193f11666dc7',
 | 
				
			||||||
 | 
					        'https://nodejs.org/download/nightly/v17.5.0-nightly20220209e43808936a/node-v17.5.0-nightly20220209e43808936a-linux-x64.tar.gz'
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					      [
 | 
				
			||||||
 | 
					        '18.0.0-nightly',
 | 
				
			||||||
 | 
					        '18.0.0-nightly20220419bde889bd4e',
 | 
				
			||||||
 | 
					        '18.0.0-nightly202204180699150267',
 | 
				
			||||||
 | 
					        'https://nodejs.org/download/nightly/v18.0.0-nightly20220419bde889bd4e/node-v18.0.0-nightly20220419bde889bd4e-linux-x64.tar.gz'
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					      [
 | 
				
			||||||
 | 
					        '18-nightly',
 | 
				
			||||||
 | 
					        '18.0.0-nightly20220419bde889bd4e',
 | 
				
			||||||
 | 
					        '18.0.0-nightly202204180699150267',
 | 
				
			||||||
 | 
					        'https://nodejs.org/download/nightly/v18.0.0-nightly20220419bde889bd4e/node-v18.0.0-nightly20220419bde889bd4e-linux-x64.tar.gz'
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					      [
 | 
				
			||||||
 | 
					        '20.0.0-nightly',
 | 
				
			||||||
 | 
					        '20.0.0-nightly2022101987cdf7d412',
 | 
				
			||||||
 | 
					        '20.0.0-nightly2022101987cdf7d411',
 | 
				
			||||||
 | 
					        'https://nodejs.org/download/nightly/v20.0.0-nightly2022101987cdf7d412/node-v20.0.0-nightly2022101987cdf7d412-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';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        findSpy.mockReturnValue(foundToolPath);
 | 
				
			||||||
 | 
					        findAllVersionsSpy.mockReturnValue([
 | 
				
			||||||
 | 
					          '17.0.0-nightly202110193f11666dc7',
 | 
				
			||||||
 | 
					          '18.0.0-nightly202204180699150267',
 | 
				
			||||||
 | 
					          '20.0.0-nightly2022101987cdf7d411'
 | 
				
			||||||
 | 
					        ]);
 | 
				
			||||||
 | 
					        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}`
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
@@ -1,24 +1,26 @@
 | 
				
			|||||||
import * as core from '@actions/core';
 | 
					import * as core from '@actions/core';
 | 
				
			||||||
import * as io from '@actions/io';
 | 
					import * as io from '@actions/io';
 | 
				
			||||||
import * as tc from '@actions/tool-cache';
 | 
					import * as tc from '@actions/tool-cache';
 | 
				
			||||||
import * as exec from '@actions/exec';
 | 
					 | 
				
			||||||
import * as im from '../src/installer';
 | 
					 | 
				
			||||||
import * as cache from '@actions/cache';
 | 
					 | 
				
			||||||
import * as httpm from '@actions/http-client';
 | 
					import * as httpm from '@actions/http-client';
 | 
				
			||||||
 | 
					import * as exec from '@actions/exec';
 | 
				
			||||||
 | 
					import * as cache from '@actions/cache';
 | 
				
			||||||
import fs from 'fs';
 | 
					import fs from 'fs';
 | 
				
			||||||
import cp from 'child_process';
 | 
					import cp from 'child_process';
 | 
				
			||||||
import osm from 'os';
 | 
					import osm from 'os';
 | 
				
			||||||
import path from 'path';
 | 
					import path from 'path';
 | 
				
			||||||
import each from 'jest-each';
 | 
					 | 
				
			||||||
import * as main from '../src/main';
 | 
					import * as main from '../src/main';
 | 
				
			||||||
import * as auth from '../src/authutil';
 | 
					import * as auth from '../src/authutil';
 | 
				
			||||||
 | 
					import OfficialBuilds from '../src/distributions/official_builds/official_builds';
 | 
				
			||||||
 | 
					import {INodeVersion} from '../src/distributions/base-models';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const nodeTestManifest = require('./data/versions-manifest.json');
 | 
					const nodeTestManifest = require('./data/versions-manifest.json');
 | 
				
			||||||
const nodeTestDist = require('./data/node-dist-index.json');
 | 
					const nodeTestDist = require('./data/node-dist-index.json');
 | 
				
			||||||
const nodeTestDistNightly = require('./data/node-nightly-index.json');
 | 
					const nodeTestDistNightly = require('./data/node-nightly-index.json');
 | 
				
			||||||
const nodeTestDistRc = require('./data/node-rc-index.json');
 | 
					const nodeTestDistRc = require('./data/node-rc-index.json');
 | 
				
			||||||
 | 
					const nodeV8CanaryTestDist = require('./data/v8-canary-dist-index.json');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
describe('setup-node', () => {
 | 
					describe('setup-node', () => {
 | 
				
			||||||
 | 
					  let build: OfficialBuilds;
 | 
				
			||||||
  let inputs = {} as any;
 | 
					  let inputs = {} as any;
 | 
				
			||||||
  let os = {} as any;
 | 
					  let os = {} as any;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -29,7 +31,6 @@ describe('setup-node', () => {
 | 
				
			|||||||
  let logSpy: jest.SpyInstance;
 | 
					  let logSpy: jest.SpyInstance;
 | 
				
			||||||
  let warningSpy: jest.SpyInstance;
 | 
					  let warningSpy: jest.SpyInstance;
 | 
				
			||||||
  let getManifestSpy: jest.SpyInstance;
 | 
					  let getManifestSpy: jest.SpyInstance;
 | 
				
			||||||
  let getDistSpy: jest.SpyInstance;
 | 
					 | 
				
			||||||
  let platSpy: jest.SpyInstance;
 | 
					  let platSpy: jest.SpyInstance;
 | 
				
			||||||
  let archSpy: jest.SpyInstance;
 | 
					  let archSpy: jest.SpyInstance;
 | 
				
			||||||
  let dlSpy: jest.SpyInstance;
 | 
					  let dlSpy: jest.SpyInstance;
 | 
				
			||||||
@@ -42,7 +43,6 @@ describe('setup-node', () => {
 | 
				
			|||||||
  let mkdirpSpy: jest.SpyInstance;
 | 
					  let mkdirpSpy: jest.SpyInstance;
 | 
				
			||||||
  let execSpy: jest.SpyInstance;
 | 
					  let execSpy: jest.SpyInstance;
 | 
				
			||||||
  let authSpy: jest.SpyInstance;
 | 
					  let authSpy: jest.SpyInstance;
 | 
				
			||||||
  let parseNodeVersionSpy: jest.SpyInstance;
 | 
					 | 
				
			||||||
  let isCacheActionAvailable: jest.SpyInstance;
 | 
					  let isCacheActionAvailable: jest.SpyInstance;
 | 
				
			||||||
  let getExecOutputSpy: jest.SpyInstance;
 | 
					  let getExecOutputSpy: jest.SpyInstance;
 | 
				
			||||||
  let getJsonSpy: jest.SpyInstance;
 | 
					  let getJsonSpy: jest.SpyInstance;
 | 
				
			||||||
@@ -71,8 +71,6 @@ describe('setup-node', () => {
 | 
				
			|||||||
    exSpy = jest.spyOn(tc, 'extractTar');
 | 
					    exSpy = jest.spyOn(tc, 'extractTar');
 | 
				
			||||||
    cacheSpy = jest.spyOn(tc, 'cacheDir');
 | 
					    cacheSpy = jest.spyOn(tc, 'cacheDir');
 | 
				
			||||||
    getManifestSpy = jest.spyOn(tc, 'getManifestFromRepo');
 | 
					    getManifestSpy = jest.spyOn(tc, 'getManifestFromRepo');
 | 
				
			||||||
    getDistSpy = jest.spyOn(im, 'getVersionsFromDist');
 | 
					 | 
				
			||||||
    parseNodeVersionSpy = jest.spyOn(im, 'parseNodeVersionFile');
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // http-client
 | 
					    // http-client
 | 
				
			||||||
    getJsonSpy = jest.spyOn(httpm.HttpClient.prototype, 'getJson');
 | 
					    getJsonSpy = jest.spyOn(httpm.HttpClient.prototype, 'getJson');
 | 
				
			||||||
@@ -94,25 +92,14 @@ describe('setup-node', () => {
 | 
				
			|||||||
      () => <tc.IToolRelease[]>nodeTestManifest
 | 
					      () => <tc.IToolRelease[]>nodeTestManifest
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    getDistSpy.mockImplementation(version => {
 | 
					 | 
				
			||||||
      const initialUrl = im.getNodejsDistUrl(version);
 | 
					 | 
				
			||||||
      if (initialUrl.endsWith('/rc')) {
 | 
					 | 
				
			||||||
        return <im.INodeVersion>nodeTestDistRc;
 | 
					 | 
				
			||||||
      } else if (initialUrl.endsWith('/nightly')) {
 | 
					 | 
				
			||||||
        return <im.INodeVersion>nodeTestDistNightly;
 | 
					 | 
				
			||||||
      } else {
 | 
					 | 
				
			||||||
        return <im.INodeVersion>nodeTestDist;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    getJsonSpy.mockImplementation(url => {
 | 
					    getJsonSpy.mockImplementation(url => {
 | 
				
			||||||
      let res: any;
 | 
					      let res: any;
 | 
				
			||||||
      if (url.includes('/rc')) {
 | 
					      if (url.includes('/rc')) {
 | 
				
			||||||
        res = <im.INodeVersion>nodeTestDistRc;
 | 
					        res = <INodeVersion>nodeTestDistRc;
 | 
				
			||||||
      } else if (url.includes('/nightly')) {
 | 
					      } else if (url.includes('/nightly')) {
 | 
				
			||||||
        res = <im.INodeVersion>nodeTestDistNightly;
 | 
					        res = <INodeVersion>nodeTestDistNightly;
 | 
				
			||||||
      } else {
 | 
					      } else {
 | 
				
			||||||
        res = <im.INodeVersion>nodeTestDist;
 | 
					        res = <INodeVersion>nodeTestDist;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      return {result: res};
 | 
					      return {result: res};
 | 
				
			||||||
@@ -125,11 +112,11 @@ describe('setup-node', () => {
 | 
				
			|||||||
    warningSpy = jest.spyOn(core, 'warning');
 | 
					    warningSpy = jest.spyOn(core, 'warning');
 | 
				
			||||||
    cnSpy.mockImplementation(line => {
 | 
					    cnSpy.mockImplementation(line => {
 | 
				
			||||||
      // uncomment to debug
 | 
					      // uncomment to debug
 | 
				
			||||||
      // process.stderr.write('write:' + line + '\n');
 | 
					      process.stderr.write('write:' + line + '\n');
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    logSpy.mockImplementation(line => {
 | 
					    logSpy.mockImplementation(line => {
 | 
				
			||||||
      // uncomment to debug
 | 
					      //   uncomment to debug
 | 
				
			||||||
      // process.stderr.write('log:' + line + '\n');
 | 
					      process.stderr.write('log:' + line + '\n');
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    dbgSpy.mockImplementation(msg => {
 | 
					    dbgSpy.mockImplementation(msg => {
 | 
				
			||||||
      // uncomment to see debug output
 | 
					      // uncomment to see debug output
 | 
				
			||||||
@@ -137,7 +124,7 @@ describe('setup-node', () => {
 | 
				
			|||||||
    });
 | 
					    });
 | 
				
			||||||
    warningSpy.mockImplementation(msg => {
 | 
					    warningSpy.mockImplementation(msg => {
 | 
				
			||||||
      // uncomment to debug
 | 
					      // uncomment to debug
 | 
				
			||||||
      // process.stderr.write('log:' + line + '\n');
 | 
					      // process.stderr.write('log:' + msg + '\n');
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // @actions/exec
 | 
					    // @actions/exec
 | 
				
			||||||
@@ -159,23 +146,6 @@ describe('setup-node', () => {
 | 
				
			|||||||
  //--------------------------------------------------
 | 
					  //--------------------------------------------------
 | 
				
			||||||
  // Manifest find tests
 | 
					  // Manifest find tests
 | 
				
			||||||
  //--------------------------------------------------
 | 
					  //--------------------------------------------------
 | 
				
			||||||
  it('can mock manifest versions', async () => {
 | 
					 | 
				
			||||||
    let versions: tc.IToolRelease[] | null = await tc.getManifestFromRepo(
 | 
					 | 
				
			||||||
      'actions',
 | 
					 | 
				
			||||||
      'node-versions',
 | 
					 | 
				
			||||||
      'mocktoken'
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
    expect(versions).toBeDefined();
 | 
					 | 
				
			||||||
    expect(versions?.length).toBe(7);
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  it('can mock dist versions', async () => {
 | 
					 | 
				
			||||||
    const versionSpec = '1.2.3';
 | 
					 | 
				
			||||||
    let versions: im.INodeVersion[] = await im.getVersionsFromDist(versionSpec);
 | 
					 | 
				
			||||||
    expect(versions).toBeDefined();
 | 
					 | 
				
			||||||
    expect(versions?.length).toBe(23);
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  it.each([
 | 
					  it.each([
 | 
				
			||||||
    ['12.16.2', 'darwin', '12.16.2', 'Erbium'],
 | 
					    ['12.16.2', 'darwin', '12.16.2', 'Erbium'],
 | 
				
			||||||
    ['12', 'linux', '12.16.2', 'Erbium'],
 | 
					    ['12', 'linux', '12.16.2', 'Erbium'],
 | 
				
			||||||
@@ -315,35 +285,32 @@ describe('setup-node', () => {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    // a version which is not in the manifest but is in node dist
 | 
					    // a version which is not in the manifest but is in node dist
 | 
				
			||||||
    let versionSpec = '11.15.0';
 | 
					    let versionSpec = '11.15.0';
 | 
				
			||||||
    let resolvedVersion = versionSpec;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    inputs['node-version'] = versionSpec;
 | 
					    inputs['node-version'] = versionSpec;
 | 
				
			||||||
    inputs['always-auth'] = false;
 | 
					    inputs['always-auth'] = false;
 | 
				
			||||||
    inputs['token'] = 'faketoken';
 | 
					    inputs['token'] = 'faketoken';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let expectedUrl =
 | 
					 | 
				
			||||||
      'https://github.com/actions/node-versions/releases/download/12.16.2-20200507.95/node-12.16.2-linux-x64.tar.gz';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // ... but not in the local cache
 | 
					    // ... but not in the local cache
 | 
				
			||||||
    findSpy.mockImplementation(() => '');
 | 
					    findSpy.mockImplementation(() => '');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    dlSpy.mockImplementation(async () => '/some/temp/path');
 | 
					    dlSpy.mockImplementation(async () => '/some/temp/path');
 | 
				
			||||||
    let toolPath = path.normalize('/cache/node/11.11.0/x64');
 | 
					    const toolPath = path.normalize('/cache/node/11.15.0/x64');
 | 
				
			||||||
    exSpy.mockImplementation(async () => '/some/other/temp/path');
 | 
					    exSpy.mockImplementation(async () => '/some/other/temp/path');
 | 
				
			||||||
    cacheSpy.mockImplementation(async () => toolPath);
 | 
					    cacheSpy.mockImplementation(async () => toolPath);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    await main.run();
 | 
					    await main.run();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let expPath = path.join(toolPath, 'bin');
 | 
					    const expPath = path.join(toolPath, 'bin');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    expect(dlSpy).toHaveBeenCalled();
 | 
					    expect(getManifestSpy).toHaveBeenCalled();
 | 
				
			||||||
    expect(exSpy).toHaveBeenCalled();
 | 
					 | 
				
			||||||
    expect(logSpy).toHaveBeenCalledWith(
 | 
					 | 
				
			||||||
      'Not found in manifest.  Falling back to download directly from Node'
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
    expect(logSpy).toHaveBeenCalledWith(
 | 
					    expect(logSpy).toHaveBeenCalledWith(
 | 
				
			||||||
      `Attempting to download ${versionSpec}...`
 | 
					      `Attempting to download ${versionSpec}...`
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
					    expect(logSpy).toHaveBeenCalledWith(
 | 
				
			||||||
 | 
					      'Not found in manifest. Falling back to download directly from Node'
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    expect(dlSpy).toHaveBeenCalled();
 | 
				
			||||||
 | 
					    expect(exSpy).toHaveBeenCalled();
 | 
				
			||||||
    expect(cnSpy).toHaveBeenCalledWith(`::add-path::${expPath}${osm.EOL}`);
 | 
					    expect(cnSpy).toHaveBeenCalledWith(`::add-path::${expPath}${osm.EOL}`);
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -358,7 +325,7 @@ describe('setup-node', () => {
 | 
				
			|||||||
    await main.run();
 | 
					    await main.run();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    expect(logSpy).toHaveBeenCalledWith(
 | 
					    expect(logSpy).toHaveBeenCalledWith(
 | 
				
			||||||
      'Not found in manifest.  Falling back to download directly from Node'
 | 
					      'Not found in manifest. Falling back to download directly from Node'
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
    expect(logSpy).toHaveBeenCalledWith(
 | 
					    expect(logSpy).toHaveBeenCalledWith(
 | 
				
			||||||
      `Attempting to download ${versionSpec}...`
 | 
					      `Attempting to download ${versionSpec}...`
 | 
				
			||||||
@@ -596,165 +563,6 @@ describe('setup-node', () => {
 | 
				
			|||||||
    });
 | 
					    });
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  describe('node-version-file flag', () => {
 | 
					 | 
				
			||||||
    it('not used if node-version is provided', async () => {
 | 
					 | 
				
			||||||
      // Arrange
 | 
					 | 
				
			||||||
      inputs['node-version'] = '12';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      // Act
 | 
					 | 
				
			||||||
      await main.run();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      // Assert
 | 
					 | 
				
			||||||
      expect(parseNodeVersionSpy).toHaveBeenCalledTimes(0);
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    it('not used if node-version-file not provided', async () => {
 | 
					 | 
				
			||||||
      // Act
 | 
					 | 
				
			||||||
      await main.run();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      // Assert
 | 
					 | 
				
			||||||
      expect(parseNodeVersionSpy).toHaveBeenCalledTimes(0);
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    it('reads node-version-file if provided', async () => {
 | 
					 | 
				
			||||||
      // Arrange
 | 
					 | 
				
			||||||
      const versionSpec = 'v14';
 | 
					 | 
				
			||||||
      const versionFile = '.nvmrc';
 | 
					 | 
				
			||||||
      const expectedVersionSpec = '14';
 | 
					 | 
				
			||||||
      process.env['GITHUB_WORKSPACE'] = path.join(__dirname, 'data');
 | 
					 | 
				
			||||||
      inputs['node-version-file'] = versionFile;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      parseNodeVersionSpy.mockImplementation(() => expectedVersionSpec);
 | 
					 | 
				
			||||||
      existsSpy.mockImplementationOnce(
 | 
					 | 
				
			||||||
        input => input === path.join(__dirname, 'data', versionFile)
 | 
					 | 
				
			||||||
      );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      // Act
 | 
					 | 
				
			||||||
      await main.run();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      // Assert
 | 
					 | 
				
			||||||
      expect(existsSpy).toHaveBeenCalledTimes(1);
 | 
					 | 
				
			||||||
      expect(existsSpy).toHaveReturnedWith(true);
 | 
					 | 
				
			||||||
      expect(parseNodeVersionSpy).toHaveBeenCalledWith(versionSpec);
 | 
					 | 
				
			||||||
      expect(logSpy).toHaveBeenCalledWith(
 | 
					 | 
				
			||||||
        `Resolved ${versionFile} as ${expectedVersionSpec}`
 | 
					 | 
				
			||||||
      );
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    it('reads package.json as node-version-file if provided', async () => {
 | 
					 | 
				
			||||||
      // Arrange
 | 
					 | 
				
			||||||
      const versionSpec = fs.readFileSync(
 | 
					 | 
				
			||||||
        path.join(__dirname, 'data/package.json'),
 | 
					 | 
				
			||||||
        'utf-8'
 | 
					 | 
				
			||||||
      );
 | 
					 | 
				
			||||||
      const versionFile = 'package.json';
 | 
					 | 
				
			||||||
      const expectedVersionSpec = '14';
 | 
					 | 
				
			||||||
      process.env['GITHUB_WORKSPACE'] = path.join(__dirname, 'data');
 | 
					 | 
				
			||||||
      inputs['node-version-file'] = versionFile;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      parseNodeVersionSpy.mockImplementation(() => expectedVersionSpec);
 | 
					 | 
				
			||||||
      existsSpy.mockImplementationOnce(
 | 
					 | 
				
			||||||
        input => input === path.join(__dirname, 'data', versionFile)
 | 
					 | 
				
			||||||
      );
 | 
					 | 
				
			||||||
      // Act
 | 
					 | 
				
			||||||
      await main.run();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      // Assert
 | 
					 | 
				
			||||||
      expect(existsSpy).toHaveBeenCalledTimes(1);
 | 
					 | 
				
			||||||
      expect(existsSpy).toHaveReturnedWith(true);
 | 
					 | 
				
			||||||
      expect(parseNodeVersionSpy).toHaveBeenCalledWith(versionSpec);
 | 
					 | 
				
			||||||
      expect(logSpy).toHaveBeenCalledWith(
 | 
					 | 
				
			||||||
        `Resolved ${versionFile} as ${expectedVersionSpec}`
 | 
					 | 
				
			||||||
      );
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    it('both node-version-file and node-version are provided', async () => {
 | 
					 | 
				
			||||||
      inputs['node-version'] = '12';
 | 
					 | 
				
			||||||
      const versionSpec = 'v14';
 | 
					 | 
				
			||||||
      const versionFile = '.nvmrc';
 | 
					 | 
				
			||||||
      const expectedVersionSpec = '14';
 | 
					 | 
				
			||||||
      process.env['GITHUB_WORKSPACE'] = path.join(__dirname, '..');
 | 
					 | 
				
			||||||
      inputs['node-version-file'] = versionFile;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      parseNodeVersionSpy.mockImplementation(() => expectedVersionSpec);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      // Act
 | 
					 | 
				
			||||||
      await main.run();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      // Assert
 | 
					 | 
				
			||||||
      expect(existsSpy).toHaveBeenCalledTimes(0);
 | 
					 | 
				
			||||||
      expect(parseNodeVersionSpy).not.toHaveBeenCalled();
 | 
					 | 
				
			||||||
      expect(warningSpy).toHaveBeenCalledWith(
 | 
					 | 
				
			||||||
        'Both node-version and node-version-file inputs are specified, only node-version will be used'
 | 
					 | 
				
			||||||
      );
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    it('should throw an error if node-version-file is not found', async () => {
 | 
					 | 
				
			||||||
      const versionFile = '.nvmrc';
 | 
					 | 
				
			||||||
      const versionFilePath = path.join(__dirname, '..', versionFile);
 | 
					 | 
				
			||||||
      inputs['node-version-file'] = versionFile;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      inSpy.mockImplementation(name => inputs[name]);
 | 
					 | 
				
			||||||
      existsSpy.mockImplementationOnce(
 | 
					 | 
				
			||||||
        input => input === path.join(__dirname, 'data', versionFile)
 | 
					 | 
				
			||||||
      );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      // Act
 | 
					 | 
				
			||||||
      await main.run();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      // Assert
 | 
					 | 
				
			||||||
      expect(existsSpy).toHaveBeenCalled();
 | 
					 | 
				
			||||||
      expect(existsSpy).toHaveReturnedWith(false);
 | 
					 | 
				
			||||||
      expect(parseNodeVersionSpy).not.toHaveBeenCalled();
 | 
					 | 
				
			||||||
      expect(cnSpy).toHaveBeenCalledWith(
 | 
					 | 
				
			||||||
        `::error::The specified node version file at: ${versionFilePath} does not exist${osm.EOL}`
 | 
					 | 
				
			||||||
      );
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  describe('cache on GHES', () => {
 | 
					 | 
				
			||||||
    it('Should throw an error, because cache is not supported', async () => {
 | 
					 | 
				
			||||||
      inputs['node-version'] = '12';
 | 
					 | 
				
			||||||
      inputs['cache'] = 'npm';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      inSpy.mockImplementation(name => inputs[name]);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      let toolPath = path.normalize('/cache/node/12.16.1/x64');
 | 
					 | 
				
			||||||
      findSpy.mockImplementation(() => toolPath);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      // expect(logSpy).toHaveBeenCalledWith(`Found in cache @ ${toolPath}`);
 | 
					 | 
				
			||||||
      process.env['GITHUB_SERVER_URL'] = 'https://www.test.com';
 | 
					 | 
				
			||||||
      isCacheActionAvailable.mockImplementation(() => false);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      await main.run();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      expect(warningSpy).toHaveBeenCalledWith(
 | 
					 | 
				
			||||||
        //  `::error::Cache action is only supported on GHES version >= 3.5. If you are on version >=3.5 Please check with GHES admin if Actions cache service is enabled or not.${osm.EOL}`
 | 
					 | 
				
			||||||
        'Cache action is only supported on GHES version >= 3.5. If you are on version >=3.5 Please check with GHES admin if Actions cache service is enabled or not.'
 | 
					 | 
				
			||||||
      );
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    it('Should throw an internal error', async () => {
 | 
					 | 
				
			||||||
      inputs['node-version'] = '12';
 | 
					 | 
				
			||||||
      inputs['cache'] = 'npm';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      inSpy.mockImplementation(name => inputs[name]);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      let toolPath = path.normalize('/cache/node/12.16.1/x64');
 | 
					 | 
				
			||||||
      findSpy.mockImplementation(() => toolPath);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      // expect(logSpy).toHaveBeenCalledWith(`Found in cache @ ${toolPath}`);
 | 
					 | 
				
			||||||
      process.env['GITHUB_SERVER_URL'] = '';
 | 
					 | 
				
			||||||
      isCacheActionAvailable.mockImplementation(() => false);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      await main.run();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      expect(warningSpy).toHaveBeenCalledWith(
 | 
					 | 
				
			||||||
        'The runner was not able to contact the cache service. Caching will be skipped'
 | 
					 | 
				
			||||||
      );
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  describe('LTS version', () => {
 | 
					  describe('LTS version', () => {
 | 
				
			||||||
    beforeEach(() => {
 | 
					    beforeEach(() => {
 | 
				
			||||||
      os.platform = 'linux';
 | 
					      os.platform = 'linux';
 | 
				
			||||||
@@ -930,277 +738,6 @@ describe('setup-node', () => {
 | 
				
			|||||||
    });
 | 
					    });
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  describe('rc versions', () => {
 | 
					 | 
				
			||||||
    it.each([
 | 
					 | 
				
			||||||
      [
 | 
					 | 
				
			||||||
        '13.10.1-rc.0',
 | 
					 | 
				
			||||||
        '13.10.1-rc.0',
 | 
					 | 
				
			||||||
        'https://nodejs.org/download/rc/v13.10.1-rc.0/node-v13.10.1-rc.0-linux-x64.tar.gz'
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      [
 | 
					 | 
				
			||||||
        '14.15.5-rc.1',
 | 
					 | 
				
			||||||
        '14.15.5-rc.1',
 | 
					 | 
				
			||||||
        'https://nodejs.org/download/rc/v14.15.5-rc.1/node-v14.15.5-rc.1-linux-x64.tar.gz'
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      [
 | 
					 | 
				
			||||||
        '16.17.0-rc.1',
 | 
					 | 
				
			||||||
        '16.17.0-rc.1',
 | 
					 | 
				
			||||||
        'https://nodejs.org/download/rc/v16.17.0-rc.1/node-v16.17.0-rc.1-linux-x64.tar.gz'
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      [
 | 
					 | 
				
			||||||
        '17.0.0-rc.1',
 | 
					 | 
				
			||||||
        '17.0.0-rc.1',
 | 
					 | 
				
			||||||
        'https://nodejs.org/download/rc/v17.0.0-rc.1/node-v17.0.0-rc.1-linux-x64.tar.gz'
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      [
 | 
					 | 
				
			||||||
        '19.0.0-rc.2',
 | 
					 | 
				
			||||||
        '19.0.0-rc.2',
 | 
					 | 
				
			||||||
        'https://nodejs.org/download/rc/v19.0.0-rc.2/node-v19.0.0-rc.2-linux-x64.tar.gz'
 | 
					 | 
				
			||||||
      ]
 | 
					 | 
				
			||||||
    ])(
 | 
					 | 
				
			||||||
      'finds the versions in the index.json and installs it',
 | 
					 | 
				
			||||||
      async (input, expectedVersion, expectedUrl) => {
 | 
					 | 
				
			||||||
        const toolPath = path.normalize(`/cache/node/${expectedVersion}/x64`);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        findSpy.mockImplementation(() => '');
 | 
					 | 
				
			||||||
        findAllVersionsSpy.mockImplementation(() => []);
 | 
					 | 
				
			||||||
        dlSpy.mockImplementation(async () => '/some/temp/path');
 | 
					 | 
				
			||||||
        exSpy.mockImplementation(async () => '/some/other/temp/path');
 | 
					 | 
				
			||||||
        cacheSpy.mockImplementation(async () => toolPath);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        inputs['node-version'] = input;
 | 
					 | 
				
			||||||
        os['arch'] = 'x64';
 | 
					 | 
				
			||||||
        os['platform'] = 'linux';
 | 
					 | 
				
			||||||
        // act
 | 
					 | 
				
			||||||
        await main.run();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // assert
 | 
					 | 
				
			||||||
        expect(logSpy).toHaveBeenCalledWith(
 | 
					 | 
				
			||||||
          `Attempting to download ${input}...`
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        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}`
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    it.each([
 | 
					 | 
				
			||||||
      ['13.10.1-rc.0', '13.10.1-rc.0'],
 | 
					 | 
				
			||||||
      ['14.15.5-rc.1', '14.15.5-rc.1'],
 | 
					 | 
				
			||||||
      ['16.17.0-rc.1', '16.17.0-rc.1'],
 | 
					 | 
				
			||||||
      ['17.0.0-rc.1', '17.0.0-rc.1']
 | 
					 | 
				
			||||||
    ])(
 | 
					 | 
				
			||||||
      'finds the %s version in the hostedToolcache',
 | 
					 | 
				
			||||||
      async (input, expectedVersion) => {
 | 
					 | 
				
			||||||
        const toolPath = path.normalize(`/cache/node/${expectedVersion}/x64`);
 | 
					 | 
				
			||||||
        findSpy.mockReturnValue(toolPath);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        inputs['node-version'] = input;
 | 
					 | 
				
			||||||
        os['arch'] = 'x64';
 | 
					 | 
				
			||||||
        os['platform'] = 'linux';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // act
 | 
					 | 
				
			||||||
        await main.run();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // assert
 | 
					 | 
				
			||||||
        expect(logSpy).toHaveBeenCalledWith(`Found in cache @ ${toolPath}`);
 | 
					 | 
				
			||||||
        expect(cnSpy).toHaveBeenCalledWith(
 | 
					 | 
				
			||||||
          `::add-path::${path.join(toolPath, 'bin')}${osm.EOL}`
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    it('throws an error if version is not found', async () => {
 | 
					 | 
				
			||||||
      const versionSpec = '19.0.0-rc.3';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      findSpy.mockImplementation(() => '');
 | 
					 | 
				
			||||||
      findAllVersionsSpy.mockImplementation(() => []);
 | 
					 | 
				
			||||||
      dlSpy.mockImplementation(async () => '/some/temp/path');
 | 
					 | 
				
			||||||
      exSpy.mockImplementation(async () => '/some/other/temp/path');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      inputs['node-version'] = versionSpec;
 | 
					 | 
				
			||||||
      os['arch'] = 'x64';
 | 
					 | 
				
			||||||
      os['platform'] = 'linux';
 | 
					 | 
				
			||||||
      // act
 | 
					 | 
				
			||||||
      await main.run();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      // assert
 | 
					 | 
				
			||||||
      expect(logSpy).toHaveBeenCalledWith(
 | 
					 | 
				
			||||||
        `Attempting to download ${versionSpec}...`
 | 
					 | 
				
			||||||
      );
 | 
					 | 
				
			||||||
      expect(cnSpy).toHaveBeenCalledWith(
 | 
					 | 
				
			||||||
        `::error::Unable to find Node version '${versionSpec}' for platform ${os.platform} and architecture ${os.arch}.${osm.EOL}`
 | 
					 | 
				
			||||||
      );
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  describe('nightly versions', () => {
 | 
					 | 
				
			||||||
    it.each([
 | 
					 | 
				
			||||||
      [
 | 
					 | 
				
			||||||
        '17.5.0-nightly',
 | 
					 | 
				
			||||||
        '17.5.0-nightly20220209e43808936a',
 | 
					 | 
				
			||||||
        'https://nodejs.org/download/nightly/v17.5.0-nightly20220209e43808936a/node-v17.5.0-nightly20220209e43808936a-linux-x64.tar.gz'
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      [
 | 
					 | 
				
			||||||
        '17-nightly',
 | 
					 | 
				
			||||||
        '17.5.0-nightly20220209e43808936a',
 | 
					 | 
				
			||||||
        'https://nodejs.org/download/nightly/v17.5.0-nightly20220209e43808936a/node-v17.5.0-nightly20220209e43808936a-linux-x64.tar.gz'
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      [
 | 
					 | 
				
			||||||
        '18.0.0-nightly',
 | 
					 | 
				
			||||||
        '18.0.0-nightly20220419bde889bd4e',
 | 
					 | 
				
			||||||
        'https://nodejs.org/download/nightly/v18.0.0-nightly20220419bde889bd4e/node-v18.0.0-nightly20220419bde889bd4e-linux-x64.tar.gz'
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      [
 | 
					 | 
				
			||||||
        '18-nightly',
 | 
					 | 
				
			||||||
        '18.0.0-nightly20220419bde889bd4e',
 | 
					 | 
				
			||||||
        'https://nodejs.org/download/nightly/v18.0.0-nightly20220419bde889bd4e/node-v18.0.0-nightly20220419bde889bd4e-linux-x64.tar.gz'
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      [
 | 
					 | 
				
			||||||
        '20.0.0-nightly',
 | 
					 | 
				
			||||||
        '20.0.0-nightly2022101987cdf7d412',
 | 
					 | 
				
			||||||
        'https://nodejs.org/download/nightly/v20.0.0-nightly2022101987cdf7d412/node-v20.0.0-nightly2022101987cdf7d412-linux-x64.tar.gz'
 | 
					 | 
				
			||||||
      ]
 | 
					 | 
				
			||||||
    ])(
 | 
					 | 
				
			||||||
      'finds the versions in the index.json and installs it',
 | 
					 | 
				
			||||||
      async (input, expectedVersion, expectedUrl) => {
 | 
					 | 
				
			||||||
        const toolPath = path.normalize(`/cache/node/${expectedVersion}/x64`);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        findSpy.mockImplementation(() => '');
 | 
					 | 
				
			||||||
        findAllVersionsSpy.mockImplementation(() => []);
 | 
					 | 
				
			||||||
        dlSpy.mockImplementation(async () => '/some/temp/path');
 | 
					 | 
				
			||||||
        exSpy.mockImplementation(async () => '/some/other/temp/path');
 | 
					 | 
				
			||||||
        cacheSpy.mockImplementation(async () => toolPath);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        inputs['node-version'] = input;
 | 
					 | 
				
			||||||
        os['arch'] = 'x64';
 | 
					 | 
				
			||||||
        os['platform'] = 'linux';
 | 
					 | 
				
			||||||
        // act
 | 
					 | 
				
			||||||
        await main.run();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // assert
 | 
					 | 
				
			||||||
        expect(logSpy).toHaveBeenCalledWith(
 | 
					 | 
				
			||||||
          `Attempting to download ${input}...`
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        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}`
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    it.each([
 | 
					 | 
				
			||||||
      ['17.5.0-nightly', '17.5.0-nightly20220209e43808936a'],
 | 
					 | 
				
			||||||
      ['17-nightly', '17.5.0-nightly20220209e43808936a'],
 | 
					 | 
				
			||||||
      ['20.0.0-nightly', '20.0.0-nightly2022101987cdf7d412']
 | 
					 | 
				
			||||||
    ])(
 | 
					 | 
				
			||||||
      'finds the %s version in the hostedToolcache',
 | 
					 | 
				
			||||||
      async (input, expectedVersion) => {
 | 
					 | 
				
			||||||
        const toolPath = path.normalize(`/cache/node/${expectedVersion}/x64`);
 | 
					 | 
				
			||||||
        findSpy.mockReturnValue(toolPath);
 | 
					 | 
				
			||||||
        findAllVersionsSpy.mockReturnValue([
 | 
					 | 
				
			||||||
          '17.5.0-nightly20220209e43808936a',
 | 
					 | 
				
			||||||
          '17.5.0-nightly20220209e43808935a',
 | 
					 | 
				
			||||||
          '20.0.0-nightly2022101987cdf7d412',
 | 
					 | 
				
			||||||
          '20.0.0-nightly2022101987cdf7d411'
 | 
					 | 
				
			||||||
        ]);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        inputs['node-version'] = input;
 | 
					 | 
				
			||||||
        os['arch'] = 'x64';
 | 
					 | 
				
			||||||
        os['platform'] = 'linux';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // act
 | 
					 | 
				
			||||||
        await main.run();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // assert
 | 
					 | 
				
			||||||
        expect(findAllVersionsSpy).toHaveBeenCalled();
 | 
					 | 
				
			||||||
        expect(logSpy).toHaveBeenCalledWith(`Found in cache @ ${toolPath}`);
 | 
					 | 
				
			||||||
        expect(cnSpy).toHaveBeenCalledWith(
 | 
					 | 
				
			||||||
          `::add-path::${path.join(toolPath, 'bin')}${osm.EOL}`
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    it.each([
 | 
					 | 
				
			||||||
      [
 | 
					 | 
				
			||||||
        '17.5.0-nightly',
 | 
					 | 
				
			||||||
        '17.5.0-nightly20220209e43808936a',
 | 
					 | 
				
			||||||
        '17.0.0-nightly202110193f11666dc7',
 | 
					 | 
				
			||||||
        'https://nodejs.org/download/nightly/v17.5.0-nightly20220209e43808936a/node-v17.5.0-nightly20220209e43808936a-linux-x64.tar.gz'
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      [
 | 
					 | 
				
			||||||
        '17-nightly',
 | 
					 | 
				
			||||||
        '17.5.0-nightly20220209e43808936a',
 | 
					 | 
				
			||||||
        '17.0.0-nightly202110193f11666dc7',
 | 
					 | 
				
			||||||
        'https://nodejs.org/download/nightly/v17.5.0-nightly20220209e43808936a/node-v17.5.0-nightly20220209e43808936a-linux-x64.tar.gz'
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      [
 | 
					 | 
				
			||||||
        '18.0.0-nightly',
 | 
					 | 
				
			||||||
        '18.0.0-nightly20220419bde889bd4e',
 | 
					 | 
				
			||||||
        '18.0.0-nightly202204180699150267',
 | 
					 | 
				
			||||||
        'https://nodejs.org/download/nightly/v18.0.0-nightly20220419bde889bd4e/node-v18.0.0-nightly20220419bde889bd4e-linux-x64.tar.gz'
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      [
 | 
					 | 
				
			||||||
        '18-nightly',
 | 
					 | 
				
			||||||
        '18.0.0-nightly20220419bde889bd4e',
 | 
					 | 
				
			||||||
        '18.0.0-nightly202204180699150267',
 | 
					 | 
				
			||||||
        'https://nodejs.org/download/nightly/v18.0.0-nightly20220419bde889bd4e/node-v18.0.0-nightly20220419bde889bd4e-linux-x64.tar.gz'
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      [
 | 
					 | 
				
			||||||
        '20.0.0-nightly',
 | 
					 | 
				
			||||||
        '20.0.0-nightly2022101987cdf7d412',
 | 
					 | 
				
			||||||
        '20.0.0-nightly2022101987cdf7d411',
 | 
					 | 
				
			||||||
        'https://nodejs.org/download/nightly/v20.0.0-nightly2022101987cdf7d412/node-v20.0.0-nightly2022101987cdf7d412-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';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        findSpy.mockReturnValue(foundToolPath);
 | 
					 | 
				
			||||||
        findAllVersionsSpy.mockReturnValue([
 | 
					 | 
				
			||||||
          '17.0.0-nightly202110193f11666dc7',
 | 
					 | 
				
			||||||
          '18.0.0-nightly202204180699150267',
 | 
					 | 
				
			||||||
          '20.0.0-nightly2022101987cdf7d411'
 | 
					 | 
				
			||||||
        ]);
 | 
					 | 
				
			||||||
        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('latest alias syntax', () => {
 | 
					  describe('latest alias syntax', () => {
 | 
				
			||||||
    it.each(['latest', 'current', 'node'])(
 | 
					    it.each(['latest', 'current', 'node'])(
 | 
				
			||||||
      'download the %s version if alias is provided',
 | 
					      'download the %s version if alias is provided',
 | 
				
			||||||
@@ -1241,36 +778,16 @@ describe('setup-node', () => {
 | 
				
			|||||||
        const toolPath = path.normalize(
 | 
					        const toolPath = path.normalize(
 | 
				
			||||||
          `/cache/node/${expectedVersion.version}/x64`
 | 
					          `/cache/node/${expectedVersion.version}/x64`
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
        findSpy.mockReturnValue(toolPath);
 | 
					        findSpy.mockImplementation(() => toolPath);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Act
 | 
					        // Act
 | 
				
			||||||
        await main.run();
 | 
					        await main.run();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // assert
 | 
					        // assert
 | 
				
			||||||
        expect(logSpy).toHaveBeenCalledWith(`Found in cache @ ${toolPath}`);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        expect(logSpy).toHaveBeenCalledWith('getting latest node version...');
 | 
					        expect(logSpy).toHaveBeenCalledWith('getting latest node version...');
 | 
				
			||||||
 | 
					        expect(logSpy).toHaveBeenCalledWith(`Found in cache @ ${toolPath}`);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					 | 
				
			||||||
describe('helper methods', () => {
 | 
					 | 
				
			||||||
  describe('parseNodeVersionFile', () => {
 | 
					 | 
				
			||||||
    each`
 | 
					 | 
				
			||||||
      contents                                     | expected
 | 
					 | 
				
			||||||
      ${'12'}                                      | ${'12'}
 | 
					 | 
				
			||||||
      ${'12.3'}                                    | ${'12.3'}
 | 
					 | 
				
			||||||
      ${'12.3.4'}                                  | ${'12.3.4'}
 | 
					 | 
				
			||||||
      ${'v12.3.4'}                                 | ${'12.3.4'}
 | 
					 | 
				
			||||||
      ${'lts/erbium'}                              | ${'lts/erbium'}
 | 
					 | 
				
			||||||
      ${'lts/*'}                                   | ${'lts/*'}
 | 
					 | 
				
			||||||
      ${'nodejs 12.3.4'}                           | ${'12.3.4'}
 | 
					 | 
				
			||||||
      ${'ruby 2.3.4\nnodejs 12.3.4\npython 3.4.5'} | ${'12.3.4'}
 | 
					 | 
				
			||||||
      ${''}                                        | ${''}
 | 
					 | 
				
			||||||
      ${'unknown format'}                          | ${'unknown format'}
 | 
					 | 
				
			||||||
    `.it('parses "$contents"', ({contents, expected}) => {
 | 
					 | 
				
			||||||
      expect(im.parseNodeVersionFile(contents)).toBe(expected);
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
							
								
								
									
										402
									
								
								__tests__/rc-installer.test.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										402
									
								
								__tests__/rc-installer.test.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,402 @@
 | 
				
			|||||||
 | 
					import * as core from '@actions/core';
 | 
				
			||||||
 | 
					import * as io from '@actions/io';
 | 
				
			||||||
 | 
					import * as tc from '@actions/tool-cache';
 | 
				
			||||||
 | 
					import * as httpm from '@actions/http-client';
 | 
				
			||||||
 | 
					import * as exec from '@actions/exec';
 | 
				
			||||||
 | 
					import * as cache from '@actions/cache';
 | 
				
			||||||
 | 
					import fs from 'fs';
 | 
				
			||||||
 | 
					import cp from 'child_process';
 | 
				
			||||||
 | 
					import osm from 'os';
 | 
				
			||||||
 | 
					import path from 'path';
 | 
				
			||||||
 | 
					import * as main from '../src/main';
 | 
				
			||||||
 | 
					import * as auth from '../src/authutil';
 | 
				
			||||||
 | 
					import {INodeVersion} from '../src/distributions/base-models';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const nodeTestDist = require('./data/node-dist-index.json');
 | 
				
			||||||
 | 
					const nodeTestDistNightly = require('./data/node-nightly-index.json');
 | 
				
			||||||
 | 
					const nodeTestDistRc = require('./data/node-rc-index.json');
 | 
				
			||||||
 | 
					const nodeV8CanaryTestDist = require('./data/v8-canary-dist-index.json');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					describe('setup-node', () => {
 | 
				
			||||||
 | 
					  let inputs = {} as any;
 | 
				
			||||||
 | 
					  let os = {} as any;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let inSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let findSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let findAllVersionsSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let cnSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let logSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let warningSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let platSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let archSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let dlSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let exSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let cacheSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let dbgSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let whichSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let existsSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let mkdirpSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let execSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let authSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let isCacheActionAvailable: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let getExecOutputSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					  let getJsonSpy: jest.SpyInstance;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  beforeEach(() => {
 | 
				
			||||||
 | 
					    // @actions/core
 | 
				
			||||||
 | 
					    console.log('::stop-commands::stoptoken'); // Disable executing of runner commands when running tests in actions
 | 
				
			||||||
 | 
					    process.env['GITHUB_PATH'] = ''; // Stub out ENV file functionality so we can verify it writes to standard out
 | 
				
			||||||
 | 
					    process.env['GITHUB_OUTPUT'] = ''; // Stub out ENV file functionality so we can verify it writes to standard out
 | 
				
			||||||
 | 
					    inputs = {};
 | 
				
			||||||
 | 
					    inSpy = jest.spyOn(core, 'getInput');
 | 
				
			||||||
 | 
					    inSpy.mockImplementation(name => inputs[name]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // node
 | 
				
			||||||
 | 
					    os = {};
 | 
				
			||||||
 | 
					    platSpy = jest.spyOn(osm, 'platform');
 | 
				
			||||||
 | 
					    platSpy.mockImplementation(() => os['platform']);
 | 
				
			||||||
 | 
					    archSpy = jest.spyOn(osm, 'arch');
 | 
				
			||||||
 | 
					    archSpy.mockImplementation(() => os['arch']);
 | 
				
			||||||
 | 
					    execSpy = jest.spyOn(cp, 'execSync');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // @actions/tool-cache
 | 
				
			||||||
 | 
					    findSpy = jest.spyOn(tc, 'find');
 | 
				
			||||||
 | 
					    findAllVersionsSpy = jest.spyOn(tc, 'findAllVersions');
 | 
				
			||||||
 | 
					    dlSpy = jest.spyOn(tc, 'downloadTool');
 | 
				
			||||||
 | 
					    exSpy = jest.spyOn(tc, 'extractTar');
 | 
				
			||||||
 | 
					    cacheSpy = jest.spyOn(tc, 'cacheDir');
 | 
				
			||||||
 | 
					    // getDistSpy = jest.spyOn(im, 'getVersionsFromDist');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // http-client
 | 
				
			||||||
 | 
					    getJsonSpy = jest.spyOn(httpm.HttpClient.prototype, 'getJson');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // io
 | 
				
			||||||
 | 
					    whichSpy = jest.spyOn(io, 'which');
 | 
				
			||||||
 | 
					    existsSpy = jest.spyOn(fs, 'existsSync');
 | 
				
			||||||
 | 
					    mkdirpSpy = jest.spyOn(io, 'mkdirP');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // @actions/tool-cache
 | 
				
			||||||
 | 
					    isCacheActionAvailable = jest.spyOn(cache, 'isFeatureAvailable');
 | 
				
			||||||
 | 
					    isCacheActionAvailable.mockImplementation(() => false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // disable authentication portion for installer tests
 | 
				
			||||||
 | 
					    authSpy = jest.spyOn(auth, 'configAuthentication');
 | 
				
			||||||
 | 
					    authSpy.mockImplementation(() => {});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    getJsonSpy.mockImplementation(url => {
 | 
				
			||||||
 | 
					      let res: any;
 | 
				
			||||||
 | 
					      if (url.includes('/rc')) {
 | 
				
			||||||
 | 
					        res = <INodeVersion>nodeTestDistRc;
 | 
				
			||||||
 | 
					      } else if (url.includes('/nightly')) {
 | 
				
			||||||
 | 
					        res = <INodeVersion>nodeTestDistNightly;
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        res = <INodeVersion>nodeTestDist;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      return {result: res};
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // writes
 | 
				
			||||||
 | 
					    cnSpy = jest.spyOn(process.stdout, 'write');
 | 
				
			||||||
 | 
					    logSpy = jest.spyOn(core, 'info');
 | 
				
			||||||
 | 
					    dbgSpy = jest.spyOn(core, 'debug');
 | 
				
			||||||
 | 
					    warningSpy = jest.spyOn(core, 'warning');
 | 
				
			||||||
 | 
					    cnSpy.mockImplementation(line => {
 | 
				
			||||||
 | 
					      // uncomment to debug
 | 
				
			||||||
 | 
					      // process.stderr.write('write:' + line + '\n');
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    logSpy.mockImplementation(line => {
 | 
				
			||||||
 | 
					      // uncomment to debug
 | 
				
			||||||
 | 
					      // process.stderr.write('log:' + line + '\n');
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    dbgSpy.mockImplementation(msg => {
 | 
				
			||||||
 | 
					      // uncomment to see debug output
 | 
				
			||||||
 | 
					      // process.stderr.write(msg + '\n');
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    warningSpy.mockImplementation(msg => {
 | 
				
			||||||
 | 
					      // uncomment to debug
 | 
				
			||||||
 | 
					      // process.stderr.write('log:' + msg + '\n');
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // @actions/exec
 | 
				
			||||||
 | 
					    getExecOutputSpy = jest.spyOn(exec, 'getExecOutput');
 | 
				
			||||||
 | 
					    getExecOutputSpy.mockImplementation(() => 'v16.15.0-rc.1');
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  afterEach(() => {
 | 
				
			||||||
 | 
					    jest.resetAllMocks();
 | 
				
			||||||
 | 
					    jest.clearAllMocks();
 | 
				
			||||||
 | 
					    //jest.restoreAllMocks();
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  afterAll(async () => {
 | 
				
			||||||
 | 
					    console.log('::stoptoken::'); // Re-enable executing of runner commands when running tests in actions
 | 
				
			||||||
 | 
					    jest.restoreAllMocks();
 | 
				
			||||||
 | 
					  }, 100000);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  //--------------------------------------------------
 | 
				
			||||||
 | 
					  // Found in cache tests
 | 
				
			||||||
 | 
					  //--------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  it('finds version in cache with stable true', async () => {
 | 
				
			||||||
 | 
					    inputs['node-version'] = '12.0.0-rc.1';
 | 
				
			||||||
 | 
					    inputs.stable = 'true';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let toolPath = path.normalize('/cache/node/12.0.0-rc.1/x64');
 | 
				
			||||||
 | 
					    findSpy.mockImplementation(() => toolPath);
 | 
				
			||||||
 | 
					    await main.run();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    expect(logSpy).toHaveBeenCalledWith(`Found in cache @ ${toolPath}`);
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  it('finds version in cache with stable not supplied', async () => {
 | 
				
			||||||
 | 
					    inputs['node-version'] = '12.0.0-rc.1';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    inSpy.mockImplementation(name => inputs[name]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let toolPath = path.normalize('/cache/node/12.0.0-rc.1/x64');
 | 
				
			||||||
 | 
					    findSpy.mockImplementation(() => toolPath);
 | 
				
			||||||
 | 
					    await main.run();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    expect(logSpy).toHaveBeenCalledWith(`Found in cache @ ${toolPath}`);
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  it('finds version in cache and adds it to the path', async () => {
 | 
				
			||||||
 | 
					    inputs['node-version'] = '12.0.0-rc.1';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    inSpy.mockImplementation(name => inputs[name]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let toolPath = path.normalize('/cache/node/12.0.0-rc.1/x64');
 | 
				
			||||||
 | 
					    findSpy.mockImplementation(() => toolPath);
 | 
				
			||||||
 | 
					    await main.run();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let expPath = path.join(toolPath, 'bin');
 | 
				
			||||||
 | 
					    expect(cnSpy).toHaveBeenCalledWith(`::add-path::${expPath}${osm.EOL}`);
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  it('handles unhandled find error and reports error', async () => {
 | 
				
			||||||
 | 
					    let errMsg = 'unhandled error message';
 | 
				
			||||||
 | 
					    inputs['node-version'] = '12.0.0-rc.1';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    findSpy.mockImplementation(() => {
 | 
				
			||||||
 | 
					      throw new Error(errMsg);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    await main.run();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    expect(cnSpy).toHaveBeenCalledWith('::error::' + errMsg + osm.EOL);
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  it('falls back to a version from node dist', async () => {
 | 
				
			||||||
 | 
					    os.platform = 'linux';
 | 
				
			||||||
 | 
					    os.arch = 'x64';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let versionSpec = '13.0.0-rc.0';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    inputs['node-version'] = versionSpec;
 | 
				
			||||||
 | 
					    inputs['always-auth'] = false;
 | 
				
			||||||
 | 
					    inputs['token'] = 'faketoken';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // ... but not in the local cache
 | 
				
			||||||
 | 
					    findSpy.mockImplementation(() => '');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dlSpy.mockImplementation(async () => '/some/temp/path');
 | 
				
			||||||
 | 
					    let toolPath = path.normalize('/cache/node/13.0.0-rc.0/x64');
 | 
				
			||||||
 | 
					    exSpy.mockImplementation(async () => '/some/other/temp/path');
 | 
				
			||||||
 | 
					    cacheSpy.mockImplementation(async () => toolPath);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    await main.run();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let expPath = path.join(toolPath, 'bin');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    expect(dlSpy).toHaveBeenCalled();
 | 
				
			||||||
 | 
					    expect(exSpy).toHaveBeenCalled();
 | 
				
			||||||
 | 
					    expect(logSpy).toHaveBeenCalledWith('Extracting ...');
 | 
				
			||||||
 | 
					    expect(logSpy).toHaveBeenCalledWith('Done');
 | 
				
			||||||
 | 
					    expect(cnSpy).toHaveBeenCalledWith(`::add-path::${expPath}${osm.EOL}`);
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  it('does not find a version that does not exist', async () => {
 | 
				
			||||||
 | 
					    os.platform = 'linux';
 | 
				
			||||||
 | 
					    os.arch = 'x64';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let versionSpec = '9.99.9-rc.1';
 | 
				
			||||||
 | 
					    inputs['node-version'] = versionSpec;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    findSpy.mockImplementation(() => '');
 | 
				
			||||||
 | 
					    await main.run();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    expect(cnSpy).toHaveBeenCalledWith(
 | 
				
			||||||
 | 
					      `::error::Unable to find Node version '${versionSpec}' for platform ${os.platform} and architecture ${os.arch}.${osm.EOL}`
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  it('reports a failed download', async () => {
 | 
				
			||||||
 | 
					    let errMsg = 'unhandled download message';
 | 
				
			||||||
 | 
					    os.platform = 'linux';
 | 
				
			||||||
 | 
					    os.arch = 'x64';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let versionSpec = '14.7.0-rc.1';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    inputs['node-version'] = versionSpec;
 | 
				
			||||||
 | 
					    inputs['always-auth'] = false;
 | 
				
			||||||
 | 
					    inputs['token'] = 'faketoken';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    findSpy.mockImplementation(() => '');
 | 
				
			||||||
 | 
					    findAllVersionsSpy.mockImplementation(() => []);
 | 
				
			||||||
 | 
					    dlSpy.mockImplementation(() => {
 | 
				
			||||||
 | 
					      throw new Error(errMsg);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    await main.run();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    expect(cnSpy).toHaveBeenCalledWith(`::error::${errMsg}${osm.EOL}`);
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  it('acquires specified architecture of node', async () => {
 | 
				
			||||||
 | 
					    for (const {arch, version, osSpec} of [
 | 
				
			||||||
 | 
					      {arch: 'x86', version: '13.4.0-rc.0', osSpec: 'win32'},
 | 
				
			||||||
 | 
					      {arch: 'x86', version: '14.15.5-rc.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';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      let expectedUrl = `https://nodejs.org/download/rc/v${version}/node-v${version}-${platform}-${arch}.${fileExtension}`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // ... but not in the local cache
 | 
				
			||||||
 | 
					      findSpy.mockImplementation(() => '');
 | 
				
			||||||
 | 
					      findAllVersionsSpy.mockImplementation(() => []);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      dlSpy.mockImplementation(async () => '/some/temp/path');
 | 
				
			||||||
 | 
					      let 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('rc versions', () => {
 | 
				
			||||||
 | 
					    it.each([
 | 
				
			||||||
 | 
					      [
 | 
				
			||||||
 | 
					        '13.10.1-rc.0',
 | 
				
			||||||
 | 
					        '13.10.1-rc.0',
 | 
				
			||||||
 | 
					        'https://nodejs.org/download/rc/v13.10.1-rc.0/node-v13.10.1-rc.0-linux-x64.tar.gz'
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					      [
 | 
				
			||||||
 | 
					        '14.15.5-rc.1',
 | 
				
			||||||
 | 
					        '14.15.5-rc.1',
 | 
				
			||||||
 | 
					        'https://nodejs.org/download/rc/v14.15.5-rc.1/node-v14.15.5-rc.1-linux-x64.tar.gz'
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					      [
 | 
				
			||||||
 | 
					        '16.17.0-rc.1',
 | 
				
			||||||
 | 
					        '16.17.0-rc.1',
 | 
				
			||||||
 | 
					        'https://nodejs.org/download/rc/v16.17.0-rc.1/node-v16.17.0-rc.1-linux-x64.tar.gz'
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					      [
 | 
				
			||||||
 | 
					        '17.0.0-rc.1',
 | 
				
			||||||
 | 
					        '17.0.0-rc.1',
 | 
				
			||||||
 | 
					        'https://nodejs.org/download/rc/v17.0.0-rc.1/node-v17.0.0-rc.1-linux-x64.tar.gz'
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					      [
 | 
				
			||||||
 | 
					        '19.0.0-rc.2',
 | 
				
			||||||
 | 
					        '19.0.0-rc.2',
 | 
				
			||||||
 | 
					        'https://nodejs.org/download/rc/v19.0.0-rc.2/node-v19.0.0-rc.2-linux-x64.tar.gz'
 | 
				
			||||||
 | 
					      ]
 | 
				
			||||||
 | 
					    ])(
 | 
				
			||||||
 | 
					      'finds the versions in the index.json and installs it',
 | 
				
			||||||
 | 
					      async (input, expectedVersion, expectedUrl) => {
 | 
				
			||||||
 | 
					        const toolPath = path.normalize(`/cache/node/${expectedVersion}/x64`);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        findSpy.mockImplementation(() => '');
 | 
				
			||||||
 | 
					        findAllVersionsSpy.mockImplementation(() => []);
 | 
				
			||||||
 | 
					        dlSpy.mockImplementation(async () => '/some/temp/path');
 | 
				
			||||||
 | 
					        exSpy.mockImplementation(async () => '/some/other/temp/path');
 | 
				
			||||||
 | 
					        cacheSpy.mockImplementation(async () => toolPath);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        inputs['node-version'] = input;
 | 
				
			||||||
 | 
					        os['arch'] = 'x64';
 | 
				
			||||||
 | 
					        os['platform'] = 'linux';
 | 
				
			||||||
 | 
					        // act
 | 
				
			||||||
 | 
					        await main.run();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // assert
 | 
				
			||||||
 | 
					        expect(logSpy).toHaveBeenCalledWith('Extracting ...');
 | 
				
			||||||
 | 
					        expect(logSpy).toHaveBeenCalledWith('Adding to the cache ...');
 | 
				
			||||||
 | 
					        expect(cnSpy).toHaveBeenCalledWith(
 | 
				
			||||||
 | 
					          `::add-path::${path.join(toolPath, 'bin')}${osm.EOL}`
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it.each([
 | 
				
			||||||
 | 
					      ['13.10.1-rc.0', '13.10.1-rc.0'],
 | 
				
			||||||
 | 
					      ['14.15.5-rc.1', '14.15.5-rc.1'],
 | 
				
			||||||
 | 
					      ['16.17.0-rc.1', '16.17.0-rc.1'],
 | 
				
			||||||
 | 
					      ['17.0.0-rc.1', '17.0.0-rc.1']
 | 
				
			||||||
 | 
					    ])(
 | 
				
			||||||
 | 
					      'finds the %s version in the hostedToolcache',
 | 
				
			||||||
 | 
					      async (input, expectedVersion) => {
 | 
				
			||||||
 | 
					        const toolPath = path.normalize(`/cache/node/${expectedVersion}/x64`);
 | 
				
			||||||
 | 
					        findSpy.mockImplementation((_, version) =>
 | 
				
			||||||
 | 
					          path.normalize(`/cache/node/${version}/x64`)
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        findAllVersionsSpy.mockReturnValue([
 | 
				
			||||||
 | 
					          '2.2.2-rc.2',
 | 
				
			||||||
 | 
					          '1.1.1-rc.1',
 | 
				
			||||||
 | 
					          '99.1.1',
 | 
				
			||||||
 | 
					          expectedVersion,
 | 
				
			||||||
 | 
					          '88.1.1',
 | 
				
			||||||
 | 
					          '3.3.3-rc.3'
 | 
				
			||||||
 | 
					        ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        inputs['node-version'] = input;
 | 
				
			||||||
 | 
					        os['arch'] = 'x64';
 | 
				
			||||||
 | 
					        os['platform'] = 'linux';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // act
 | 
				
			||||||
 | 
					        await main.run();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // assert
 | 
				
			||||||
 | 
					        expect(logSpy).toHaveBeenCalledWith(`Found in cache @ ${toolPath}`);
 | 
				
			||||||
 | 
					        expect(cnSpy).toHaveBeenCalledWith(
 | 
				
			||||||
 | 
					          `::add-path::${path.join(toolPath, 'bin')}${osm.EOL}`
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it('throws an error if version is not found', async () => {
 | 
				
			||||||
 | 
					      const versionSpec = '19.0.0-rc.3';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      findSpy.mockImplementation(() => '');
 | 
				
			||||||
 | 
					      findAllVersionsSpy.mockImplementation(() => []);
 | 
				
			||||||
 | 
					      dlSpy.mockImplementation(async () => '/some/temp/path');
 | 
				
			||||||
 | 
					      exSpy.mockImplementation(async () => '/some/other/temp/path');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      inputs['node-version'] = versionSpec;
 | 
				
			||||||
 | 
					      os['arch'] = 'x64';
 | 
				
			||||||
 | 
					      os['platform'] = 'linux';
 | 
				
			||||||
 | 
					      // act
 | 
				
			||||||
 | 
					      await main.run();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // assert
 | 
				
			||||||
 | 
					      expect(cnSpy).toHaveBeenCalledWith(
 | 
				
			||||||
 | 
					        `::error::Unable to find Node version '${versionSpec}' for platform ${os.platform} and architecture ${os.arch}.${osm.EOL}`
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
							
								
								
									
										64
									
								
								dist/cache-save/index.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										64
									
								
								dist/cache-save/index.js
									
									
									
									
										vendored
									
									
								
							@@ -61019,6 +61019,25 @@ exports.fromPromise = function (fn) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
"use strict";
 | 
					"use strict";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
 | 
				
			||||||
 | 
					    if (k2 === undefined) k2 = k;
 | 
				
			||||||
 | 
					    Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
 | 
				
			||||||
 | 
					}) : (function(o, m, k, k2) {
 | 
				
			||||||
 | 
					    if (k2 === undefined) k2 = k;
 | 
				
			||||||
 | 
					    o[k2] = m[k];
 | 
				
			||||||
 | 
					}));
 | 
				
			||||||
 | 
					var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
 | 
				
			||||||
 | 
					    Object.defineProperty(o, "default", { enumerable: true, value: v });
 | 
				
			||||||
 | 
					}) : function(o, v) {
 | 
				
			||||||
 | 
					    o["default"] = v;
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					var __importStar = (this && this.__importStar) || function (mod) {
 | 
				
			||||||
 | 
					    if (mod && mod.__esModule) return mod;
 | 
				
			||||||
 | 
					    var result = {};
 | 
				
			||||||
 | 
					    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
 | 
				
			||||||
 | 
					    __setModuleDefault(result, mod);
 | 
				
			||||||
 | 
					    return result;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
 | 
					var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
 | 
				
			||||||
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
 | 
					    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
 | 
				
			||||||
    return new (P || (P = Promise))(function (resolve, reject) {
 | 
					    return new (P || (P = Promise))(function (resolve, reject) {
 | 
				
			||||||
@@ -61028,17 +61047,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
 | 
				
			|||||||
        step((generator = generator.apply(thisArg, _arguments || [])).next());
 | 
					        step((generator = generator.apply(thisArg, _arguments || [])).next());
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
var __importStar = (this && this.__importStar) || function (mod) {
 | 
					 | 
				
			||||||
    if (mod && mod.__esModule) return mod;
 | 
					 | 
				
			||||||
    var result = {};
 | 
					 | 
				
			||||||
    if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
 | 
					 | 
				
			||||||
    result["default"] = mod;
 | 
					 | 
				
			||||||
    return result;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
var __importDefault = (this && this.__importDefault) || function (mod) {
 | 
					var __importDefault = (this && this.__importDefault) || function (mod) {
 | 
				
			||||||
    return (mod && mod.__esModule) ? mod : { "default": mod };
 | 
					    return (mod && mod.__esModule) ? mod : { "default": mod };
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
 | 
					Object.defineProperty(exports, "__esModule", ({ value: true }));
 | 
				
			||||||
 | 
					exports.run = void 0;
 | 
				
			||||||
const core = __importStar(__nccwpck_require__(2186));
 | 
					const core = __importStar(__nccwpck_require__(2186));
 | 
				
			||||||
const cache = __importStar(__nccwpck_require__(7799));
 | 
					const cache = __importStar(__nccwpck_require__(7799));
 | 
				
			||||||
const fs_1 = __importDefault(__nccwpck_require__(7147));
 | 
					const fs_1 = __importDefault(__nccwpck_require__(7147));
 | 
				
			||||||
@@ -61095,6 +61108,25 @@ run();
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
"use strict";
 | 
					"use strict";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
 | 
				
			||||||
 | 
					    if (k2 === undefined) k2 = k;
 | 
				
			||||||
 | 
					    Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
 | 
				
			||||||
 | 
					}) : (function(o, m, k, k2) {
 | 
				
			||||||
 | 
					    if (k2 === undefined) k2 = k;
 | 
				
			||||||
 | 
					    o[k2] = m[k];
 | 
				
			||||||
 | 
					}));
 | 
				
			||||||
 | 
					var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
 | 
				
			||||||
 | 
					    Object.defineProperty(o, "default", { enumerable: true, value: v });
 | 
				
			||||||
 | 
					}) : function(o, v) {
 | 
				
			||||||
 | 
					    o["default"] = v;
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					var __importStar = (this && this.__importStar) || function (mod) {
 | 
				
			||||||
 | 
					    if (mod && mod.__esModule) return mod;
 | 
				
			||||||
 | 
					    var result = {};
 | 
				
			||||||
 | 
					    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
 | 
				
			||||||
 | 
					    __setModuleDefault(result, mod);
 | 
				
			||||||
 | 
					    return result;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
 | 
					var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
 | 
				
			||||||
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
 | 
					    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
 | 
				
			||||||
    return new (P || (P = Promise))(function (resolve, reject) {
 | 
					    return new (P || (P = Promise))(function (resolve, reject) {
 | 
				
			||||||
@@ -61104,14 +61136,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
 | 
				
			|||||||
        step((generator = generator.apply(thisArg, _arguments || [])).next());
 | 
					        step((generator = generator.apply(thisArg, _arguments || [])).next());
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
var __importStar = (this && this.__importStar) || function (mod) {
 | 
					 | 
				
			||||||
    if (mod && mod.__esModule) return mod;
 | 
					 | 
				
			||||||
    var result = {};
 | 
					 | 
				
			||||||
    if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
 | 
					 | 
				
			||||||
    result["default"] = mod;
 | 
					 | 
				
			||||||
    return result;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
 | 
					Object.defineProperty(exports, "__esModule", ({ value: true }));
 | 
				
			||||||
 | 
					exports.isCacheFeatureAvailable = exports.isGhes = exports.getCacheDirectoryPath = exports.getPackageManagerInfo = exports.getCommandOutput = exports.supportedPackageManagers = void 0;
 | 
				
			||||||
const core = __importStar(__nccwpck_require__(2186));
 | 
					const core = __importStar(__nccwpck_require__(2186));
 | 
				
			||||||
const exec = __importStar(__nccwpck_require__(1514));
 | 
					const exec = __importStar(__nccwpck_require__(1514));
 | 
				
			||||||
const cache = __importStar(__nccwpck_require__(7799));
 | 
					const cache = __importStar(__nccwpck_require__(7799));
 | 
				
			||||||
@@ -61133,7 +61159,7 @@ exports.supportedPackageManagers = {
 | 
				
			|||||||
        getCacheFolderCommand: 'yarn config get cacheFolder'
 | 
					        getCacheFolderCommand: 'yarn config get cacheFolder'
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
exports.getCommandOutput = (toolCommand) => __awaiter(void 0, void 0, void 0, function* () {
 | 
					const getCommandOutput = (toolCommand) => __awaiter(void 0, void 0, void 0, function* () {
 | 
				
			||||||
    let { stdout, stderr, exitCode } = yield exec.getExecOutput(toolCommand, undefined, { ignoreReturnCode: true });
 | 
					    let { stdout, stderr, exitCode } = yield exec.getExecOutput(toolCommand, undefined, { ignoreReturnCode: true });
 | 
				
			||||||
    if (exitCode) {
 | 
					    if (exitCode) {
 | 
				
			||||||
        stderr = !stderr.trim()
 | 
					        stderr = !stderr.trim()
 | 
				
			||||||
@@ -61143,6 +61169,7 @@ exports.getCommandOutput = (toolCommand) => __awaiter(void 0, void 0, void 0, fu
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    return stdout.trim();
 | 
					    return stdout.trim();
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					exports.getCommandOutput = getCommandOutput;
 | 
				
			||||||
const getPackageManagerVersion = (packageManager, command) => __awaiter(void 0, void 0, void 0, function* () {
 | 
					const getPackageManagerVersion = (packageManager, command) => __awaiter(void 0, void 0, void 0, function* () {
 | 
				
			||||||
    const stdOut = yield exports.getCommandOutput(`${packageManager} ${command}`);
 | 
					    const stdOut = yield exports.getCommandOutput(`${packageManager} ${command}`);
 | 
				
			||||||
    if (!stdOut) {
 | 
					    if (!stdOut) {
 | 
				
			||||||
@@ -61150,7 +61177,7 @@ const getPackageManagerVersion = (packageManager, command) => __awaiter(void 0,
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    return stdOut;
 | 
					    return stdOut;
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
exports.getPackageManagerInfo = (packageManager) => __awaiter(void 0, void 0, void 0, function* () {
 | 
					const getPackageManagerInfo = (packageManager) => __awaiter(void 0, void 0, void 0, function* () {
 | 
				
			||||||
    if (packageManager === 'npm') {
 | 
					    if (packageManager === 'npm') {
 | 
				
			||||||
        return exports.supportedPackageManagers.npm;
 | 
					        return exports.supportedPackageManagers.npm;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -61171,7 +61198,8 @@ exports.getPackageManagerInfo = (packageManager) => __awaiter(void 0, void 0, vo
 | 
				
			|||||||
        return null;
 | 
					        return null;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
exports.getCacheDirectoryPath = (packageManagerInfo, packageManager) => __awaiter(void 0, void 0, void 0, function* () {
 | 
					exports.getPackageManagerInfo = getPackageManagerInfo;
 | 
				
			||||||
 | 
					const getCacheDirectoryPath = (packageManagerInfo, packageManager) => __awaiter(void 0, void 0, void 0, function* () {
 | 
				
			||||||
    const stdOut = yield exports.getCommandOutput(packageManagerInfo.getCacheFolderCommand);
 | 
					    const stdOut = yield exports.getCommandOutput(packageManagerInfo.getCacheFolderCommand);
 | 
				
			||||||
    if (!stdOut) {
 | 
					    if (!stdOut) {
 | 
				
			||||||
        throw new Error(`Could not get cache folder path for ${packageManager}`);
 | 
					        throw new Error(`Could not get cache folder path for ${packageManager}`);
 | 
				
			||||||
@@ -61179,6 +61207,7 @@ exports.getCacheDirectoryPath = (packageManagerInfo, packageManager) => __awaite
 | 
				
			|||||||
    core.debug(`${packageManager} path is ${stdOut}`);
 | 
					    core.debug(`${packageManager} path is ${stdOut}`);
 | 
				
			||||||
    return stdOut.trim();
 | 
					    return stdOut.trim();
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					exports.getCacheDirectoryPath = getCacheDirectoryPath;
 | 
				
			||||||
function isGhes() {
 | 
					function isGhes() {
 | 
				
			||||||
    const ghUrl = new URL(process.env['GITHUB_SERVER_URL'] || 'https://github.com');
 | 
					    const ghUrl = new URL(process.env['GITHUB_SERVER_URL'] || 'https://github.com');
 | 
				
			||||||
    return ghUrl.hostname.toUpperCase() !== 'GITHUB.COM';
 | 
					    return ghUrl.hostname.toUpperCase() !== 'GITHUB.COM';
 | 
				
			||||||
@@ -61205,6 +61234,7 @@ exports.isCacheFeatureAvailable = isCacheFeatureAvailable;
 | 
				
			|||||||
"use strict";
 | 
					"use strict";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
 | 
					Object.defineProperty(exports, "__esModule", ({ value: true }));
 | 
				
			||||||
 | 
					exports.Outputs = exports.State = exports.LockType = void 0;
 | 
				
			||||||
var LockType;
 | 
					var LockType;
 | 
				
			||||||
(function (LockType) {
 | 
					(function (LockType) {
 | 
				
			||||||
    LockType["Npm"] = "npm";
 | 
					    LockType["Npm"] = "npm";
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										1184
									
								
								dist/setup/index.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1184
									
								
								dist/setup/index.js
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -104,6 +104,57 @@ jobs:
 | 
				
			|||||||
      - run: npm test
 | 
					      - run: npm test
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## V8 Canary versions
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					You can specify a nightly version to download it from https://nodejs.org/download/v8-canary.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Install v8 canary build for specific node version
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```yaml
 | 
				
			||||||
 | 
					jobs:
 | 
				
			||||||
 | 
					  build:
 | 
				
			||||||
 | 
					    runs-on: ubuntu-latest
 | 
				
			||||||
 | 
					    name: Node sample
 | 
				
			||||||
 | 
					    steps:
 | 
				
			||||||
 | 
					      - uses: actions/checkout@v3
 | 
				
			||||||
 | 
					      - uses: actions/setup-node@v3
 | 
				
			||||||
 | 
					        with:
 | 
				
			||||||
 | 
					          node-version: '20.0.0-v8-canary' # it will install the latest v8 canary release for node 20.0.0
 | 
				
			||||||
 | 
					      - run: npm ci
 | 
				
			||||||
 | 
					      - run: npm test
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					### Install v8 canary build for major node version
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```yaml
 | 
				
			||||||
 | 
					jobs:
 | 
				
			||||||
 | 
					  build:
 | 
				
			||||||
 | 
					    runs-on: ubuntu-latest
 | 
				
			||||||
 | 
					    name: Node sample
 | 
				
			||||||
 | 
					    steps:
 | 
				
			||||||
 | 
					      - uses: actions/checkout@v3
 | 
				
			||||||
 | 
					      - uses: actions/setup-node@v3
 | 
				
			||||||
 | 
					        with:
 | 
				
			||||||
 | 
					          node-version: '20-v8-canary' # it will install the latest v8 canary release for node 20
 | 
				
			||||||
 | 
					      - run: npm ci
 | 
				
			||||||
 | 
					      - run: npm test
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Install the exact v8 canary version
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```yaml
 | 
				
			||||||
 | 
					jobs:
 | 
				
			||||||
 | 
					  build:
 | 
				
			||||||
 | 
					    runs-on: ubuntu-latest
 | 
				
			||||||
 | 
					    name: Node sample
 | 
				
			||||||
 | 
					    steps:
 | 
				
			||||||
 | 
					      - uses: actions/checkout@v3
 | 
				
			||||||
 | 
					      - uses: actions/setup-node@v3
 | 
				
			||||||
 | 
					        with:
 | 
				
			||||||
 | 
					          node-version: 'v20.1.1-v8-canary20221103f7e2421e91'
 | 
				
			||||||
 | 
					      - run: npm ci
 | 
				
			||||||
 | 
					      - run: npm test
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Nightly versions
 | 
					## Nightly versions
 | 
				
			||||||
 | 
					
 | 
				
			||||||
You can specify a nightly version to download it from https://nodejs.org/download/nightly. 
 | 
					You can specify a nightly version to download it from https://nodejs.org/download/nightly. 
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										46
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										46
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							@@ -28,7 +28,7 @@
 | 
				
			|||||||
        "jest-circus": "^27.2.5",
 | 
					        "jest-circus": "^27.2.5",
 | 
				
			||||||
        "prettier": "^1.19.1",
 | 
					        "prettier": "^1.19.1",
 | 
				
			||||||
        "ts-jest": "^27.0.5",
 | 
					        "ts-jest": "^27.0.5",
 | 
				
			||||||
        "typescript": "^3.8.3"
 | 
					        "typescript": "^4.2.3"
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "node_modules/@actions/cache": {
 | 
					    "node_modules/@actions/cache": {
 | 
				
			||||||
@@ -3779,13 +3779,10 @@
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "node_modules/json5": {
 | 
					    "node_modules/json5": {
 | 
				
			||||||
      "version": "2.2.0",
 | 
					      "version": "2.2.2",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.2.tgz",
 | 
				
			||||||
      "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==",
 | 
					      "integrity": "sha512-46Tk9JiOL2z7ytNQWFLpj99RZkVgeHf87yGQKsIkaPz1qSH9UczKH1rO7K3wgRselo0tYMUNfecYpm/p1vC7tQ==",
 | 
				
			||||||
      "dev": true,
 | 
					      "dev": true,
 | 
				
			||||||
      "dependencies": {
 | 
					 | 
				
			||||||
        "minimist": "^1.2.5"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      "bin": {
 | 
					      "bin": {
 | 
				
			||||||
        "json5": "lib/cli.js"
 | 
					        "json5": "lib/cli.js"
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
@@ -3965,12 +3962,6 @@
 | 
				
			|||||||
        "node": "*"
 | 
					        "node": "*"
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "node_modules/minimist": {
 | 
					 | 
				
			||||||
      "version": "1.2.6",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
 | 
					 | 
				
			||||||
      "dev": true
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/ms": {
 | 
					    "node_modules/ms": {
 | 
				
			||||||
      "version": "2.1.2",
 | 
					      "version": "2.1.2",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
 | 
				
			||||||
@@ -4813,9 +4804,9 @@
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "node_modules/typescript": {
 | 
					    "node_modules/typescript": {
 | 
				
			||||||
      "version": "3.8.3",
 | 
					      "version": "4.2.3",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.8.3.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.3.tgz",
 | 
				
			||||||
      "integrity": "sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w==",
 | 
					      "integrity": "sha512-qOcYwxaByStAWrBf4x0fibwZvMRG+r4cQoTjbPtUlrWjBHbmCAww1i448U0GJ+3cNNEtebDteo/cHOR3xJ4wEw==",
 | 
				
			||||||
      "dev": true,
 | 
					      "dev": true,
 | 
				
			||||||
      "bin": {
 | 
					      "bin": {
 | 
				
			||||||
        "tsc": "bin/tsc",
 | 
					        "tsc": "bin/tsc",
 | 
				
			||||||
@@ -8088,13 +8079,10 @@
 | 
				
			|||||||
      "dev": true
 | 
					      "dev": true
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "json5": {
 | 
					    "json5": {
 | 
				
			||||||
      "version": "2.2.0",
 | 
					      "version": "2.2.2",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.2.tgz",
 | 
				
			||||||
      "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==",
 | 
					      "integrity": "sha512-46Tk9JiOL2z7ytNQWFLpj99RZkVgeHf87yGQKsIkaPz1qSH9UczKH1rO7K3wgRselo0tYMUNfecYpm/p1vC7tQ==",
 | 
				
			||||||
      "dev": true,
 | 
					      "dev": true
 | 
				
			||||||
      "requires": {
 | 
					 | 
				
			||||||
        "minimist": "^1.2.5"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "kleur": {
 | 
					    "kleur": {
 | 
				
			||||||
      "version": "3.0.3",
 | 
					      "version": "3.0.3",
 | 
				
			||||||
@@ -8229,12 +8217,6 @@
 | 
				
			|||||||
        "brace-expansion": "^1.1.7"
 | 
					        "brace-expansion": "^1.1.7"
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "minimist": {
 | 
					 | 
				
			||||||
      "version": "1.2.6",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
 | 
					 | 
				
			||||||
      "dev": true
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "ms": {
 | 
					    "ms": {
 | 
				
			||||||
      "version": "2.1.2",
 | 
					      "version": "2.1.2",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
 | 
				
			||||||
@@ -8861,9 +8843,9 @@
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "typescript": {
 | 
					    "typescript": {
 | 
				
			||||||
      "version": "3.8.3",
 | 
					      "version": "4.2.3",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.8.3.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.3.tgz",
 | 
				
			||||||
      "integrity": "sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w==",
 | 
					      "integrity": "sha512-qOcYwxaByStAWrBf4x0fibwZvMRG+r4cQoTjbPtUlrWjBHbmCAww1i448U0GJ+3cNNEtebDteo/cHOR3xJ4wEw==",
 | 
				
			||||||
      "dev": true
 | 
					      "dev": true
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "universal-user-agent": {
 | 
					    "universal-user-agent": {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -43,6 +43,6 @@
 | 
				
			|||||||
    "jest-circus": "^27.2.5",
 | 
					    "jest-circus": "^27.2.5",
 | 
				
			||||||
    "prettier": "^1.19.1",
 | 
					    "prettier": "^1.19.1",
 | 
				
			||||||
    "ts-jest": "^27.0.5",
 | 
					    "ts-jest": "^27.0.5",
 | 
				
			||||||
    "typescript": "^3.8.3"
 | 
					    "typescript": "^4.2.3"
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										53
									
								
								src/distributions/base-distribution-prerelease.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								src/distributions/base-distribution-prerelease.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,53 @@
 | 
				
			|||||||
 | 
					import * as tc from '@actions/tool-cache';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import semver from 'semver';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import BaseDistribution from './base-distribution';
 | 
				
			||||||
 | 
					import {NodeInputs} from './base-models';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default abstract class BasePrereleaseNodejs extends BaseDistribution {
 | 
				
			||||||
 | 
					  protected abstract distribution: string;
 | 
				
			||||||
 | 
					  constructor(nodeInfo: NodeInputs) {
 | 
				
			||||||
 | 
					    super(nodeInfo);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected findVersionInHostedToolCacheDirectory(): string {
 | 
				
			||||||
 | 
					    let toolPath = '';
 | 
				
			||||||
 | 
					    const localVersionPaths = tc
 | 
				
			||||||
 | 
					      .findAllVersions('node', this.nodeInfo.arch)
 | 
				
			||||||
 | 
					      .filter(i => {
 | 
				
			||||||
 | 
					        const prerelease = semver.prerelease(i);
 | 
				
			||||||
 | 
					        if (!prerelease) {
 | 
				
			||||||
 | 
					          return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return prerelease[0].includes(this.distribution);
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    localVersionPaths.sort(semver.rcompare);
 | 
				
			||||||
 | 
					    const localVersion = this.evaluateVersions(localVersionPaths);
 | 
				
			||||||
 | 
					    if (localVersion) {
 | 
				
			||||||
 | 
					      toolPath = tc.find('node', localVersion, this.nodeInfo.arch);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return toolPath;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected validRange(versionSpec: string) {
 | 
				
			||||||
 | 
					    let range: string;
 | 
				
			||||||
 | 
					    const [raw, prerelease] = this.splitVersionSpec(versionSpec);
 | 
				
			||||||
 | 
					    const isValidVersion = semver.valid(raw);
 | 
				
			||||||
 | 
					    const rawVersion = (isValidVersion ? raw : semver.coerce(raw))!;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (prerelease !== this.distribution) {
 | 
				
			||||||
 | 
					      range = versionSpec;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      range = `${semver.validRange(`^${rawVersion}-${this.distribution}`)}-0`;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return {range, options: {includePrerelease: !isValidVersion}};
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected splitVersionSpec(versionSpec: string) {
 | 
				
			||||||
 | 
					    return versionSpec.split(/-(.*)/s);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										287
									
								
								src/distributions/base-distribution.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										287
									
								
								src/distributions/base-distribution.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,287 @@
 | 
				
			|||||||
 | 
					import * as tc from '@actions/tool-cache';
 | 
				
			||||||
 | 
					import * as hc from '@actions/http-client';
 | 
				
			||||||
 | 
					import * as core from '@actions/core';
 | 
				
			||||||
 | 
					import * as io from '@actions/io';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import semver from 'semver';
 | 
				
			||||||
 | 
					import * as assert from 'assert';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import * as path from 'path';
 | 
				
			||||||
 | 
					import os from 'os';
 | 
				
			||||||
 | 
					import fs from 'fs';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import {NodeInputs, INodeVersion, INodeVersionInfo} from './base-models';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default abstract class BaseDistribution {
 | 
				
			||||||
 | 
					  protected httpClient: hc.HttpClient;
 | 
				
			||||||
 | 
					  protected osPlat = os.platform();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  constructor(protected nodeInfo: NodeInputs) {
 | 
				
			||||||
 | 
					    this.httpClient = new hc.HttpClient('setup-node', [], {
 | 
				
			||||||
 | 
					      allowRetries: true,
 | 
				
			||||||
 | 
					      maxRetries: 3
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected abstract getDistributionUrl(): string;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public async setupNodeJs() {
 | 
				
			||||||
 | 
					    let nodeJsVersions: INodeVersion[] | undefined;
 | 
				
			||||||
 | 
					    if (this.nodeInfo.checkLatest) {
 | 
				
			||||||
 | 
					      const evaluatedVersion = await this.findVersionInDist(nodeJsVersions);
 | 
				
			||||||
 | 
					      this.nodeInfo.versionSpec = evaluatedVersion;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let toolPath = this.findVersionInHostedToolCacheDirectory();
 | 
				
			||||||
 | 
					    if (toolPath) {
 | 
				
			||||||
 | 
					      core.info(`Found in cache @ ${toolPath}`);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      const evaluatedVersion = await this.findVersionInDist(nodeJsVersions);
 | 
				
			||||||
 | 
					      const toolName = this.getNodejsDistInfo(evaluatedVersion);
 | 
				
			||||||
 | 
					      toolPath = await this.downloadNodejs(toolName);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (this.osPlat != 'win32') {
 | 
				
			||||||
 | 
					      toolPath = path.join(toolPath, 'bin');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    core.addPath(toolPath);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected async findVersionInDist(nodeJsVersions?: INodeVersion[]) {
 | 
				
			||||||
 | 
					    if (!nodeJsVersions) {
 | 
				
			||||||
 | 
					      nodeJsVersions = await this.getNodeJsVersions();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    const versions = this.filterVersions(nodeJsVersions);
 | 
				
			||||||
 | 
					    const evaluatedVersion = this.evaluateVersions(versions);
 | 
				
			||||||
 | 
					    if (!evaluatedVersion) {
 | 
				
			||||||
 | 
					      throw new Error(
 | 
				
			||||||
 | 
					        `Unable to find Node version '${this.nodeInfo.versionSpec}' for platform ${this.osPlat} and architecture ${this.nodeInfo.arch}.`
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return evaluatedVersion;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected evaluateVersions(versions: string[]): string {
 | 
				
			||||||
 | 
					    let version = '';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const {range, options} = this.validRange(this.nodeInfo.versionSpec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    core.debug(`evaluating ${versions.length} versions`);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (let potential of versions) {
 | 
				
			||||||
 | 
					      const satisfied: boolean = semver.satisfies(potential, range, options);
 | 
				
			||||||
 | 
					      if (satisfied) {
 | 
				
			||||||
 | 
					        version = potential;
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (version) {
 | 
				
			||||||
 | 
					      core.debug(`matched: ${version}`);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      core.debug('match not found');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return version;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected findVersionInHostedToolCacheDirectory() {
 | 
				
			||||||
 | 
					    return tc.find('node', this.nodeInfo.versionSpec, this.nodeInfo.arch);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected async getNodeJsVersions(): Promise<INodeVersion[]> {
 | 
				
			||||||
 | 
					    const initialUrl = this.getDistributionUrl();
 | 
				
			||||||
 | 
					    const dataUrl = `${initialUrl}/index.json`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let response = await this.httpClient.getJson<INodeVersion[]>(dataUrl);
 | 
				
			||||||
 | 
					    return response.result || [];
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected getNodejsDistInfo(version: string) {
 | 
				
			||||||
 | 
					    let osArch: string = this.translateArchToDistUrl(this.nodeInfo.arch);
 | 
				
			||||||
 | 
					    version = semver.clean(version) || '';
 | 
				
			||||||
 | 
					    let fileName: string =
 | 
				
			||||||
 | 
					      this.osPlat == 'win32'
 | 
				
			||||||
 | 
					        ? `node-v${version}-win-${osArch}`
 | 
				
			||||||
 | 
					        : `node-v${version}-${this.osPlat}-${osArch}`;
 | 
				
			||||||
 | 
					    let urlFileName: string =
 | 
				
			||||||
 | 
					      this.osPlat == 'win32' ? `${fileName}.7z` : `${fileName}.tar.gz`;
 | 
				
			||||||
 | 
					    const initialUrl = this.getDistributionUrl();
 | 
				
			||||||
 | 
					    const url = `${initialUrl}/v${version}/${urlFileName}`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return <INodeVersionInfo>{
 | 
				
			||||||
 | 
					      downloadUrl: url,
 | 
				
			||||||
 | 
					      resolvedVersion: version,
 | 
				
			||||||
 | 
					      arch: osArch,
 | 
				
			||||||
 | 
					      fileName: fileName
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected async downloadNodejs(info: INodeVersionInfo) {
 | 
				
			||||||
 | 
					    let downloadPath = '';
 | 
				
			||||||
 | 
					    core.info(
 | 
				
			||||||
 | 
					      `Acquiring ${info.resolvedVersion} - ${info.arch} from ${info.downloadUrl}`
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					      downloadPath = await tc.downloadTool(info.downloadUrl);
 | 
				
			||||||
 | 
					    } catch (err) {
 | 
				
			||||||
 | 
					      if (err instanceof tc.HTTPError && err.httpStatusCode == 404) {
 | 
				
			||||||
 | 
					        return await this.acquireNodeFromFallbackLocation(
 | 
				
			||||||
 | 
					          info.resolvedVersion,
 | 
				
			||||||
 | 
					          info.arch
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      throw err;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let toolPath = await this.extractArchive(downloadPath, info);
 | 
				
			||||||
 | 
					    core.info('Done');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return toolPath;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected validRange(versionSpec: string) {
 | 
				
			||||||
 | 
					    let options: semver.Options | undefined;
 | 
				
			||||||
 | 
					    const c = semver.clean(versionSpec) || '';
 | 
				
			||||||
 | 
					    const valid = semver.valid(c) ?? versionSpec;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return {range: valid, options};
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected async acquireNodeFromFallbackLocation(
 | 
				
			||||||
 | 
					    version: string,
 | 
				
			||||||
 | 
					    arch: string = os.arch()
 | 
				
			||||||
 | 
					  ): Promise<string> {
 | 
				
			||||||
 | 
					    const initialUrl = this.getDistributionUrl();
 | 
				
			||||||
 | 
					    let osArch: string = this.translateArchToDistUrl(arch);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Create temporary folder to download in to
 | 
				
			||||||
 | 
					    const tempDownloadFolder: string =
 | 
				
			||||||
 | 
					      'temp_' + Math.floor(Math.random() * 2000000000);
 | 
				
			||||||
 | 
					    const tempDirectory = process.env['RUNNER_TEMP'] || '';
 | 
				
			||||||
 | 
					    assert.ok(tempDirectory, 'Expected RUNNER_TEMP to be defined');
 | 
				
			||||||
 | 
					    const tempDir: string = path.join(tempDirectory, tempDownloadFolder);
 | 
				
			||||||
 | 
					    await io.mkdirP(tempDir);
 | 
				
			||||||
 | 
					    let exeUrl: string;
 | 
				
			||||||
 | 
					    let libUrl: string;
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					      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 = await tc.downloadTool(exeUrl);
 | 
				
			||||||
 | 
					      await io.cp(exePath, path.join(tempDir, 'node.exe'));
 | 
				
			||||||
 | 
					      const libPath = await tc.downloadTool(libUrl);
 | 
				
			||||||
 | 
					      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);
 | 
				
			||||||
 | 
					        await io.cp(exePath, path.join(tempDir, 'node.exe'));
 | 
				
			||||||
 | 
					        const libPath = await tc.downloadTool(libUrl);
 | 
				
			||||||
 | 
					        await io.cp(libPath, path.join(tempDir, 'node.lib'));
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        throw err;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const toolPath = await tc.cacheDir(tempDir, 'node', version, arch);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return toolPath;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected async extractArchive(
 | 
				
			||||||
 | 
					    downloadPath: string,
 | 
				
			||||||
 | 
					    info: INodeVersionInfo | null
 | 
				
			||||||
 | 
					  ) {
 | 
				
			||||||
 | 
					    //
 | 
				
			||||||
 | 
					    // Extract
 | 
				
			||||||
 | 
					    //
 | 
				
			||||||
 | 
					    core.info('Extracting ...');
 | 
				
			||||||
 | 
					    let extPath: string;
 | 
				
			||||||
 | 
					    info = info || ({} as INodeVersionInfo); // satisfy compiler, never null when reaches here
 | 
				
			||||||
 | 
					    if (this.osPlat == 'win32') {
 | 
				
			||||||
 | 
					      const _7zPath = path.join(__dirname, '../..', 'externals', '7zr.exe');
 | 
				
			||||||
 | 
					      extPath = await tc.extract7z(downloadPath, undefined, _7zPath);
 | 
				
			||||||
 | 
					      // 7z extracts to folder matching file name
 | 
				
			||||||
 | 
					      const nestedPath = path.join(
 | 
				
			||||||
 | 
					        extPath,
 | 
				
			||||||
 | 
					        path.basename(info.fileName, '.7z')
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					      if (fs.existsSync(nestedPath)) {
 | 
				
			||||||
 | 
					        extPath = nestedPath;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      extPath = await tc.extractTar(downloadPath, undefined, [
 | 
				
			||||||
 | 
					        'xz',
 | 
				
			||||||
 | 
					        '--strip',
 | 
				
			||||||
 | 
					        '1'
 | 
				
			||||||
 | 
					      ]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //
 | 
				
			||||||
 | 
					    // Install into the local tool cache - node extracts with a root folder that matches the fileName downloaded
 | 
				
			||||||
 | 
					    //
 | 
				
			||||||
 | 
					    core.info('Adding to the cache ...');
 | 
				
			||||||
 | 
					    const toolPath = await tc.cacheDir(
 | 
				
			||||||
 | 
					      extPath,
 | 
				
			||||||
 | 
					      'node',
 | 
				
			||||||
 | 
					      info.resolvedVersion,
 | 
				
			||||||
 | 
					      info.arch
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return toolPath;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected getDistFileName(): string {
 | 
				
			||||||
 | 
					    let osArch: string = this.translateArchToDistUrl(this.nodeInfo.arch);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // node offers a json list of versions
 | 
				
			||||||
 | 
					    let dataFileName: string;
 | 
				
			||||||
 | 
					    switch (this.osPlat) {
 | 
				
			||||||
 | 
					      case 'linux':
 | 
				
			||||||
 | 
					        dataFileName = `linux-${osArch}`;
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      case 'darwin':
 | 
				
			||||||
 | 
					        dataFileName = `osx-${osArch}-tar`;
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      case 'win32':
 | 
				
			||||||
 | 
					        dataFileName = `win-${osArch}-exe`;
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      default:
 | 
				
			||||||
 | 
					        throw new Error(`Unexpected OS '${this.osPlat}'`);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return dataFileName;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected filterVersions(nodeJsVersions: INodeVersion[]) {
 | 
				
			||||||
 | 
					    const versions: string[] = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const dataFileName = this.getDistFileName();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    nodeJsVersions.forEach((nodeVersion: INodeVersion) => {
 | 
				
			||||||
 | 
					      // ensure this version supports your os and platform
 | 
				
			||||||
 | 
					      if (nodeVersion.files.indexOf(dataFileName) >= 0) {
 | 
				
			||||||
 | 
					        versions.push(nodeVersion.version);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return versions.sort(semver.rcompare);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected translateArchToDistUrl(arch: string): string {
 | 
				
			||||||
 | 
					    switch (arch) {
 | 
				
			||||||
 | 
					      case 'arm':
 | 
				
			||||||
 | 
					        return 'armv7l';
 | 
				
			||||||
 | 
					      default:
 | 
				
			||||||
 | 
					        return arch;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										19
									
								
								src/distributions/base-models.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								src/distributions/base-models.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
				
			|||||||
 | 
					export interface NodeInputs {
 | 
				
			||||||
 | 
					  versionSpec: string;
 | 
				
			||||||
 | 
					  arch: string;
 | 
				
			||||||
 | 
					  auth?: string;
 | 
				
			||||||
 | 
					  checkLatest: boolean;
 | 
				
			||||||
 | 
					  stable: boolean;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export interface INodeVersionInfo {
 | 
				
			||||||
 | 
					  downloadUrl: string;
 | 
				
			||||||
 | 
					  resolvedVersion: string;
 | 
				
			||||||
 | 
					  arch: string;
 | 
				
			||||||
 | 
					  fileName: string;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export interface INodeVersion {
 | 
				
			||||||
 | 
					  version: string;
 | 
				
			||||||
 | 
					  files: string[];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										31
									
								
								src/distributions/installer-factory.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								src/distributions/installer-factory.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,31 @@
 | 
				
			|||||||
 | 
					import BaseDistribution from './base-distribution';
 | 
				
			||||||
 | 
					import {NodeInputs} from './base-models';
 | 
				
			||||||
 | 
					import NightlyNodejs from './nightly/nightly_builds';
 | 
				
			||||||
 | 
					import OfficialBuilds from './official_builds/official_builds';
 | 
				
			||||||
 | 
					import RcBuild from './rc/rc_builds';
 | 
				
			||||||
 | 
					import CanaryBuild from './v8-canary/canary_builds';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum Distributions {
 | 
				
			||||||
 | 
					  DEFAULT = '',
 | 
				
			||||||
 | 
					  CANARY = 'v8-canary',
 | 
				
			||||||
 | 
					  NIGHTLY = 'nightly',
 | 
				
			||||||
 | 
					  RC = 'rc'
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function getNodejsDistribution(
 | 
				
			||||||
 | 
					  installerOptions: NodeInputs
 | 
				
			||||||
 | 
					): BaseDistribution {
 | 
				
			||||||
 | 
					  const versionSpec = installerOptions.versionSpec;
 | 
				
			||||||
 | 
					  let distribution: BaseDistribution;
 | 
				
			||||||
 | 
					  if (versionSpec.includes(Distributions.NIGHTLY)) {
 | 
				
			||||||
 | 
					    distribution = new NightlyNodejs(installerOptions);
 | 
				
			||||||
 | 
					  } else if (versionSpec.includes(Distributions.CANARY)) {
 | 
				
			||||||
 | 
					    distribution = new CanaryBuild(installerOptions);
 | 
				
			||||||
 | 
					  } else if (versionSpec.includes(Distributions.RC)) {
 | 
				
			||||||
 | 
					    distribution = new RcBuild(installerOptions);
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    distribution = new OfficialBuilds(installerOptions);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return distribution;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										13
									
								
								src/distributions/nightly/nightly_builds.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								src/distributions/nightly/nightly_builds.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
				
			|||||||
 | 
					import BasePrereleaseNodejs from '../base-distribution-prerelease';
 | 
				
			||||||
 | 
					import {NodeInputs} from '../base-models';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default class NightlyNodejs extends BasePrereleaseNodejs {
 | 
				
			||||||
 | 
					  protected distribution = 'nightly';
 | 
				
			||||||
 | 
					  constructor(nodeInfo: NodeInputs) {
 | 
				
			||||||
 | 
					    super(nodeInfo);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected getDistributionUrl(): string {
 | 
				
			||||||
 | 
					    return 'https://nodejs.org/download/nightly';
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										258
									
								
								src/distributions/official_builds/official_builds.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										258
									
								
								src/distributions/official_builds/official_builds.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,258 @@
 | 
				
			|||||||
 | 
					import * as core from '@actions/core';
 | 
				
			||||||
 | 
					import * as tc from '@actions/tool-cache';
 | 
				
			||||||
 | 
					import path from 'path';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import BaseDistribution from '../base-distribution';
 | 
				
			||||||
 | 
					import {NodeInputs, INodeVersion, INodeVersionInfo} from '../base-models';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface INodeRelease extends tc.IToolRelease {
 | 
				
			||||||
 | 
					  lts?: string;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default class OfficialBuilds extends BaseDistribution {
 | 
				
			||||||
 | 
					  constructor(nodeInfo: NodeInputs) {
 | 
				
			||||||
 | 
					    super(nodeInfo);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public async setupNodeJs() {
 | 
				
			||||||
 | 
					    let manifest: tc.IToolRelease[] | undefined;
 | 
				
			||||||
 | 
					    let nodeJsVersions: INodeVersion[] | undefined;
 | 
				
			||||||
 | 
					    const osArch = this.translateArchToDistUrl(this.nodeInfo.arch);
 | 
				
			||||||
 | 
					    if (this.isLtsAlias(this.nodeInfo.versionSpec)) {
 | 
				
			||||||
 | 
					      core.info('Attempt to resolve LTS alias from manifest...');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // No try-catch since it's not possible to resolve LTS alias without manifest
 | 
				
			||||||
 | 
					      manifest = await this.getManifest();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      this.nodeInfo.versionSpec = this.resolveLtsAliasFromManifest(
 | 
				
			||||||
 | 
					        this.nodeInfo.versionSpec,
 | 
				
			||||||
 | 
					        this.nodeInfo.stable,
 | 
				
			||||||
 | 
					        manifest
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (this.isLatestSyntax(this.nodeInfo.versionSpec)) {
 | 
				
			||||||
 | 
					      nodeJsVersions = await this.getNodeJsVersions();
 | 
				
			||||||
 | 
					      const versions = this.filterVersions(nodeJsVersions);
 | 
				
			||||||
 | 
					      this.nodeInfo.versionSpec = this.evaluateVersions(versions);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      core.info('getting latest node version...');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (this.nodeInfo.checkLatest) {
 | 
				
			||||||
 | 
					      core.info('Attempt to resolve the latest version from manifest...');
 | 
				
			||||||
 | 
					      const resolvedVersion = await this.resolveVersionFromManifest(
 | 
				
			||||||
 | 
					        this.nodeInfo.versionSpec,
 | 
				
			||||||
 | 
					        this.nodeInfo.stable,
 | 
				
			||||||
 | 
					        osArch,
 | 
				
			||||||
 | 
					        manifest
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					      if (resolvedVersion) {
 | 
				
			||||||
 | 
					        this.nodeInfo.versionSpec = resolvedVersion;
 | 
				
			||||||
 | 
					        core.info(`Resolved as '${resolvedVersion}'`);
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        core.info(
 | 
				
			||||||
 | 
					          `Failed to resolve version ${this.nodeInfo.versionSpec} from manifest`
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let toolPath = this.findVersionInHostedToolCacheDirectory();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (toolPath) {
 | 
				
			||||||
 | 
					      core.info(`Found in cache @ ${toolPath}`);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      let downloadPath = '';
 | 
				
			||||||
 | 
					      try {
 | 
				
			||||||
 | 
					        core.info(`Attempting to download ${this.nodeInfo.versionSpec}...`);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const versionInfo = await this.getInfoFromManifest(
 | 
				
			||||||
 | 
					          this.nodeInfo.versionSpec,
 | 
				
			||||||
 | 
					          this.nodeInfo.stable,
 | 
				
			||||||
 | 
					          osArch,
 | 
				
			||||||
 | 
					          manifest
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        if (versionInfo) {
 | 
				
			||||||
 | 
					          core.info(
 | 
				
			||||||
 | 
					            `Acquiring ${versionInfo.resolvedVersion} - ${versionInfo.arch} from ${versionInfo.downloadUrl}`
 | 
				
			||||||
 | 
					          );
 | 
				
			||||||
 | 
					          downloadPath = await tc.downloadTool(
 | 
				
			||||||
 | 
					            versionInfo.downloadUrl,
 | 
				
			||||||
 | 
					            undefined,
 | 
				
			||||||
 | 
					            this.nodeInfo.auth
 | 
				
			||||||
 | 
					          );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          if (downloadPath) {
 | 
				
			||||||
 | 
					            toolPath = await this.extractArchive(downloadPath, versionInfo);
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					          core.info(
 | 
				
			||||||
 | 
					            'Not found in manifest. Falling back to download directly from Node'
 | 
				
			||||||
 | 
					          );
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      } catch (err) {
 | 
				
			||||||
 | 
					        // Rate limit?
 | 
				
			||||||
 | 
					        if (
 | 
				
			||||||
 | 
					          err instanceof tc.HTTPError &&
 | 
				
			||||||
 | 
					          (err.httpStatusCode === 403 || err.httpStatusCode === 429)
 | 
				
			||||||
 | 
					        ) {
 | 
				
			||||||
 | 
					          core.info(
 | 
				
			||||||
 | 
					            `Received HTTP status code ${err.httpStatusCode}. This usually indicates the rate limit has been exceeded`
 | 
				
			||||||
 | 
					          );
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					          core.info(err.message);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        core.debug(err.stack);
 | 
				
			||||||
 | 
					        core.info('Falling back to download directly from Node');
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (!toolPath) {
 | 
				
			||||||
 | 
					        const nodeJsVersions = await this.getNodeJsVersions();
 | 
				
			||||||
 | 
					        const versions = this.filterVersions(nodeJsVersions);
 | 
				
			||||||
 | 
					        const evaluatedVersion = this.evaluateVersions(versions);
 | 
				
			||||||
 | 
					        if (!evaluatedVersion) {
 | 
				
			||||||
 | 
					          throw new Error(
 | 
				
			||||||
 | 
					            `Unable to find Node version '${this.nodeInfo.versionSpec}' for platform ${this.osPlat} and architecture ${this.nodeInfo.arch}.`
 | 
				
			||||||
 | 
					          );
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        const toolName = this.getNodejsDistInfo(evaluatedVersion);
 | 
				
			||||||
 | 
					        toolPath = await this.downloadNodejs(toolName);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (this.osPlat != 'win32') {
 | 
				
			||||||
 | 
					      toolPath = path.join(toolPath, 'bin');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    core.addPath(toolPath);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected evaluateVersions(versions: string[]): string {
 | 
				
			||||||
 | 
					    let version = '';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (this.isLatestSyntax(this.nodeInfo.versionSpec)) {
 | 
				
			||||||
 | 
					      core.info(`getting latest node version...`);
 | 
				
			||||||
 | 
					      return versions[0];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    version = super.evaluateVersions(versions);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return version;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected getDistributionUrl(): string {
 | 
				
			||||||
 | 
					    return `https://nodejs.org/dist`;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private getManifest(): Promise<tc.IToolRelease[]> {
 | 
				
			||||||
 | 
					    core.debug('Getting manifest from actions/node-versions@main');
 | 
				
			||||||
 | 
					    return tc.getManifestFromRepo(
 | 
				
			||||||
 | 
					      'actions',
 | 
				
			||||||
 | 
					      'node-versions',
 | 
				
			||||||
 | 
					      this.nodeInfo.auth,
 | 
				
			||||||
 | 
					      'main'
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private resolveLtsAliasFromManifest(
 | 
				
			||||||
 | 
					    versionSpec: string,
 | 
				
			||||||
 | 
					    stable: boolean,
 | 
				
			||||||
 | 
					    manifest: INodeRelease[]
 | 
				
			||||||
 | 
					  ): string {
 | 
				
			||||||
 | 
					    const alias = versionSpec.split('lts/')[1]?.toLowerCase();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!alias) {
 | 
				
			||||||
 | 
					      throw new Error(
 | 
				
			||||||
 | 
					        `Unable to parse LTS alias for Node version '${versionSpec}'`
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    core.debug(`LTS alias '${alias}' for Node version '${versionSpec}'`);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Supported formats are `lts/<alias>`, `lts/*`, and `lts/-n`. Where asterisk means highest possible LTS and -n means the nth-highest.
 | 
				
			||||||
 | 
					    const n = Number(alias);
 | 
				
			||||||
 | 
					    const aliases = Object.fromEntries(
 | 
				
			||||||
 | 
					      manifest
 | 
				
			||||||
 | 
					        .filter(x => x.lts && x.stable === stable)
 | 
				
			||||||
 | 
					        .map(x => [x.lts!.toLowerCase(), x])
 | 
				
			||||||
 | 
					        .reverse()
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    const numbered = Object.values(aliases);
 | 
				
			||||||
 | 
					    const release =
 | 
				
			||||||
 | 
					      alias === '*'
 | 
				
			||||||
 | 
					        ? numbered[numbered.length - 1]
 | 
				
			||||||
 | 
					        : n < 0
 | 
				
			||||||
 | 
					        ? numbered[numbered.length - 1 + n]
 | 
				
			||||||
 | 
					        : aliases[alias];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!release) {
 | 
				
			||||||
 | 
					      throw new Error(
 | 
				
			||||||
 | 
					        `Unable to find LTS release '${alias}' for Node version '${versionSpec}'.`
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    core.debug(
 | 
				
			||||||
 | 
					      `Found LTS release '${release.version}' for Node version '${versionSpec}'`
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return release.version.split('.')[0];
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private async resolveVersionFromManifest(
 | 
				
			||||||
 | 
					    versionSpec: string,
 | 
				
			||||||
 | 
					    stable: boolean,
 | 
				
			||||||
 | 
					    osArch: string,
 | 
				
			||||||
 | 
					    manifest: tc.IToolRelease[] | undefined
 | 
				
			||||||
 | 
					  ): Promise<string | undefined> {
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					      const info = await this.getInfoFromManifest(
 | 
				
			||||||
 | 
					        versionSpec,
 | 
				
			||||||
 | 
					        stable,
 | 
				
			||||||
 | 
					        osArch,
 | 
				
			||||||
 | 
					        manifest
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					      return info?.resolvedVersion;
 | 
				
			||||||
 | 
					    } catch (err) {
 | 
				
			||||||
 | 
					      core.info('Unable to resolve version from manifest...');
 | 
				
			||||||
 | 
					      core.debug(err.message);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private async getInfoFromManifest(
 | 
				
			||||||
 | 
					    versionSpec: string,
 | 
				
			||||||
 | 
					    stable: boolean,
 | 
				
			||||||
 | 
					    osArch: string,
 | 
				
			||||||
 | 
					    manifest: tc.IToolRelease[] | undefined
 | 
				
			||||||
 | 
					  ): Promise<INodeVersionInfo | null> {
 | 
				
			||||||
 | 
					    let info: INodeVersionInfo | null = null;
 | 
				
			||||||
 | 
					    if (!manifest) {
 | 
				
			||||||
 | 
					      core.debug('No manifest cached');
 | 
				
			||||||
 | 
					      manifest = await this.getManifest();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const rel = await tc.findFromManifest(
 | 
				
			||||||
 | 
					      versionSpec,
 | 
				
			||||||
 | 
					      stable,
 | 
				
			||||||
 | 
					      manifest,
 | 
				
			||||||
 | 
					      osArch
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (rel && rel.files.length > 0) {
 | 
				
			||||||
 | 
					      info = <INodeVersionInfo>{};
 | 
				
			||||||
 | 
					      info.resolvedVersion = rel.version;
 | 
				
			||||||
 | 
					      info.arch = rel.files[0].arch;
 | 
				
			||||||
 | 
					      info.downloadUrl = rel.files[0].download_url;
 | 
				
			||||||
 | 
					      info.fileName = rel.files[0].filename;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return info;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private isLtsAlias(versionSpec: string): boolean {
 | 
				
			||||||
 | 
					    return versionSpec.startsWith('lts/');
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private isLatestSyntax(versionSpec): boolean {
 | 
				
			||||||
 | 
					    return ['current', 'latest', 'node'].includes(versionSpec);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										12
									
								
								src/distributions/rc/rc_builds.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/distributions/rc/rc_builds.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
				
			|||||||
 | 
					import BaseDistribution from '../base-distribution';
 | 
				
			||||||
 | 
					import {NodeInputs} from '../base-models';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default class RcBuild extends BaseDistribution {
 | 
				
			||||||
 | 
					  constructor(nodeInfo: NodeInputs) {
 | 
				
			||||||
 | 
					    super(nodeInfo);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  getDistributionUrl(): string {
 | 
				
			||||||
 | 
					    return 'https://nodejs.org/download/rc';
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										13
									
								
								src/distributions/v8-canary/canary_builds.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								src/distributions/v8-canary/canary_builds.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
				
			|||||||
 | 
					import BasePrereleaseNodejs from '../base-distribution-prerelease';
 | 
				
			||||||
 | 
					import {NodeInputs} from '../base-models';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default class CanaryBuild extends BasePrereleaseNodejs {
 | 
				
			||||||
 | 
					  protected distribution = 'v8-canary';
 | 
				
			||||||
 | 
					  constructor(nodeInfo: NodeInputs) {
 | 
				
			||||||
 | 
					    super(nodeInfo);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected getDistributionUrl(): string {
 | 
				
			||||||
 | 
					    return 'https://nodejs.org/download/v8-canary';
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										606
									
								
								src/installer.ts
									
									
									
									
									
								
							
							
						
						
									
										606
									
								
								src/installer.ts
									
									
									
									
									
								
							@@ -1,606 +0,0 @@
 | 
				
			|||||||
import os from 'os';
 | 
					 | 
				
			||||||
import * as assert from 'assert';
 | 
					 | 
				
			||||||
import * as core from '@actions/core';
 | 
					 | 
				
			||||||
import * as hc from '@actions/http-client';
 | 
					 | 
				
			||||||
import * as io from '@actions/io';
 | 
					 | 
				
			||||||
import * as tc from '@actions/tool-cache';
 | 
					 | 
				
			||||||
import * as path from 'path';
 | 
					 | 
				
			||||||
import * as semver from 'semver';
 | 
					 | 
				
			||||||
import fs from 'fs';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Node versions interface
 | 
					 | 
				
			||||||
// see https://nodejs.org/dist/index.json
 | 
					 | 
				
			||||||
// for nightly https://nodejs.org/download/nightly/index.json
 | 
					 | 
				
			||||||
// for rc https://nodejs.org/download/rc/index.json
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
export interface INodeVersion {
 | 
					 | 
				
			||||||
  version: string;
 | 
					 | 
				
			||||||
  files: string[];
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
interface INodeVersionInfo {
 | 
					 | 
				
			||||||
  downloadUrl: string;
 | 
					 | 
				
			||||||
  resolvedVersion: string;
 | 
					 | 
				
			||||||
  arch: string;
 | 
					 | 
				
			||||||
  fileName: string;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
interface INodeRelease extends tc.IToolRelease {
 | 
					 | 
				
			||||||
  lts?: string;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export async function getNode(
 | 
					 | 
				
			||||||
  versionSpec: string,
 | 
					 | 
				
			||||||
  stable: boolean,
 | 
					 | 
				
			||||||
  checkLatest: boolean,
 | 
					 | 
				
			||||||
  auth: string | undefined,
 | 
					 | 
				
			||||||
  arch: string = os.arch()
 | 
					 | 
				
			||||||
) {
 | 
					 | 
				
			||||||
  // Store manifest data to avoid multiple calls
 | 
					 | 
				
			||||||
  let manifest: INodeRelease[] | undefined;
 | 
					 | 
				
			||||||
  let nodeVersions: INodeVersion[] | undefined;
 | 
					 | 
				
			||||||
  let isNightly = versionSpec.includes('nightly');
 | 
					 | 
				
			||||||
  let osPlat: string = os.platform();
 | 
					 | 
				
			||||||
  let osArch: string = translateArchToDistUrl(arch);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (isLtsAlias(versionSpec)) {
 | 
					 | 
				
			||||||
    core.info('Attempt to resolve LTS alias from manifest...');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // No try-catch since it's not possible to resolve LTS alias without manifest
 | 
					 | 
				
			||||||
    manifest = await getManifest(auth);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    versionSpec = resolveLtsAliasFromManifest(versionSpec, stable, manifest);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (isLatestSyntax(versionSpec)) {
 | 
					 | 
				
			||||||
    nodeVersions = await getVersionsFromDist(versionSpec);
 | 
					 | 
				
			||||||
    versionSpec = await queryDistForMatch(versionSpec, arch, nodeVersions);
 | 
					 | 
				
			||||||
    core.info(`getting latest node version...`);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (isNightly && checkLatest) {
 | 
					 | 
				
			||||||
    nodeVersions = await getVersionsFromDist(versionSpec);
 | 
					 | 
				
			||||||
    versionSpec = await queryDistForMatch(versionSpec, arch, nodeVersions);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (checkLatest && !isNightly) {
 | 
					 | 
				
			||||||
    core.info('Attempt to resolve the latest version from manifest...');
 | 
					 | 
				
			||||||
    const resolvedVersion = await resolveVersionFromManifest(
 | 
					 | 
				
			||||||
      versionSpec,
 | 
					 | 
				
			||||||
      stable,
 | 
					 | 
				
			||||||
      auth,
 | 
					 | 
				
			||||||
      osArch,
 | 
					 | 
				
			||||||
      manifest
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
    if (resolvedVersion) {
 | 
					 | 
				
			||||||
      versionSpec = resolvedVersion;
 | 
					 | 
				
			||||||
      core.info(`Resolved as '${versionSpec}'`);
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      core.info(`Failed to resolve version ${versionSpec} from manifest`);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // check cache
 | 
					 | 
				
			||||||
  let toolPath: string;
 | 
					 | 
				
			||||||
  if (isNightly) {
 | 
					 | 
				
			||||||
    const nightlyVersion = findNightlyVersionInHostedToolcache(
 | 
					 | 
				
			||||||
      versionSpec,
 | 
					 | 
				
			||||||
      osArch
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
    toolPath = nightlyVersion && tc.find('node', nightlyVersion, osArch);
 | 
					 | 
				
			||||||
  } else {
 | 
					 | 
				
			||||||
    toolPath = tc.find('node', versionSpec, osArch);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // If not found in cache, download
 | 
					 | 
				
			||||||
  if (toolPath) {
 | 
					 | 
				
			||||||
    core.info(`Found in cache @ ${toolPath}`);
 | 
					 | 
				
			||||||
  } else {
 | 
					 | 
				
			||||||
    core.info(`Attempting to download ${versionSpec}...`);
 | 
					 | 
				
			||||||
    let downloadPath = '';
 | 
					 | 
				
			||||||
    let info: INodeVersionInfo | null = null;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    //
 | 
					 | 
				
			||||||
    // Try download from internal distribution (popular versions only)
 | 
					 | 
				
			||||||
    //
 | 
					 | 
				
			||||||
    try {
 | 
					 | 
				
			||||||
      info = await getInfoFromManifest(
 | 
					 | 
				
			||||||
        versionSpec,
 | 
					 | 
				
			||||||
        stable,
 | 
					 | 
				
			||||||
        auth,
 | 
					 | 
				
			||||||
        osArch,
 | 
					 | 
				
			||||||
        manifest
 | 
					 | 
				
			||||||
      );
 | 
					 | 
				
			||||||
      if (info) {
 | 
					 | 
				
			||||||
        core.info(
 | 
					 | 
				
			||||||
          `Acquiring ${info.resolvedVersion} - ${info.arch} from ${info.downloadUrl}`
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
        downloadPath = await tc.downloadTool(info.downloadUrl, undefined, auth);
 | 
					 | 
				
			||||||
      } else {
 | 
					 | 
				
			||||||
        core.info(
 | 
					 | 
				
			||||||
          'Not found in manifest.  Falling back to download directly from Node'
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    } catch (err) {
 | 
					 | 
				
			||||||
      // Rate limit?
 | 
					 | 
				
			||||||
      if (
 | 
					 | 
				
			||||||
        err instanceof tc.HTTPError &&
 | 
					 | 
				
			||||||
        (err.httpStatusCode === 403 || err.httpStatusCode === 429)
 | 
					 | 
				
			||||||
      ) {
 | 
					 | 
				
			||||||
        core.info(
 | 
					 | 
				
			||||||
          `Received HTTP status code ${err.httpStatusCode}.  This usually indicates the rate limit has been exceeded`
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
      } else {
 | 
					 | 
				
			||||||
        core.info(err.message);
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      core.debug(err.stack);
 | 
					 | 
				
			||||||
      core.info('Falling back to download directly from Node');
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    //
 | 
					 | 
				
			||||||
    // Download from nodejs.org
 | 
					 | 
				
			||||||
    //
 | 
					 | 
				
			||||||
    if (!downloadPath) {
 | 
					 | 
				
			||||||
      info = await getInfoFromDist(versionSpec, arch, nodeVersions);
 | 
					 | 
				
			||||||
      if (!info) {
 | 
					 | 
				
			||||||
        throw new Error(
 | 
					 | 
				
			||||||
          `Unable to find Node version '${versionSpec}' for platform ${osPlat} and architecture ${osArch}.`
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      core.info(
 | 
					 | 
				
			||||||
        `Acquiring ${info.resolvedVersion} - ${info.arch} from ${info.downloadUrl}`
 | 
					 | 
				
			||||||
      );
 | 
					 | 
				
			||||||
      try {
 | 
					 | 
				
			||||||
        downloadPath = await tc.downloadTool(info.downloadUrl);
 | 
					 | 
				
			||||||
      } catch (err) {
 | 
					 | 
				
			||||||
        if (err instanceof tc.HTTPError && err.httpStatusCode == 404) {
 | 
					 | 
				
			||||||
          return await acquireNodeFromFallbackLocation(
 | 
					 | 
				
			||||||
            info.resolvedVersion,
 | 
					 | 
				
			||||||
            info.arch
 | 
					 | 
				
			||||||
          );
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        throw err;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    //
 | 
					 | 
				
			||||||
    // Extract
 | 
					 | 
				
			||||||
    //
 | 
					 | 
				
			||||||
    core.info('Extracting ...');
 | 
					 | 
				
			||||||
    let extPath: string;
 | 
					 | 
				
			||||||
    info = info || ({} as INodeVersionInfo); // satisfy compiler, never null when reaches here
 | 
					 | 
				
			||||||
    if (osPlat == 'win32') {
 | 
					 | 
				
			||||||
      let _7zPath = path.join(__dirname, '../..', 'externals', '7zr.exe');
 | 
					 | 
				
			||||||
      extPath = await tc.extract7z(downloadPath, undefined, _7zPath);
 | 
					 | 
				
			||||||
      // 7z extracts to folder matching file name
 | 
					 | 
				
			||||||
      let nestedPath = path.join(extPath, path.basename(info.fileName, '.7z'));
 | 
					 | 
				
			||||||
      if (fs.existsSync(nestedPath)) {
 | 
					 | 
				
			||||||
        extPath = nestedPath;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      extPath = await tc.extractTar(downloadPath, undefined, [
 | 
					 | 
				
			||||||
        'xz',
 | 
					 | 
				
			||||||
        '--strip',
 | 
					 | 
				
			||||||
        '1'
 | 
					 | 
				
			||||||
      ]);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    //
 | 
					 | 
				
			||||||
    // Install into the local tool cache - node extracts with a root folder that matches the fileName downloaded
 | 
					 | 
				
			||||||
    //
 | 
					 | 
				
			||||||
    core.info('Adding to the cache ...');
 | 
					 | 
				
			||||||
    toolPath = await tc.cacheDir(
 | 
					 | 
				
			||||||
      extPath,
 | 
					 | 
				
			||||||
      'node',
 | 
					 | 
				
			||||||
      info.resolvedVersion,
 | 
					 | 
				
			||||||
      info.arch
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
    core.info('Done');
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  //
 | 
					 | 
				
			||||||
  // a tool installer initimately knows details about the layout of that tool
 | 
					 | 
				
			||||||
  // for example, node binary is in the bin folder after the extract on Mac/Linux.
 | 
					 | 
				
			||||||
  // layouts could change by version, by platform etc... but that's the tool installers job
 | 
					 | 
				
			||||||
  //
 | 
					 | 
				
			||||||
  if (osPlat != 'win32') {
 | 
					 | 
				
			||||||
    toolPath = path.join(toolPath, 'bin');
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  //
 | 
					 | 
				
			||||||
  // prepend the tools path. instructs the agent to prepend for future tasks
 | 
					 | 
				
			||||||
  core.addPath(toolPath);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function findNightlyVersionInHostedToolcache(
 | 
					 | 
				
			||||||
  versionsSpec: string,
 | 
					 | 
				
			||||||
  osArch: string
 | 
					 | 
				
			||||||
) {
 | 
					 | 
				
			||||||
  const foundAllVersions = tc.findAllVersions('node', osArch);
 | 
					 | 
				
			||||||
  const version = evaluateVersions(foundAllVersions, versionsSpec);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  return version;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function isLtsAlias(versionSpec: string): boolean {
 | 
					 | 
				
			||||||
  return versionSpec.startsWith('lts/');
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function getManifest(auth: string | undefined): Promise<tc.IToolRelease[]> {
 | 
					 | 
				
			||||||
  core.debug('Getting manifest from actions/node-versions@main');
 | 
					 | 
				
			||||||
  return tc.getManifestFromRepo('actions', 'node-versions', auth, 'main');
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function resolveLtsAliasFromManifest(
 | 
					 | 
				
			||||||
  versionSpec: string,
 | 
					 | 
				
			||||||
  stable: boolean,
 | 
					 | 
				
			||||||
  manifest: INodeRelease[]
 | 
					 | 
				
			||||||
): string {
 | 
					 | 
				
			||||||
  const alias = versionSpec.split('lts/')[1]?.toLowerCase();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (!alias) {
 | 
					 | 
				
			||||||
    throw new Error(
 | 
					 | 
				
			||||||
      `Unable to parse LTS alias for Node version '${versionSpec}'`
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  core.debug(`LTS alias '${alias}' for Node version '${versionSpec}'`);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Supported formats are `lts/<alias>`, `lts/*`, and `lts/-n`. Where asterisk means highest possible LTS and -n means the nth-highest.
 | 
					 | 
				
			||||||
  const n = Number(alias);
 | 
					 | 
				
			||||||
  const aliases = Object.fromEntries(
 | 
					 | 
				
			||||||
    manifest
 | 
					 | 
				
			||||||
      .filter(x => x.lts && x.stable === stable)
 | 
					 | 
				
			||||||
      .map(x => [x.lts!.toLowerCase(), x])
 | 
					 | 
				
			||||||
      .reverse()
 | 
					 | 
				
			||||||
  );
 | 
					 | 
				
			||||||
  const numbered = Object.values(aliases);
 | 
					 | 
				
			||||||
  const release =
 | 
					 | 
				
			||||||
    alias === '*'
 | 
					 | 
				
			||||||
      ? numbered[numbered.length - 1]
 | 
					 | 
				
			||||||
      : n < 0
 | 
					 | 
				
			||||||
      ? numbered[numbered.length - 1 + n]
 | 
					 | 
				
			||||||
      : aliases[alias];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (!release) {
 | 
					 | 
				
			||||||
    throw new Error(
 | 
					 | 
				
			||||||
      `Unable to find LTS release '${alias}' for Node version '${versionSpec}'.`
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  core.debug(
 | 
					 | 
				
			||||||
    `Found LTS release '${release.version}' for Node version '${versionSpec}'`
 | 
					 | 
				
			||||||
  );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  return release.version.split('.')[0];
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
async function getInfoFromManifest(
 | 
					 | 
				
			||||||
  versionSpec: string,
 | 
					 | 
				
			||||||
  stable: boolean,
 | 
					 | 
				
			||||||
  auth: string | undefined,
 | 
					 | 
				
			||||||
  osArch: string = translateArchToDistUrl(os.arch()),
 | 
					 | 
				
			||||||
  manifest: tc.IToolRelease[] | undefined
 | 
					 | 
				
			||||||
): Promise<INodeVersionInfo | null> {
 | 
					 | 
				
			||||||
  let info: INodeVersionInfo | null = null;
 | 
					 | 
				
			||||||
  if (!manifest) {
 | 
					 | 
				
			||||||
    core.debug('No manifest cached');
 | 
					 | 
				
			||||||
    manifest = await getManifest(auth);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const rel = await tc.findFromManifest(versionSpec, stable, manifest, osArch);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (rel && rel.files.length > 0) {
 | 
					 | 
				
			||||||
    info = <INodeVersionInfo>{};
 | 
					 | 
				
			||||||
    info.resolvedVersion = rel.version;
 | 
					 | 
				
			||||||
    info.arch = rel.files[0].arch;
 | 
					 | 
				
			||||||
    info.downloadUrl = rel.files[0].download_url;
 | 
					 | 
				
			||||||
    info.fileName = rel.files[0].filename;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  return info;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
async function getInfoFromDist(
 | 
					 | 
				
			||||||
  versionSpec: string,
 | 
					 | 
				
			||||||
  arch: string = os.arch(),
 | 
					 | 
				
			||||||
  nodeVersions?: INodeVersion[]
 | 
					 | 
				
			||||||
): Promise<INodeVersionInfo | null> {
 | 
					 | 
				
			||||||
  let osPlat: string = os.platform();
 | 
					 | 
				
			||||||
  let osArch: string = translateArchToDistUrl(arch);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  let version: string = await queryDistForMatch(
 | 
					 | 
				
			||||||
    versionSpec,
 | 
					 | 
				
			||||||
    arch,
 | 
					 | 
				
			||||||
    nodeVersions
 | 
					 | 
				
			||||||
  );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (!version) {
 | 
					 | 
				
			||||||
    return null;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  //
 | 
					 | 
				
			||||||
  // Download - a tool installer intimately knows how to get the tool (and construct urls)
 | 
					 | 
				
			||||||
  //
 | 
					 | 
				
			||||||
  version = semver.clean(version) || '';
 | 
					 | 
				
			||||||
  let fileName: string =
 | 
					 | 
				
			||||||
    osPlat == 'win32'
 | 
					 | 
				
			||||||
      ? `node-v${version}-win-${osArch}`
 | 
					 | 
				
			||||||
      : `node-v${version}-${osPlat}-${osArch}`;
 | 
					 | 
				
			||||||
  let urlFileName: string =
 | 
					 | 
				
			||||||
    osPlat == 'win32' ? `${fileName}.7z` : `${fileName}.tar.gz`;
 | 
					 | 
				
			||||||
  const initialUrl = getNodejsDistUrl(versionSpec);
 | 
					 | 
				
			||||||
  const url = `${initialUrl}/v${version}/${urlFileName}`;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  return <INodeVersionInfo>{
 | 
					 | 
				
			||||||
    downloadUrl: url,
 | 
					 | 
				
			||||||
    resolvedVersion: version,
 | 
					 | 
				
			||||||
    arch: arch,
 | 
					 | 
				
			||||||
    fileName: fileName
 | 
					 | 
				
			||||||
  };
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
async function resolveVersionFromManifest(
 | 
					 | 
				
			||||||
  versionSpec: string,
 | 
					 | 
				
			||||||
  stable: boolean,
 | 
					 | 
				
			||||||
  auth: string | undefined,
 | 
					 | 
				
			||||||
  osArch: string = translateArchToDistUrl(os.arch()),
 | 
					 | 
				
			||||||
  manifest: tc.IToolRelease[] | undefined
 | 
					 | 
				
			||||||
): Promise<string | undefined> {
 | 
					 | 
				
			||||||
  try {
 | 
					 | 
				
			||||||
    const info = await getInfoFromManifest(
 | 
					 | 
				
			||||||
      versionSpec,
 | 
					 | 
				
			||||||
      stable,
 | 
					 | 
				
			||||||
      auth,
 | 
					 | 
				
			||||||
      osArch,
 | 
					 | 
				
			||||||
      manifest
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
    return info?.resolvedVersion;
 | 
					 | 
				
			||||||
  } catch (err) {
 | 
					 | 
				
			||||||
    core.info('Unable to resolve version from manifest...');
 | 
					 | 
				
			||||||
    core.debug(err.message);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function evaluateNightlyVersions(
 | 
					 | 
				
			||||||
  versions: string[],
 | 
					 | 
				
			||||||
  versionSpec: string
 | 
					 | 
				
			||||||
): string {
 | 
					 | 
				
			||||||
  let version = '';
 | 
					 | 
				
			||||||
  let range: string | undefined;
 | 
					 | 
				
			||||||
  const [raw, prerelease] = versionSpec.split('-');
 | 
					 | 
				
			||||||
  const isValidVersion = semver.valid(raw);
 | 
					 | 
				
			||||||
  const rawVersion = isValidVersion ? raw : semver.coerce(raw);
 | 
					 | 
				
			||||||
  if (rawVersion) {
 | 
					 | 
				
			||||||
    if (prerelease !== 'nightly') {
 | 
					 | 
				
			||||||
      range = `${rawVersion}-${prerelease.replace('nightly', 'nightly.')}`;
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      range = `${semver.validRange(`^${rawVersion}-0`)}-0`;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (range) {
 | 
					 | 
				
			||||||
    versions.sort(semver.rcompare);
 | 
					 | 
				
			||||||
    for (const currentVersion of versions) {
 | 
					 | 
				
			||||||
      const satisfied: boolean =
 | 
					 | 
				
			||||||
        semver.satisfies(
 | 
					 | 
				
			||||||
          currentVersion.replace('-nightly', '-nightly.'),
 | 
					 | 
				
			||||||
          range,
 | 
					 | 
				
			||||||
          {includePrerelease: true}
 | 
					 | 
				
			||||||
        ) && currentVersion.includes('nightly');
 | 
					 | 
				
			||||||
      if (satisfied) {
 | 
					 | 
				
			||||||
        version = currentVersion;
 | 
					 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (version) {
 | 
					 | 
				
			||||||
    core.debug(`matched: ${version}`);
 | 
					 | 
				
			||||||
  } else {
 | 
					 | 
				
			||||||
    core.debug('match not found');
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  return version;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// TODO - should we just export this from @actions/tool-cache? Lifted directly from there
 | 
					 | 
				
			||||||
function evaluateVersions(versions: string[], versionSpec: string): string {
 | 
					 | 
				
			||||||
  let version = '';
 | 
					 | 
				
			||||||
  core.debug(`evaluating ${versions.length} versions`);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (versionSpec.includes('nightly')) {
 | 
					 | 
				
			||||||
    return evaluateNightlyVersions(versions, versionSpec);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  versions = versions.sort(semver.rcompare);
 | 
					 | 
				
			||||||
  for (let i = versions.length - 1; i >= 0; i--) {
 | 
					 | 
				
			||||||
    const potential: string = versions[i];
 | 
					 | 
				
			||||||
    const satisfied: boolean = semver.satisfies(potential, versionSpec);
 | 
					 | 
				
			||||||
    if (satisfied) {
 | 
					 | 
				
			||||||
      version = potential;
 | 
					 | 
				
			||||||
      break;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (version) {
 | 
					 | 
				
			||||||
    core.debug(`matched: ${version}`);
 | 
					 | 
				
			||||||
  } else {
 | 
					 | 
				
			||||||
    core.debug('match not found');
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  return version;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export function getNodejsDistUrl(version: string) {
 | 
					 | 
				
			||||||
  const prerelease = semver.prerelease(version);
 | 
					 | 
				
			||||||
  if (version.includes('nightly')) {
 | 
					 | 
				
			||||||
    return 'https://nodejs.org/download/nightly';
 | 
					 | 
				
			||||||
  } else if (prerelease) {
 | 
					 | 
				
			||||||
    return 'https://nodejs.org/download/rc';
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  return 'https://nodejs.org/dist';
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
async function queryDistForMatch(
 | 
					 | 
				
			||||||
  versionSpec: string,
 | 
					 | 
				
			||||||
  arch: string = os.arch(),
 | 
					 | 
				
			||||||
  nodeVersions?: INodeVersion[]
 | 
					 | 
				
			||||||
): Promise<string> {
 | 
					 | 
				
			||||||
  let osPlat: string = os.platform();
 | 
					 | 
				
			||||||
  let osArch: string = translateArchToDistUrl(arch);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // node offers a json list of versions
 | 
					 | 
				
			||||||
  let dataFileName: string;
 | 
					 | 
				
			||||||
  switch (osPlat) {
 | 
					 | 
				
			||||||
    case 'linux':
 | 
					 | 
				
			||||||
      dataFileName = `linux-${osArch}`;
 | 
					 | 
				
			||||||
      break;
 | 
					 | 
				
			||||||
    case 'darwin':
 | 
					 | 
				
			||||||
      dataFileName = `osx-${osArch}-tar`;
 | 
					 | 
				
			||||||
      break;
 | 
					 | 
				
			||||||
    case 'win32':
 | 
					 | 
				
			||||||
      dataFileName = `win-${osArch}-exe`;
 | 
					 | 
				
			||||||
      break;
 | 
					 | 
				
			||||||
    default:
 | 
					 | 
				
			||||||
      throw new Error(`Unexpected OS '${osPlat}'`);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (!nodeVersions) {
 | 
					 | 
				
			||||||
    core.debug('No dist manifest cached');
 | 
					 | 
				
			||||||
    nodeVersions = await getVersionsFromDist(versionSpec);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  let versions: string[] = [];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (isLatestSyntax(versionSpec)) {
 | 
					 | 
				
			||||||
    core.info(`getting latest node version...`);
 | 
					 | 
				
			||||||
    return nodeVersions[0].version;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  nodeVersions.forEach((nodeVersion: INodeVersion) => {
 | 
					 | 
				
			||||||
    // ensure this version supports your os and platform
 | 
					 | 
				
			||||||
    if (nodeVersion.files.indexOf(dataFileName) >= 0) {
 | 
					 | 
				
			||||||
      versions.push(nodeVersion.version);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // get the latest version that matches the version spec
 | 
					 | 
				
			||||||
  let version = evaluateVersions(versions, versionSpec);
 | 
					 | 
				
			||||||
  return version;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export async function getVersionsFromDist(
 | 
					 | 
				
			||||||
  versionSpec: string
 | 
					 | 
				
			||||||
): Promise<INodeVersion[]> {
 | 
					 | 
				
			||||||
  const initialUrl = getNodejsDistUrl(versionSpec);
 | 
					 | 
				
			||||||
  const dataUrl = `${initialUrl}/index.json`;
 | 
					 | 
				
			||||||
  let httpClient = new hc.HttpClient('setup-node', [], {
 | 
					 | 
				
			||||||
    allowRetries: true,
 | 
					 | 
				
			||||||
    maxRetries: 3
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
  let response = await httpClient.getJson<INodeVersion[]>(dataUrl);
 | 
					 | 
				
			||||||
  return response.result || [];
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// For non LTS versions of Node, the files we need (for Windows) are sometimes located
 | 
					 | 
				
			||||||
// in a different folder than they normally are for other versions.
 | 
					 | 
				
			||||||
// Normally the format is similar to: https://nodejs.org/dist/v5.10.1/node-v5.10.1-win-x64.7z
 | 
					 | 
				
			||||||
// In this case, there will be two files located at:
 | 
					 | 
				
			||||||
//      /dist/v5.10.1/win-x64/node.exe
 | 
					 | 
				
			||||||
//      /dist/v5.10.1/win-x64/node.lib
 | 
					 | 
				
			||||||
// If this is not the structure, there may also be two files located at:
 | 
					 | 
				
			||||||
//      /dist/v0.12.18/node.exe
 | 
					 | 
				
			||||||
//      /dist/v0.12.18/node.lib
 | 
					 | 
				
			||||||
// This method attempts to download and cache the resources from these alternative locations.
 | 
					 | 
				
			||||||
// Note also that the files are normally zipped but in this case they are just an exe
 | 
					 | 
				
			||||||
// and lib file in a folder, not zipped.
 | 
					 | 
				
			||||||
async function acquireNodeFromFallbackLocation(
 | 
					 | 
				
			||||||
  version: string,
 | 
					 | 
				
			||||||
  arch: string = os.arch()
 | 
					 | 
				
			||||||
): Promise<string> {
 | 
					 | 
				
			||||||
  const initialUrl = getNodejsDistUrl(version);
 | 
					 | 
				
			||||||
  let osPlat: string = os.platform();
 | 
					 | 
				
			||||||
  let osArch: string = translateArchToDistUrl(arch);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Create temporary folder to download in to
 | 
					 | 
				
			||||||
  const tempDownloadFolder: string =
 | 
					 | 
				
			||||||
    'temp_' + Math.floor(Math.random() * 2000000000);
 | 
					 | 
				
			||||||
  const tempDirectory = process.env['RUNNER_TEMP'] || '';
 | 
					 | 
				
			||||||
  assert.ok(tempDirectory, 'Expected RUNNER_TEMP to be defined');
 | 
					 | 
				
			||||||
  const tempDir: string = path.join(tempDirectory, tempDownloadFolder);
 | 
					 | 
				
			||||||
  await io.mkdirP(tempDir);
 | 
					 | 
				
			||||||
  let exeUrl: string;
 | 
					 | 
				
			||||||
  let libUrl: string;
 | 
					 | 
				
			||||||
  try {
 | 
					 | 
				
			||||||
    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 = await tc.downloadTool(exeUrl);
 | 
					 | 
				
			||||||
    await io.cp(exePath, path.join(tempDir, 'node.exe'));
 | 
					 | 
				
			||||||
    const libPath = await tc.downloadTool(libUrl);
 | 
					 | 
				
			||||||
    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);
 | 
					 | 
				
			||||||
      await io.cp(exePath, path.join(tempDir, 'node.exe'));
 | 
					 | 
				
			||||||
      const libPath = await tc.downloadTool(libUrl);
 | 
					 | 
				
			||||||
      await io.cp(libPath, path.join(tempDir, 'node.lib'));
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      throw err;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  let toolPath = await tc.cacheDir(tempDir, 'node', version, arch);
 | 
					 | 
				
			||||||
  core.addPath(toolPath);
 | 
					 | 
				
			||||||
  return toolPath;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// os.arch does not always match the relative download url, e.g.
 | 
					 | 
				
			||||||
// os.arch == 'arm' != node-v12.13.1-linux-armv7l.tar.gz
 | 
					 | 
				
			||||||
// All other currently supported architectures match, e.g.:
 | 
					 | 
				
			||||||
//   os.arch = arm64 => https://nodejs.org/dist/v{VERSION}/node-v{VERSION}-{OS}-arm64.tar.gz
 | 
					 | 
				
			||||||
//   os.arch = x64 => https://nodejs.org/dist/v{VERSION}/node-v{VERSION}-{OS}-x64.tar.gz
 | 
					 | 
				
			||||||
function translateArchToDistUrl(arch: string): string {
 | 
					 | 
				
			||||||
  switch (arch) {
 | 
					 | 
				
			||||||
    case 'arm':
 | 
					 | 
				
			||||||
      return 'armv7l';
 | 
					 | 
				
			||||||
    default:
 | 
					 | 
				
			||||||
      return arch;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export function parseNodeVersionFile(contents: string): string {
 | 
					 | 
				
			||||||
  let nodeVersion: string | undefined;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Try parsing the file as an NPM `package.json` file.
 | 
					 | 
				
			||||||
  try {
 | 
					 | 
				
			||||||
    nodeVersion = JSON.parse(contents).volta?.node;
 | 
					 | 
				
			||||||
    if (!nodeVersion) nodeVersion = JSON.parse(contents).engines?.node;
 | 
					 | 
				
			||||||
  } catch {
 | 
					 | 
				
			||||||
    core.info('Node version file is not JSON file');
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (!nodeVersion) {
 | 
					 | 
				
			||||||
    const found = contents.match(/^(?:nodejs\s+)?v?(?<version>[^\s]+)$/m);
 | 
					 | 
				
			||||||
    nodeVersion = found?.groups?.version;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // In the case of an unknown format,
 | 
					 | 
				
			||||||
  // return as is and evaluate the version separately.
 | 
					 | 
				
			||||||
  if (!nodeVersion) nodeVersion = contents.trim();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  return nodeVersion as string;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function isLatestSyntax(versionSpec): boolean {
 | 
					 | 
				
			||||||
  return ['current', 'latest', 'node'].includes(versionSpec);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										60
									
								
								src/main.ts
									
									
									
									
									
								
							
							
						
						
									
										60
									
								
								src/main.ts
									
									
									
									
									
								
							@@ -1,12 +1,14 @@
 | 
				
			|||||||
import * as core from '@actions/core';
 | 
					import * as core from '@actions/core';
 | 
				
			||||||
import * as exec from '@actions/exec';
 | 
					
 | 
				
			||||||
import * as installer from './installer';
 | 
					 | 
				
			||||||
import fs from 'fs';
 | 
					import fs from 'fs';
 | 
				
			||||||
 | 
					import os from 'os';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import * as auth from './authutil';
 | 
					import * as auth from './authutil';
 | 
				
			||||||
import * as path from 'path';
 | 
					import * as path from 'path';
 | 
				
			||||||
import {restoreCache} from './cache-restore';
 | 
					import {restoreCache} from './cache-restore';
 | 
				
			||||||
import {isGhes, isCacheFeatureAvailable} from './cache-utils';
 | 
					import {isCacheFeatureAvailable} from './cache-utils';
 | 
				
			||||||
import os from 'os';
 | 
					import {getNodejsDistribution} from './distributions/installer-factory';
 | 
				
			||||||
 | 
					import {parseNodeVersionFile, printEnvDetailsAndSetOutput} from './util';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export async function run() {
 | 
					export async function run() {
 | 
				
			||||||
  try {
 | 
					  try {
 | 
				
			||||||
@@ -38,7 +40,15 @@ export async function run() {
 | 
				
			|||||||
        (core.getInput('stable') || 'true').toUpperCase() === 'TRUE';
 | 
					        (core.getInput('stable') || 'true').toUpperCase() === 'TRUE';
 | 
				
			||||||
      const checkLatest =
 | 
					      const checkLatest =
 | 
				
			||||||
        (core.getInput('check-latest') || 'false').toUpperCase() === 'TRUE';
 | 
					        (core.getInput('check-latest') || 'false').toUpperCase() === 'TRUE';
 | 
				
			||||||
      await installer.getNode(version, stable, checkLatest, auth, arch);
 | 
					      const nodejsInfo = {
 | 
				
			||||||
 | 
					        versionSpec: version,
 | 
				
			||||||
 | 
					        checkLatest,
 | 
				
			||||||
 | 
					        auth,
 | 
				
			||||||
 | 
					        stable,
 | 
				
			||||||
 | 
					        arch
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					      const nodeDistribution = getNodejsDistribution(nodejsInfo);
 | 
				
			||||||
 | 
					      await nodeDistribution.setupNodeJs();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    await printEnvDetailsAndSetOutput();
 | 
					    await printEnvDetailsAndSetOutput();
 | 
				
			||||||
@@ -93,48 +103,10 @@ function resolveVersionInput(): string {
 | 
				
			|||||||
      );
 | 
					      );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    version = installer.parseNodeVersionFile(
 | 
					    version = parseNodeVersionFile(fs.readFileSync(versionFilePath, 'utf8'));
 | 
				
			||||||
      fs.readFileSync(versionFilePath, 'utf8')
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    core.info(`Resolved ${versionFileInput} as ${version}`);
 | 
					    core.info(`Resolved ${versionFileInput} as ${version}`);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return version;
 | 
					  return version;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
export async function printEnvDetailsAndSetOutput() {
 | 
					 | 
				
			||||||
  core.startGroup('Environment details');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const promises = ['node', 'npm', 'yarn'].map(async tool => {
 | 
					 | 
				
			||||||
    const output = await getToolVersion(tool, ['--version']);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (tool === 'node') {
 | 
					 | 
				
			||||||
      core.setOutput(`${tool}-version`, output);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    core.info(`${tool}: ${output}`);
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  await Promise.all(promises);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  core.endGroup();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
async function getToolVersion(tool: string, options: string[]) {
 | 
					 | 
				
			||||||
  try {
 | 
					 | 
				
			||||||
    const {stdout, stderr, exitCode} = await exec.getExecOutput(tool, options, {
 | 
					 | 
				
			||||||
      ignoreReturnCode: true,
 | 
					 | 
				
			||||||
      silent: true
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (exitCode > 0) {
 | 
					 | 
				
			||||||
      core.warning(`[warning]${stderr}`);
 | 
					 | 
				
			||||||
      return '';
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return stdout.trim();
 | 
					 | 
				
			||||||
  } catch (err) {
 | 
					 | 
				
			||||||
    return '';
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										63
									
								
								src/util.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								src/util.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,63 @@
 | 
				
			|||||||
 | 
					import * as core from '@actions/core';
 | 
				
			||||||
 | 
					import * as exec from '@actions/exec';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function parseNodeVersionFile(contents: string): string {
 | 
				
			||||||
 | 
					  let nodeVersion: string | undefined;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Try parsing the file as an NPM `package.json` file.
 | 
				
			||||||
 | 
					  try {
 | 
				
			||||||
 | 
					    nodeVersion = JSON.parse(contents).volta?.node;
 | 
				
			||||||
 | 
					    if (!nodeVersion) nodeVersion = JSON.parse(contents).engines?.node;
 | 
				
			||||||
 | 
					  } catch {
 | 
				
			||||||
 | 
					    core.info('Node version file is not JSON file');
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (!nodeVersion) {
 | 
				
			||||||
 | 
					    const found = contents.match(/^(?:nodejs\s+)?v?(?<version>[^\s]+)$/m);
 | 
				
			||||||
 | 
					    nodeVersion = found?.groups?.version;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // In the case of an unknown format,
 | 
				
			||||||
 | 
					  // return as is and evaluate the version separately.
 | 
				
			||||||
 | 
					  if (!nodeVersion) nodeVersion = contents.trim();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return nodeVersion as string;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export async function printEnvDetailsAndSetOutput() {
 | 
				
			||||||
 | 
					  core.startGroup('Environment details');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const promises = ['node', 'npm', 'yarn'].map(async tool => {
 | 
				
			||||||
 | 
					    const output = await getToolVersion(tool, ['--version']);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return {tool, output};
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const tools = await Promise.all(promises);
 | 
				
			||||||
 | 
					  tools.forEach(({tool, output}) => {
 | 
				
			||||||
 | 
					    if (tool === 'node') {
 | 
				
			||||||
 | 
					      core.setOutput(`${tool}-version`, output);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    core.info(`${tool}: ${output}`);
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  core.endGroup();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					async function getToolVersion(tool: string, options: string[]) {
 | 
				
			||||||
 | 
					  try {
 | 
				
			||||||
 | 
					    const {stdout, stderr, exitCode} = await exec.getExecOutput(tool, options, {
 | 
				
			||||||
 | 
					      ignoreReturnCode: true,
 | 
				
			||||||
 | 
					      silent: true
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (exitCode > 0) {
 | 
				
			||||||
 | 
					      core.info(`[warning]${stderr}`);
 | 
				
			||||||
 | 
					      return '';
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return stdout.trim();
 | 
				
			||||||
 | 
					  } catch (err) {
 | 
				
			||||||
 | 
					    return '';
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user