@@ -1367,4 +1367,274 @@ describe('setup-node', () => {
13671367 ) ;
13681368 } ) ;
13691369 } ) ;
1370+
1371+ describe ( 'force-mirror' , ( ) => {
1372+ const mirror = 'https://my_mirror_url' ;
1373+
1374+ beforeEach ( ( ) => {
1375+ os . platform = 'linux' ;
1376+ os . arch = 'x64' ;
1377+ inputs [ 'token' ] = 'faketoken' ;
1378+ inputs [ 'mirror' ] = mirror ;
1379+ inputs [ 'mirror-token' ] = 'fake-mirror-token' ;
1380+ inputs [ 'force-mirror' ] = 'true' ;
1381+ } ) ;
1382+
1383+ function mockNodeVersion ( version : string ) {
1384+ getExecOutputSpy . mockImplementation ( async ( ) => ( {
1385+ stdout : `v${ version } \n` ,
1386+ stderr : '' ,
1387+ exitCode : 0
1388+ } ) ) ;
1389+ }
1390+
1391+ it ( 'downloads from the mirror without using the manifest, even if the version is in the manifest' , async ( ) => {
1392+ // 12.16.2 is present in the test manifest
1393+ const version = '12.16.2' ;
1394+ inputs [ 'node-version' ] = version ;
1395+ findSpy . mockImplementation ( ( ) => '' ) ;
1396+ dlSpy . mockImplementation ( async ( ) => '/some/temp/path' ) ;
1397+ exSpy . mockImplementation ( async ( ) => '/some/other/temp/path' ) ;
1398+ const toolPath = path . normalize ( `/cache/node/${ version } /x64` ) ;
1399+ cacheSpy . mockImplementation ( async ( ) => toolPath ) ;
1400+ mockNodeVersion ( version ) ;
1401+
1402+ await main . run ( ) ;
1403+
1404+ expect ( getManifestSpy ) . not . toHaveBeenCalled ( ) ;
1405+ expect ( getJsonSpy ) . not . toHaveBeenCalledWith (
1406+ nodeVersionsManifestUrl ,
1407+ expect . anything ( )
1408+ ) ;
1409+ expect ( dlSpy ) . toHaveBeenCalledTimes ( 1 ) ;
1410+ expect ( dlSpy ) . toHaveBeenCalledWith (
1411+ `${ mirror } /dist/v${ version } /node-v${ version } -linux-x64.tar.gz` ,
1412+ undefined ,
1413+ 'fake-mirror-token'
1414+ ) ;
1415+ expect ( getJsonSpy ) . toHaveBeenCalledWith ( `${ mirror } /dist/index.json` , {
1416+ Authorization : 'fake-mirror-token'
1417+ } ) ;
1418+ expect ( addPathSpy ) . toHaveBeenCalledWith ( path . join ( toolPath , 'bin' ) ) ;
1419+ expect ( setFailedSpy ) . not . toHaveBeenCalled ( ) ;
1420+ } ) ;
1421+
1422+ it ( 'uses the local tool cache without contacting the mirror' , async ( ) => {
1423+ inputs [ 'node-version' ] = '12' ;
1424+ const toolPath = path . normalize ( '/cache/node/12.16.2/x64' ) ;
1425+ findSpy . mockReturnValue ( toolPath ) ;
1426+ mockNodeVersion ( '12.16.2' ) ;
1427+
1428+ await main . run ( ) ;
1429+
1430+ expect ( getManifestSpy ) . not . toHaveBeenCalled ( ) ;
1431+ expect ( getJsonSpy ) . not . toHaveBeenCalled ( ) ;
1432+ expect ( dlSpy ) . not . toHaveBeenCalled ( ) ;
1433+ expect ( logSpy ) . toHaveBeenCalledWith ( `Found in cache @ ${ toolPath } ` ) ;
1434+ expect ( addPathSpy ) . toHaveBeenCalledWith ( path . join ( toolPath , 'bin' ) ) ;
1435+ } ) ;
1436+
1437+ it . each ( [
1438+ [ 'erbium' , '12' ] ,
1439+ [ '*' , '12' ] ,
1440+ [ '-1' , '10' ] ,
1441+ [ 'dubnium' , '10' ]
1442+ ] ) (
1443+ 'resolves LTS alias lts/%s from the mirror index' ,
1444+ async ( lts , expectedMajor ) => {
1445+ inputs [ 'node-version' ] = `lts/${ lts } ` ;
1446+ const toolPath = path . normalize ( `/cache/node/${ expectedMajor } .0.0/x64` ) ;
1447+ findSpy . mockReturnValue ( toolPath ) ;
1448+ mockNodeVersion ( `${ expectedMajor } .0.0` ) ;
1449+
1450+ await main . run ( ) ;
1451+
1452+ expect ( getManifestSpy ) . not . toHaveBeenCalled ( ) ;
1453+ expect ( logSpy ) . toHaveBeenCalledWith (
1454+ 'Attempt to resolve LTS alias from mirror...'
1455+ ) ;
1456+ expect ( findSpy ) . toHaveBeenCalledWith ( 'node' , expectedMajor , 'x64' ) ;
1457+ expect ( setFailedSpy ) . not . toHaveBeenCalled ( ) ;
1458+ }
1459+ ) ;
1460+
1461+ it ( 'fails to resolve an unknown LTS alias' , async ( ) => {
1462+ inputs [ 'node-version' ] = 'lts/unknown' ;
1463+
1464+ await main . run ( ) ;
1465+
1466+ expect ( getManifestSpy ) . not . toHaveBeenCalled ( ) ;
1467+ expect ( setFailedSpy ) . toHaveBeenCalledWith (
1468+ `Unable to find LTS release 'unknown' for Node version 'lts/unknown'.`
1469+ ) ;
1470+ } ) ;
1471+
1472+ it . each ( [
1473+ [ '10' , '10.20.1' ] ,
1474+ [ 'latest' , '14.1.0' ]
1475+ ] ) (
1476+ 'resolves %s to the latest version from the mirror index' ,
1477+ async ( versionSpec , expectedVersion ) => {
1478+ inputs [ 'node-version' ] = versionSpec ;
1479+ inputs [ 'check-latest' ] = 'true' ;
1480+ const toolPath = path . normalize ( `/cache/node/${ expectedVersion } /x64` ) ;
1481+ findSpy . mockReturnValue ( toolPath ) ;
1482+ mockNodeVersion ( expectedVersion ) ;
1483+
1484+ await main . run ( ) ;
1485+
1486+ expect ( getManifestSpy ) . not . toHaveBeenCalled ( ) ;
1487+ expect ( logSpy ) . toHaveBeenCalledWith ( `Resolved as '${ expectedVersion } '` ) ;
1488+ expect ( findSpy ) . toHaveBeenCalledWith ( 'node' , expectedVersion , 'x64' ) ;
1489+ expect ( setFailedSpy ) . not . toHaveBeenCalled ( ) ;
1490+ }
1491+ ) ;
1492+
1493+ function mockDownload ( version : string ) {
1494+ findSpy . mockImplementation ( ( ) => '' ) ;
1495+ dlSpy . mockImplementation ( async ( ) => '/some/temp/path' ) ;
1496+ exSpy . mockImplementation ( async ( ) => '/some/other/temp/path' ) ;
1497+ const toolPath = path . normalize ( `/cache/node/${ version } /x64` ) ;
1498+ cacheSpy . mockImplementation ( async ( ) => toolPath ) ;
1499+ mockNodeVersion ( version ) ;
1500+ return toolPath ;
1501+ }
1502+
1503+ it . each ( [ 500 , 404 , 403 ] ) (
1504+ 'fails without falling back to GitHub when the mirror download returns HTTP %s' ,
1505+ async status => {
1506+ inputs [ 'node-version' ] = '12.16.2' ;
1507+ mockDownload ( '12.16.2' ) ;
1508+ dlSpy . mockImplementation ( async ( ) => {
1509+ throw new tc . HTTPError ( status ) ;
1510+ } ) ;
1511+
1512+ await main . run ( ) ;
1513+
1514+ expect ( dlSpy ) . toHaveBeenCalledTimes ( 1 ) ;
1515+ expect ( dlSpy ) . toHaveBeenCalledWith (
1516+ `${ mirror } /dist/v12.16.2/node-v12.16.2-linux-x64.tar.gz` ,
1517+ undefined ,
1518+ 'fake-mirror-token'
1519+ ) ;
1520+ expect ( getManifestSpy ) . not . toHaveBeenCalled ( ) ;
1521+ expect ( setFailedSpy ) . toHaveBeenCalledWith (
1522+ `Unexpected HTTP response: ${ status } `
1523+ ) ;
1524+ }
1525+ ) ;
1526+
1527+ it ( 'fails without falling back to GitHub when the mirror index cannot be fetched' , async ( ) => {
1528+ inputs [ 'node-version' ] = '12.16.2' ;
1529+ mockDownload ( '12.16.2' ) ;
1530+ getJsonSpy . mockImplementation ( async ( ) => {
1531+ throw new Error ( 'mirror unavailable' ) ;
1532+ } ) ;
1533+
1534+ await main . run ( ) ;
1535+
1536+ expect ( getManifestSpy ) . not . toHaveBeenCalled ( ) ;
1537+ expect ( getJsonSpy ) . toHaveBeenCalledTimes ( 1 ) ;
1538+ expect ( getJsonSpy ) . toHaveBeenCalledWith (
1539+ `${ mirror } /dist/index.json` ,
1540+ expect . anything ( )
1541+ ) ;
1542+ expect ( dlSpy ) . not . toHaveBeenCalled ( ) ;
1543+ expect ( setFailedSpy ) . toHaveBeenCalledWith ( 'mirror unavailable' ) ;
1544+ } ) ;
1545+
1546+ it ( 'fails when the version is not available on the mirror' , async ( ) => {
1547+ inputs [ 'node-version' ] = '99.0.0' ;
1548+ mockDownload ( '99.0.0' ) ;
1549+
1550+ await main . run ( ) ;
1551+
1552+ expect ( getManifestSpy ) . not . toHaveBeenCalled ( ) ;
1553+ expect ( dlSpy ) . not . toHaveBeenCalled ( ) ;
1554+ expect ( setFailedSpy ) . toHaveBeenCalledWith (
1555+ `Unable to find Node version '99.0.0' for platform linux and architecture x64.`
1556+ ) ;
1557+ } ) ;
1558+
1559+ it ( 'resolves an LTS alias with check-latest using a single mirror index request' , async ( ) => {
1560+ inputs [ 'node-version' ] = 'lts/dubnium' ;
1561+ inputs [ 'check-latest' ] = 'true' ;
1562+ const toolPath = mockDownload ( '10.20.1' ) ;
1563+
1564+ await main . run ( ) ;
1565+
1566+ expect ( getManifestSpy ) . not . toHaveBeenCalled ( ) ;
1567+ expect ( getJsonSpy ) . toHaveBeenCalledTimes ( 1 ) ;
1568+ expect ( logSpy ) . toHaveBeenCalledWith ( `Resolved as '10.20.1'` ) ;
1569+ expect ( dlSpy ) . toHaveBeenCalledWith (
1570+ `${ mirror } /dist/v10.20.1/node-v10.20.1-linux-x64.tar.gz` ,
1571+ undefined ,
1572+ 'fake-mirror-token'
1573+ ) ;
1574+ expect ( addPathSpy ) . toHaveBeenCalledWith ( path . join ( toolPath , 'bin' ) ) ;
1575+ expect ( setFailedSpy ) . not . toHaveBeenCalled ( ) ;
1576+ } ) ;
1577+
1578+ it . each ( [ 'true' , 'TRUE' , 'True' ] ) (
1579+ 'treats force-mirror=%s as enabled' ,
1580+ async value => {
1581+ inputs [ 'force-mirror' ] = value ;
1582+ inputs [ 'node-version' ] = '12.16.2' ;
1583+ mockDownload ( '12.16.2' ) ;
1584+
1585+ await main . run ( ) ;
1586+
1587+ expect ( getManifestSpy ) . not . toHaveBeenCalled ( ) ;
1588+ expect ( logSpy ) . toHaveBeenCalledWith (
1589+ `'force-mirror' is enabled. Skipping the actions/node-versions manifest and downloading from ${ mirror } /dist`
1590+ ) ;
1591+ }
1592+ ) ;
1593+
1594+ it . each ( [ 'false' , '' , undefined ] ) (
1595+ 'uses the manifest first when force-mirror is %p, even with a mirror set' ,
1596+ async value => {
1597+ inputs [ 'force-mirror' ] = value ;
1598+ inputs [ 'node-version' ] = '12.16.2' ;
1599+ mockDownload ( '12.16.2' ) ;
1600+
1601+ await main . run ( ) ;
1602+
1603+ expect ( getManifestSpy ) . toHaveBeenCalled ( ) ;
1604+ expect ( dlSpy ) . toHaveBeenCalledWith (
1605+ 'https://github.com/actions/node-versions/releases/download/12.16.2-20200507.95/node-12.16.2-linux-x64.tar.gz' ,
1606+ undefined ,
1607+ 'fake-mirror-token'
1608+ ) ;
1609+ expect ( warningSpy ) . not . toHaveBeenCalledWith (
1610+ expect . stringContaining ( 'force-mirror' )
1611+ ) ;
1612+ }
1613+ ) ;
1614+
1615+ it ( 'warns and uses nodejs.org when no mirror is set' , async ( ) => {
1616+ const version = '12.16.2' ;
1617+ inputs [ 'node-version' ] = version ;
1618+ inputs [ 'mirror' ] = '' ;
1619+ inputs [ 'mirror-token' ] = '' ;
1620+ findSpy . mockImplementation ( ( ) => '' ) ;
1621+ dlSpy . mockImplementation ( async ( ) => '/some/temp/path' ) ;
1622+ exSpy . mockImplementation ( async ( ) => '/some/other/temp/path' ) ;
1623+ const toolPath = path . normalize ( `/cache/node/${ version } /x64` ) ;
1624+ cacheSpy . mockImplementation ( async ( ) => toolPath ) ;
1625+ mockNodeVersion ( version ) ;
1626+
1627+ await main . run ( ) ;
1628+
1629+ expect ( warningSpy ) . toHaveBeenCalledWith (
1630+ '`force-mirror` is enabled but `mirror` is not set. Node.js will be downloaded directly from https://nodejs.org.'
1631+ ) ;
1632+ expect ( getManifestSpy ) . not . toHaveBeenCalled ( ) ;
1633+ expect ( dlSpy ) . toHaveBeenCalledWith (
1634+ `https://nodejs.org/dist/v${ version } /node-v${ version } -linux-x64.tar.gz` ,
1635+ undefined ,
1636+ ''
1637+ ) ;
1638+ } ) ;
1639+ } ) ;
13701640} ) ;
0 commit comments