2020-05-19 21:25:54 +08:00
import * as core from '@actions/core' ;
2020-03-10 23:51:57 +08:00
import * as io from '@actions/io' ;
import * as tc from '@actions/tool-cache' ;
2022-07-01 07:27:37 +08:00
import * as exec from '@actions/exec' ;
2021-11-29 17:18:31 +08:00
import * as im from '../src/installer' ;
2022-04-01 03:10:37 +08:00
import * as cache from '@actions/cache' ;
2020-05-19 21:25:54 +08:00
import fs from 'fs' ;
import cp from 'child_process' ;
import osm = require ( 'os' ) ;
import path from 'path' ;
2021-12-01 22:15:29 +08:00
import each from 'jest-each' ;
2020-05-19 21:25:54 +08:00
import * as main from '../src/main' ;
import * as auth from '../src/authutil' ;
let nodeTestManifest = require ( './data/versions-manifest.json' ) ;
let nodeTestDist = require ( './data/node-dist-index.json' ) ;
describe ( 'setup-node' , ( ) = > {
let inputs = { } as any ;
let os = { } as any ;
let inSpy : jest.SpyInstance ;
let findSpy : jest.SpyInstance ;
let cnSpy : jest.SpyInstance ;
let logSpy : jest.SpyInstance ;
2020-06-30 02:56:37 +08:00
let warningSpy : jest.SpyInstance ;
2020-05-19 21:25:54 +08:00
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 ;
2021-11-29 17:18:31 +08:00
let readFileSyncSpy : jest.SpyInstance ;
2020-05-19 21:25:54 +08:00
let mkdirpSpy : jest.SpyInstance ;
let execSpy : jest.SpyInstance ;
let authSpy : jest.SpyInstance ;
2021-11-29 17:18:31 +08:00
let parseNodeVersionSpy : jest.SpyInstance ;
2022-04-01 03:10:37 +08:00
let isCacheActionAvailable : jest.SpyInstance ;
2022-07-01 07:27:37 +08:00
let getExecOutputSpy : jest.SpyInstance ;
2020-05-19 21:25:54 +08:00
beforeEach ( ( ) = > {
// @actions/core
2020-10-02 00:03:22 +08:00
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
2020-05-19 21:25:54 +08:00
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' ) ;
dlSpy = jest . spyOn ( tc , 'downloadTool' ) ;
exSpy = jest . spyOn ( tc , 'extractTar' ) ;
cacheSpy = jest . spyOn ( tc , 'cacheDir' ) ;
getManifestSpy = jest . spyOn ( tc , 'getManifestFromRepo' ) ;
getDistSpy = jest . spyOn ( im , 'getVersionsFromDist' ) ;
2021-11-29 17:18:31 +08:00
parseNodeVersionSpy = jest . spyOn ( im , 'parseNodeVersionFile' ) ;
2020-05-19 21:25:54 +08:00
// io
whichSpy = jest . spyOn ( io , 'which' ) ;
existsSpy = jest . spyOn ( fs , 'existsSync' ) ;
mkdirpSpy = jest . spyOn ( io , 'mkdirP' ) ;
2022-04-01 03:10:37 +08:00
// @actions/tool-cache
isCacheActionAvailable = jest . spyOn ( cache , 'isFeatureAvailable' ) ;
2020-05-19 21:25:54 +08:00
// disable authentication portion for installer tests
authSpy = jest . spyOn ( auth , 'configAuthentication' ) ;
authSpy . mockImplementation ( ( ) = > { } ) ;
// gets
getManifestSpy . mockImplementation (
( ) = > < tc.IToolRelease [ ] > nodeTestManifest
) ;
getDistSpy . mockImplementation ( ( ) = > < im.INodeVersion > nodeTestDist ) ;
// writes
cnSpy = jest . spyOn ( process . stdout , 'write' ) ;
2020-06-30 02:56:37 +08:00
logSpy = jest . spyOn ( core , 'info' ) ;
2020-05-19 21:25:54 +08:00
dbgSpy = jest . spyOn ( core , 'debug' ) ;
2020-06-30 02:56:37 +08:00
warningSpy = jest . spyOn ( core , 'warning' ) ;
2020-05-19 21:25:54 +08:00
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');
} ) ;
2021-11-29 17:18:31 +08:00
warningSpy . mockImplementation ( msg = > {
// uncomment to debug
// process.stderr.write('log:' + line + '\n');
} ) ;
2022-07-01 07:27:37 +08:00
// @actions/exec
getExecOutputSpy = jest . spyOn ( exec , 'getExecOutput' ) ;
2022-07-01 07:30:18 +08:00
getExecOutputSpy . mockImplementation ( ( ) = > 'v16.15.0' ) ;
2020-05-19 21:25:54 +08:00
} ) ;
afterEach ( ( ) = > {
jest . resetAllMocks ( ) ;
jest . clearAllMocks ( ) ;
//jest.restoreAllMocks();
} ) ;
2020-10-02 00:03:22 +08:00
afterAll ( async ( ) = > {
console . log ( '::stoptoken::' ) ; // Re-enable executing of runner commands when running tests in actions
2021-11-29 17:18:31 +08:00
jest . restoreAllMocks ( ) ;
2020-10-02 00:03:22 +08:00
} , 100000 ) ;
2020-05-19 21:25:54 +08:00
//--------------------------------------------------
// Manifest find tests
//--------------------------------------------------
it ( 'can mock manifest versions' , async ( ) = > {
let versions : tc.IToolRelease [ ] | null = await tc . getManifestFromRepo (
'actions' ,
'node-versions' ,
'mocktoken'
) ;
expect ( versions ) . toBeDefined ( ) ;
2022-06-02 18:30:33 +08:00
expect ( versions ? . length ) . toBe ( 7 ) ;
2020-05-19 21:25:54 +08:00
} ) ;
it ( 'can mock dist versions' , async ( ) = > {
let versions : im.INodeVersion [ ] = await im . getVersionsFromDist ( ) ;
expect ( versions ) . toBeDefined ( ) ;
expect ( versions ? . length ) . toBe ( 23 ) ;
} ) ;
2022-05-18 15:50:05 +08:00
it . each ( [
[ '12.16.2' , 'darwin' , '12.16.2' , 'Erbium' ] ,
[ '12' , 'linux' , '12.16.2' , 'Erbium' ] ,
[ '10' , 'win32' , '10.20.1' , 'Dubnium' ] ,
[ '*' , 'linux' , '14.0.0' , 'Fermium' ]
] ) (
'can find %s from manifest on %s' ,
async ( versionSpec , platform , expectedVersion , expectedLts ) = > {
os . platform = platform ;
os . arch = 'x64' ;
let versions : tc.IToolRelease [ ] | null = await tc . getManifestFromRepo (
'actions' ,
'node-versions' ,
'mocktoken'
) ;
expect ( versions ) . toBeDefined ( ) ;
let match = await tc . findFromManifest ( versionSpec , true , versions ) ;
expect ( match ) . toBeDefined ( ) ;
expect ( match ? . version ) . toBe ( expectedVersion ) ;
expect ( ( match as any ) . lts ) . toBe ( expectedLts ) ;
}
) ;
2020-05-19 21:25:54 +08:00
//--------------------------------------------------
// Found in cache tests
//--------------------------------------------------
2021-08-04 22:00:35 +08:00
it ( 'finds version in cache with stable true' , async ( ) = > {
2020-05-19 21:25:54 +08:00
inputs [ 'node-version' ] = '12' ;
inputs . stable = 'true' ;
let toolPath = path . normalize ( '/cache/node/12.16.1/x64' ) ;
findSpy . mockImplementation ( ( ) = > toolPath ) ;
await main . run ( ) ;
expect ( logSpy ) . toHaveBeenCalledWith ( ` Found in cache @ ${ toolPath } ` ) ;
2019-08-04 09:49:54 +08:00
} ) ;
2021-08-04 22:00:35 +08:00
it ( 'finds version in cache with stable not supplied' , async ( ) = > {
2020-05-19 21:25:54 +08:00
inputs [ 'node-version' ] = '12' ;
inSpy . mockImplementation ( name = > inputs [ name ] ) ;
let toolPath = path . normalize ( '/cache/node/12.16.1/x64' ) ;
findSpy . mockImplementation ( ( ) = > toolPath ) ;
await main . run ( ) ;
expect ( logSpy ) . toHaveBeenCalledWith ( ` Found in cache @ ${ toolPath } ` ) ;
2019-08-04 09:49:54 +08:00
} ) ;
2021-08-04 22:00:35 +08:00
it ( 'finds version in cache and adds it to the path' , async ( ) = > {
2020-05-19 21:25:54 +08:00
inputs [ 'node-version' ] = '12' ;
inSpy . mockImplementation ( name = > inputs [ name ] ) ;
let toolPath = path . normalize ( '/cache/node/12.16.1/x64' ) ;
findSpy . mockImplementation ( ( ) = > toolPath ) ;
await main . run ( ) ;
let expPath = path . join ( toolPath , 'bin' ) ;
expect ( cnSpy ) . toHaveBeenCalledWith ( ` ::add-path:: ${ expPath } ${ osm . EOL } ` ) ;
2019-08-04 09:49:54 +08:00
} ) ;
2020-05-19 21:25:54 +08:00
it ( 'handles unhandled find error and reports error' , async ( ) = > {
let errMsg = 'unhandled error message' ;
inputs [ 'node-version' ] = '12' ;
findSpy . mockImplementation ( ( ) = > {
throw new Error ( errMsg ) ;
} ) ;
await main . run ( ) ;
expect ( cnSpy ) . toHaveBeenCalledWith ( '::error::' + errMsg + osm . EOL ) ;
} ) ;
2021-06-17 23:51:02 +08:00
//--------------------------------------------------
// Manifest tests
//--------------------------------------------------
2020-05-19 21:25:54 +08:00
it ( 'downloads a version from a manifest match' , async ( ) = > {
os . platform = 'linux' ;
os . arch = 'x64' ;
// a version which is in the manifest
let versionSpec = '12.16.2' ;
let resolvedVersion = versionSpec ;
inputs [ 'node-version' ] = versionSpec ;
inputs [ 'always-auth' ] = false ;
inputs [ 'token' ] = 'faketoken' ;
let expectedUrl =
2022-06-02 18:30:33 +08:00
'https://github.com/actions/node-versions/releases/download/12.16.2-20200507.95/node-12.16.2-linux-x64.tar.gz' ;
2020-05-19 21:25:54 +08:00
// ... but not in the local cache
findSpy . mockImplementation ( ( ) = > '' ) ;
dlSpy . mockImplementation ( async ( ) = > '/some/temp/path' ) ;
let toolPath = path . normalize ( '/cache/node/12.16.2/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 (
2020-09-03 20:50:29 +08:00
` Acquiring ${ resolvedVersion } - ${ os . arch } from ${ expectedUrl } `
2020-05-19 21:25:54 +08:00
) ;
expect ( logSpy ) . toHaveBeenCalledWith (
` Attempting to download ${ versionSpec } ... `
) ;
expect ( cnSpy ) . toHaveBeenCalledWith ( ` ::add-path:: ${ expPath } ${ 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 = '11.15.0' ;
let resolvedVersion = versionSpec ;
inputs [ 'node-version' ] = versionSpec ;
inputs [ 'always-auth' ] = false ;
inputs [ 'token' ] = 'faketoken' ;
let expectedUrl =
2022-06-02 18:30:33 +08:00
'https://github.com/actions/node-versions/releases/download/12.16.2-20200507.95/node-12.16.2-linux-x64.tar.gz' ;
2020-05-19 21:25:54 +08:00
// ... 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 = '9.99.9' ;
inputs [ 'node-version' ] = versionSpec ;
findSpy . mockImplementation ( ( ) = > '' ) ;
await main . run ( ) ;
expect ( logSpy ) . toHaveBeenCalledWith (
'Not found in manifest. Falling back to download directly from Node'
) ;
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 } `
) ;
} ) ;
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 = '12.16.2' ;
let resolvedVersion = versionSpec ;
inputs [ 'node-version' ] = versionSpec ;
inputs [ 'always-auth' ] = false ;
inputs [ 'token' ] = 'faketoken' ;
findSpy . mockImplementation ( ( ) = > '' ) ;
dlSpy . mockImplementation ( ( ) = > {
throw new Error ( errMsg ) ;
} ) ;
await main . run ( ) ;
expect ( cnSpy ) . toHaveBeenCalledWith ( ` ::error:: ${ errMsg } ${ osm . EOL } ` ) ;
2019-08-04 09:49:54 +08:00
} ) ;
2020-06-30 02:56:37 +08:00
2021-11-29 17:18:31 +08:00
it ( 'acquires specified architecture of node' , async ( ) = > {
2020-09-03 23:15:28 +08:00
for ( const { arch , version , osSpec } of [
{ arch : 'x86' , version : '12.16.2' , osSpec : 'win32' } ,
{ arch : 'x86' , version : '14.0.0' , osSpec : 'win32' }
2020-09-03 21:47:25 +08:00
] ) {
2020-09-03 23:15:28 +08:00
os . platform = osSpec ;
os . arch = arch ;
const fileExtension = os . platform === 'win32' ? '7z' : 'tar.gz' ;
2020-09-03 21:47:25 +08:00
const platform = {
linux : 'linux' ,
darwin : 'darwin' ,
win32 : 'win'
2020-09-03 23:15:28 +08:00
} [ os . platform ] ;
inputs [ 'node-version' ] = version ;
2020-12-09 06:15:38 +08:00
inputs [ 'architecture' ] = arch ;
2020-09-03 23:15:28 +08:00
inputs [ 'always-auth' ] = false ;
inputs [ 'token' ] = 'faketoken' ;
let expectedUrl =
arch === 'x64'
? ` https://github.com/actions/node-versions/releases/download/ ${ version } /node- ${ version } - ${ platform } - ${ arch } .zip `
: ` https://nodejs.org/dist/v ${ version } /node-v ${ version } - ${ platform } - ${ arch } . ${ fileExtension } ` ;
// ... but not in the local cache
findSpy . 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 } `
) ;
2020-09-03 21:47:25 +08:00
}
} , 100000 ) ;
2020-06-30 02:56:37 +08:00
describe ( 'check-latest flag' , ( ) = > {
2021-08-04 22:00:35 +08:00
it ( 'use local version and dont check manifest if check-latest is not specified' , async ( ) = > {
2020-06-30 02:56:37 +08:00
os . platform = 'linux' ;
os . arch = 'x64' ;
inputs [ 'node-version' ] = '12' ;
inputs [ 'check-latest' ] = 'false' ;
const toolPath = path . normalize ( '/cache/node/12.16.1/x64' ) ;
findSpy . mockReturnValue ( toolPath ) ;
await main . run ( ) ;
expect ( logSpy ) . toHaveBeenCalledWith ( ` Found in cache @ ${ toolPath } ` ) ;
expect ( logSpy ) . not . toHaveBeenCalledWith (
'Attempt to resolve the latest version from manifest...'
) ;
2021-06-22 23:52:06 +08:00
expect ( dbgSpy ) . not . toHaveBeenCalledWith ( 'No manifest cached' ) ;
2021-06-22 22:11:44 +08:00
expect ( dbgSpy ) . not . toHaveBeenCalledWith (
2021-06-22 23:52:06 +08:00
'Getting manifest from actions/node-versions@main'
2021-06-22 22:11:44 +08:00
) ;
2020-06-30 02:56:37 +08:00
} ) ;
2021-08-04 22:00:35 +08:00
it ( 'check latest version and resolve it from local cache' , async ( ) = > {
2020-06-30 02:56:37 +08:00
os . platform = 'linux' ;
os . arch = 'x64' ;
inputs [ 'node-version' ] = '12' ;
inputs [ 'check-latest' ] = 'true' ;
const toolPath = path . normalize ( '/cache/node/12.16.2/x64' ) ;
findSpy . mockReturnValue ( toolPath ) ;
dlSpy . mockImplementation ( async ( ) = > '/some/temp/path' ) ;
exSpy . mockImplementation ( async ( ) = > '/some/other/temp/path' ) ;
cacheSpy . mockImplementation ( async ( ) = > toolPath ) ;
await main . run ( ) ;
expect ( logSpy ) . toHaveBeenCalledWith (
'Attempt to resolve the latest version from manifest...'
) ;
2021-06-22 23:52:06 +08:00
expect ( dbgSpy ) . toHaveBeenCalledWith ( 'No manifest cached' ) ;
2021-06-22 22:11:44 +08:00
expect ( dbgSpy ) . toHaveBeenCalledWith (
2021-06-22 23:52:06 +08:00
'Getting manifest from actions/node-versions@main'
2021-06-22 22:11:44 +08:00
) ;
2020-06-30 02:56:37 +08:00
expect ( logSpy ) . toHaveBeenCalledWith ( "Resolved as '12.16.2'" ) ;
expect ( logSpy ) . toHaveBeenCalledWith ( ` Found in cache @ ${ toolPath } ` ) ;
} ) ;
it ( 'check latest version and install it from manifest' , async ( ) = > {
os . platform = 'linux' ;
os . arch = 'x64' ;
inputs [ 'node-version' ] = '12' ;
inputs [ 'check-latest' ] = 'true' ;
findSpy . mockImplementation ( ( ) = > '' ) ;
dlSpy . mockImplementation ( async ( ) = > '/some/temp/path' ) ;
const toolPath = path . normalize ( '/cache/node/12.16.2/x64' ) ;
exSpy . mockImplementation ( async ( ) = > '/some/other/temp/path' ) ;
cacheSpy . mockImplementation ( async ( ) = > toolPath ) ;
const expectedUrl =
2022-06-02 18:30:33 +08:00
'https://github.com/actions/node-versions/releases/download/12.16.2-20200507.95/node-12.16.2-linux-x64.tar.gz' ;
2020-06-30 02:56:37 +08:00
await main . run ( ) ;
expect ( logSpy ) . toHaveBeenCalledWith (
'Attempt to resolve the latest version from manifest...'
) ;
2021-06-22 23:52:06 +08:00
expect ( dbgSpy ) . toHaveBeenCalledWith ( 'No manifest cached' ) ;
2021-06-22 22:11:44 +08:00
expect ( dbgSpy ) . toHaveBeenCalledWith (
2021-06-22 23:52:06 +08:00
'Getting manifest from actions/node-versions@main'
2021-06-22 22:11:44 +08:00
) ;
2020-06-30 02:56:37 +08:00
expect ( logSpy ) . toHaveBeenCalledWith ( "Resolved as '12.16.2'" ) ;
expect ( logSpy ) . toHaveBeenCalledWith (
2020-09-03 20:50:29 +08:00
` Acquiring 12.16.2 - ${ os . arch } from ${ expectedUrl } `
2020-06-30 02:56:37 +08:00
) ;
expect ( logSpy ) . toHaveBeenCalledWith ( 'Extracting ...' ) ;
} ) ;
it ( 'fallback to dist if version if not found in manifest' , async ( ) = > {
os . platform = 'linux' ;
os . arch = 'x64' ;
// a version which is not in the manifest but is in node dist
let versionSpec = '11' ;
inputs [ 'node-version' ] = versionSpec ;
inputs [ 'check-latest' ] = 'true' ;
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 (
'Attempt to resolve the latest version from manifest...'
) ;
2021-06-22 23:52:06 +08:00
expect ( dbgSpy ) . toHaveBeenCalledWith ( 'No manifest cached' ) ;
2021-06-22 22:11:44 +08:00
expect ( dbgSpy ) . toHaveBeenCalledWith (
2021-06-22 23:52:06 +08:00
'Getting manifest from actions/node-versions@main'
2021-06-22 22:11:44 +08:00
) ;
2020-06-30 02:56:37 +08:00
expect ( logSpy ) . toHaveBeenCalledWith (
` Failed to resolve version ${ versionSpec } from manifest `
) ;
expect ( logSpy ) . toHaveBeenCalledWith (
` Attempting to download ${ versionSpec } ... `
) ;
expect ( cnSpy ) . toHaveBeenCalledWith ( ` ::add-path:: ${ expPath } ${ osm . EOL } ` ) ;
} ) ;
it ( 'fallback to dist if manifest is not available' , async ( ) = > {
os . platform = 'linux' ;
os . arch = 'x64' ;
// a version which is not in the manifest but is in node dist
let versionSpec = '12' ;
inputs [ 'node-version' ] = versionSpec ;
inputs [ 'check-latest' ] = 'true' ;
inputs [ 'always-auth' ] = false ;
inputs [ 'token' ] = 'faketoken' ;
// ... but not in the local cache
findSpy . mockImplementation ( ( ) = > '' ) ;
getManifestSpy . mockImplementation ( ( ) = > {
throw new Error ( 'Unable to download manifest' ) ;
} ) ;
dlSpy . mockImplementation ( async ( ) = > '/some/temp/path' ) ;
let toolPath = path . normalize ( '/cache/node/12.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 (
'Attempt to resolve the latest version from manifest...'
) ;
expect ( logSpy ) . toHaveBeenCalledWith (
'Unable to resolve version from manifest...'
) ;
expect ( logSpy ) . toHaveBeenCalledWith (
` Failed to resolve version ${ versionSpec } from manifest `
) ;
expect ( logSpy ) . toHaveBeenCalledWith (
` Attempting to download ${ versionSpec } ... `
) ;
expect ( cnSpy ) . toHaveBeenCalledWith ( ` ::add-path:: ${ expPath } ${ osm . EOL } ` ) ;
} ) ;
} ) ;
2021-06-17 23:51:02 +08:00
2021-11-29 17:18:31 +08:00
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 ) ;
} ) ;
2022-06-30 06:37:53 +08:00
it ( 'reads node-version-file if provided (.nvmrc)' , async ( ) = > {
2021-11-29 17:18:31 +08:00
// 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 )
) ;
2022-06-30 06:37:53 +08:00
2021-11-29 17:18:31 +08:00
// Act
await main . run ( ) ;
// Assert
expect ( existsSpy ) . toHaveBeenCalledTimes ( 1 ) ;
expect ( existsSpy ) . toHaveReturnedWith ( true ) ;
expect ( parseNodeVersionSpy ) . toHaveBeenCalledWith ( versionSpec ) ;
expect ( logSpy ) . toHaveBeenCalledWith (
` Resolved ${ versionFile } as ${ expectedVersionSpec } `
) ;
} ) ;
2022-06-30 06:37:53 +08:00
it ( 'reads node-version-file if provided (package.json, volta)' , async ( ) = > {
2022-06-30 03:28:21 +08:00
// Arrange
const versionFile = 'package.json' ;
2022-07-01 00:57:00 +08:00
const versionSpec = fs . readFileSync (
path . join ( __dirname , 'data' , versionFile ) ,
'utf8'
) ;
2022-06-30 06:37:53 +08:00
const expectedVersionSpec = '16.15.1' ;
2022-06-30 03:28:21 +08:00
process . env [ 'GITHUB_WORKSPACE' ] = path . join ( __dirname , 'data' ) ;
2022-06-30 06:37:53 +08:00
inputs [ 'node-version-file' ] = versionFile ;
2022-06-30 03:28:21 +08:00
2022-06-30 06:37:53 +08:00
parseNodeVersionSpy . mockImplementation ( ( ) = > expectedVersionSpec ) ;
2022-06-30 03:28:21 +08:00
existsSpy . mockImplementationOnce (
2022-06-30 06:11:14 +08:00
input = > input === path . join ( __dirname , 'data' , versionFile )
2022-06-30 03:28:21 +08:00
) ;
2022-06-30 06:37:53 +08:00
2022-06-30 03:28:21 +08:00
// Act
await main . run ( ) ;
// Assert
expect ( existsSpy ) . toHaveBeenCalledTimes ( 1 ) ;
expect ( existsSpy ) . toHaveReturnedWith ( true ) ;
2022-06-30 06:37:53 +08:00
expect ( parseNodeVersionSpy ) . toHaveBeenCalledWith ( versionSpec ) ;
2022-06-30 03:28:21 +08:00
expect ( logSpy ) . toHaveBeenCalledWith (
2022-06-30 06:11:14 +08:00
` Resolved ${ versionFile } as ${ expectedVersionSpec } `
2022-06-30 03:28:21 +08:00
) ;
} ) ;
2022-07-22 01:17:21 +08:00
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 ) ;
2021-11-29 17:18:31 +08:00
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 } `
) ;
} ) ;
} ) ;
2022-04-01 03:10:37 +08:00
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 ( cnSpy ) . 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 } `
) ;
} ) ;
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'
) ;
} ) ;
} ) ;
2021-06-17 23:51:02 +08:00
describe ( 'LTS version' , ( ) = > {
2021-06-30 15:27:49 +08:00
beforeEach ( ( ) = > {
2021-06-17 23:51:02 +08:00
os . platform = 'linux' ;
os . arch = 'x64' ;
2021-06-30 15:27:49 +08:00
inputs . stable = 'true' ;
} ) ;
2021-06-17 23:51:02 +08:00
2022-06-02 18:30:33 +08:00
it . each ( [
[ 'erbium' , '12.16.2' ] ,
[ '*' , '14.0.0' ] ,
[ '-1' , '12.16.2' ]
] ) (
'find latest LTS version and resolve it from local cache (lts/%s)' ,
async ( lts , expectedVersion ) = > {
// arrange
inputs [ 'node-version' ] = ` lts/ ${ lts } ` ;
const toolPath = path . normalize ( ` /cache/node/ ${ expectedVersion } /x64 ` ) ;
findSpy . mockReturnValue ( toolPath ) ;
// act
await main . run ( ) ;
// assert
expect ( logSpy ) . toHaveBeenCalledWith (
'Attempt to resolve LTS alias from manifest...'
) ;
expect ( dbgSpy ) . toHaveBeenCalledWith (
'Getting manifest from actions/node-versions@main'
) ;
expect ( dbgSpy ) . not . toHaveBeenCalledWith ( 'No manifest cached' ) ;
expect ( dbgSpy ) . toHaveBeenCalledWith (
` LTS alias ' ${ lts } ' for Node version 'lts/ ${ lts } ' `
) ;
expect ( dbgSpy ) . toHaveBeenCalledWith (
` Found LTS release ' ${ expectedVersion } ' for Node version 'lts/ ${ lts } ' `
) ;
expect ( logSpy ) . toHaveBeenCalledWith ( ` Found in cache @ ${ toolPath } ` ) ;
expect ( cnSpy ) . toHaveBeenCalledWith (
` ::add-path:: ${ path . join ( toolPath , 'bin' ) } ${ osm . EOL } `
) ;
}
) ;
2021-06-18 00:34:09 +08:00
2022-06-02 18:30:33 +08:00
it . each ( [
[
'erbium' ,
'12.16.2' ,
'https://github.com/actions/node-versions/releases/download/12.16.2-20200507.95/node-12.16.2-linux-x64.tar.gz'
] ,
[
'*' ,
'14.0.0' ,
'https://github.com/actions/node-versions/releases/download/14.0.0-20200507.99/node-14.0.0-linux-x64.tar.gz'
] ,
[
'-1' ,
'12.16.2' ,
'https://github.com/actions/node-versions/releases/download/12.16.2-20200507.95/node-12.16.2-linux-x64.tar.gz'
]
] ) (
'find latest LTS version and install it from manifest (lts/%s)' ,
async ( lts , expectedVersion , expectedUrl ) = > {
// arrange
inputs [ 'node-version' ] = ` lts/ ${ lts } ` ;
const toolPath = path . normalize ( ` /cache/node/ ${ expectedVersion } /x64 ` ) ;
findSpy . mockImplementation ( ( ) = > '' ) ;
dlSpy . mockImplementation ( async ( ) = > '/some/temp/path' ) ;
exSpy . mockImplementation ( async ( ) = > '/some/other/temp/path' ) ;
cacheSpy . mockImplementation ( async ( ) = > toolPath ) ;
const expectedMajor = expectedVersion . split ( '.' ) [ 0 ] ;
// act
await main . run ( ) ;
// assert
expect ( logSpy ) . toHaveBeenCalledWith (
'Attempt to resolve LTS alias from manifest...'
) ;
expect ( dbgSpy ) . toHaveBeenCalledWith (
'Getting manifest from actions/node-versions@main'
) ;
expect ( dbgSpy ) . not . toHaveBeenCalledWith ( 'No manifest cached' ) ;
expect ( dbgSpy ) . toHaveBeenCalledWith (
` LTS alias ' ${ lts } ' for Node version 'lts/ ${ lts } ' `
) ;
expect ( dbgSpy ) . toHaveBeenCalledWith (
` Found LTS release ' ${ expectedVersion } ' for Node version 'lts/ ${ lts } ' `
) ;
expect ( logSpy ) . toHaveBeenCalledWith (
` Attempting to download ${ expectedMajor } ... `
) ;
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 } `
) ;
}
) ;
2021-06-18 00:53:38 +08:00
2021-06-30 15:34:42 +08:00
it ( 'fail with unable to parse LTS alias (lts/)' , async ( ) = > {
2021-06-18 00:53:38 +08:00
// arrange
inputs [ 'node-version' ] = 'lts/' ;
findSpy . mockImplementation ( ( ) = > '' ) ;
// act
await main . run ( ) ;
// assert
2021-06-22 22:11:44 +08:00
expect ( logSpy ) . toHaveBeenCalledWith (
'Attempt to resolve LTS alias from manifest...'
) ;
expect ( dbgSpy ) . toHaveBeenCalledWith (
'Getting manifest from actions/node-versions@main'
) ;
expect ( cnSpy ) . toHaveBeenCalledWith (
2021-06-30 15:34:42 +08:00
` ::error::Unable to parse LTS alias for Node version 'lts/' ${ osm . EOL } `
2021-06-22 22:11:44 +08:00
) ;
2021-06-18 00:53:38 +08:00
} ) ;
it ( 'fail to find LTS version (lts/unknown)' , async ( ) = > {
// arrange
inputs [ 'node-version' ] = 'lts/unknown' ;
findSpy . mockImplementation ( ( ) = > '' ) ;
// act
await main . run ( ) ;
// assert
2021-06-22 22:11:44 +08:00
expect ( logSpy ) . toHaveBeenCalledWith (
'Attempt to resolve LTS alias from manifest...'
) ;
expect ( dbgSpy ) . toHaveBeenCalledWith (
'Getting manifest from actions/node-versions@main'
) ;
expect ( dbgSpy ) . toHaveBeenCalledWith (
` LTS alias 'unknown' for Node version 'lts/unknown' `
) ;
expect ( cnSpy ) . toHaveBeenCalledWith (
` ::error::Unable to find LTS release 'unknown' for Node version 'lts/unknown'. ${ osm . EOL } `
) ;
2021-06-18 00:53:38 +08:00
} ) ;
2021-06-22 21:45:25 +08:00
it ( 'fail if manifest is not available' , async ( ) = > {
// arrange
inputs [ 'node-version' ] = 'lts/erbium' ;
// ... but not in the local cache
findSpy . mockImplementation ( ( ) = > '' ) ;
getManifestSpy . mockImplementation ( ( ) = > {
throw new Error ( 'Unable to download manifest' ) ;
} ) ;
// act
await main . run ( ) ;
// assert
2021-06-22 22:11:44 +08:00
expect ( logSpy ) . toHaveBeenCalledWith (
'Attempt to resolve LTS alias from manifest...'
) ;
expect ( dbgSpy ) . toHaveBeenCalledWith (
'Getting manifest from actions/node-versions@main'
) ;
expect ( cnSpy ) . toHaveBeenCalledWith (
` ::error::Unable to download manifest ${ osm . EOL } `
) ;
} ) ;
} ) ;
2022-05-12 23:26:02 +08:00
describe ( 'latest alias syntax' , ( ) = > {
it . each ( [ 'latest' , 'current' , 'node' ] ) (
'download the %s version if alias is provided' ,
async inputVersion = > {
// Arrange
inputs [ 'node-version' ] = inputVersion ;
os . platform = 'darwin' ;
os . arch = 'x64' ;
findSpy . mockImplementation ( ( ) = > '' ) ;
getManifestSpy . mockImplementation ( ( ) = > {
throw new Error ( 'Unable to download manifest' ) ;
} ) ;
// Act
await main . run ( ) ;
// assert
expect ( logSpy ) . toHaveBeenCalledWith ( 'Unable to download manifest' ) ;
expect ( logSpy ) . toHaveBeenCalledWith ( 'getting latest node version...' ) ;
}
) ;
} ) ;
2022-05-19 23:33:13 +08:00
describe ( 'latest alias syntax from cache' , ( ) = > {
it . each ( [ 'latest' , 'current' , 'node' ] ) (
'download the %s version if alias is provided' ,
async inputVersion = > {
// Arrange
inputs [ 'node-version' ] = inputVersion ;
const expectedVersion = nodeTestDist [ 0 ] ;
os . platform = 'darwin' ;
os . arch = 'x64' ;
const toolPath = path . normalize (
` /cache/node/ ${ expectedVersion . version } /x64 `
) ;
findSpy . mockReturnValue ( toolPath ) ;
// Act
await main . run ( ) ;
// assert
expect ( logSpy ) . toHaveBeenCalledWith ( ` Found in cache @ ${ toolPath } ` ) ;
expect ( logSpy ) . toHaveBeenCalledWith ( 'getting latest node version...' ) ;
}
) ;
} ) ;
2019-08-04 09:49:54 +08:00
} ) ;
2021-12-01 22:15:29 +08:00
describe ( 'helper methods' , ( ) = > {
describe ( 'parseNodeVersionFile' , ( ) = > {
each `
2021-12-01 23:44:59 +08:00
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' }
2021-12-01 22:15:29 +08:00
` .it('parses " $ contents"', ({contents, expected}) => {
expect ( im . parseNodeVersionFile ( contents ) ) . toBe ( expected ) ;
} ) ;
} ) ;
} ) ;