@@ -12,13 +12,20 @@ import {Updater} from '../src/updater'
1212import { ImageService , MetricReporter } from '../src/image-service'
1313import { updaterImageName } from '../src/docker-tags'
1414import * as inputs from '../src/inputs'
15- import { run , credentialsFromEnv , getPackagesCredential } from '../src/main'
15+ import {
16+ run ,
17+ credentialsFromEnv ,
18+ getPackagesCredential ,
19+ isCliAllowedForEnvironment
20+ } from '../src/main'
21+ import * as cliRunner from '../src/cli-runner'
1622
1723import { eventFixturePath } from './helpers'
1824
1925// We do not need to build actual containers or run updates for this test.
2026jest . mock ( '../src/image-service' )
2127jest . mock ( '../src/updater' )
28+ jest . mock ( '../src/cli-runner' )
2229
2330describe ( 'run' , ( ) => {
2431 let context : Context
@@ -1219,3 +1226,268 @@ describe('getPackagesCredential', () => {
12191226 } )
12201227 } )
12211228} )
1229+
1230+ describe ( 'run with dependabot-use-cli experiment' , ( ) => {
1231+ let context : Context
1232+ let markJobAsProcessedSpy : any
1233+ let reportJobErrorSpy : any
1234+
1235+ beforeEach ( async ( ) => {
1236+ process . env . GITHUB_EVENT_PATH = eventFixturePath ( 'default' )
1237+ process . env . GITHUB_EVENT_NAME = 'dynamic'
1238+ process . env . GITHUB_ACTOR = 'dependabot[bot]'
1239+ process . env . GITHUB_TRIGGERING_ACTOR = 'dependabot[bot]'
1240+
1241+ process . env . GITHUB_SERVER_URL = 'https://github.com'
1242+ process . env . GITHUB_REPOSITORY = 'foo/bar'
1243+
1244+ process . env . GITHUB_DEPENDABOT_JOB_TOKEN = 'xxx'
1245+ process . env . GITHUB_DEPENDABOT_CRED_TOKEN = 'yyy'
1246+
1247+ jest
1248+ . spyOn ( inputs , 'getJobParameters' )
1249+ . mockReturnValue (
1250+ new inputs . JobParameters (
1251+ 1 ,
1252+ 'xxx' ,
1253+ 'yyy' ,
1254+ 'https://example.com' ,
1255+ '172.17.0.1' ,
1256+ 'image/name:tag' ,
1257+ 'dotcom'
1258+ )
1259+ )
1260+
1261+ markJobAsProcessedSpy = jest . spyOn (
1262+ ApiClient . prototype ,
1263+ 'markJobAsProcessed'
1264+ )
1265+ markJobAsProcessedSpy . mockImplementation ( jest . fn ( ) )
1266+ reportJobErrorSpy = jest . spyOn ( ApiClient . prototype , 'reportJobError' )
1267+ reportJobErrorSpy . mockImplementation ( jest . fn ( ) )
1268+ jest
1269+ . spyOn ( ApiClient . prototype , 'getCredentials' )
1270+ . mockImplementation ( jest . fn ( async ( ) => [ ] ) )
1271+
1272+ jest . spyOn ( core , 'info' ) . mockImplementation ( jest . fn ( ) )
1273+ jest . spyOn ( core , 'warning' ) . mockImplementation ( jest . fn ( ) )
1274+ jest . spyOn ( core , 'setFailed' ) . mockImplementation ( jest . fn ( ) )
1275+ jest . spyOn ( core , 'startGroup' ) . mockImplementation ( jest . fn ( ) )
1276+ jest . spyOn ( core , 'endGroup' ) . mockImplementation ( jest . fn ( ) )
1277+ } )
1278+
1279+ afterEach ( async ( ) => {
1280+ jest . clearAllMocks ( )
1281+ } )
1282+
1283+ describe ( 'when the dependabot-use-cli experiment is enabled' , ( ) => {
1284+ beforeEach ( ( ) => {
1285+ jest . spyOn ( ApiClient . prototype , 'getJobDetails' ) . mockImplementationOnce (
1286+ jest . fn ( async ( ) => {
1287+ return {
1288+ 'package-manager' : 'npm_and_yarn' ,
1289+ experiments : { 'dependabot-use-cli' : true }
1290+ } as unknown as JobDetails
1291+ } )
1292+ )
1293+ jest . spyOn ( cliRunner , 'runDependabotCLI' ) . mockResolvedValue ( undefined )
1294+ context = new Context ( )
1295+ } )
1296+
1297+ test ( 'it uses the CLI runner with hyphenated experiment name' , async ( ) => {
1298+ await run ( context )
1299+
1300+ expect ( cliRunner . runDependabotCLI ) . toHaveBeenCalled ( )
1301+ expect ( Updater ) . not . toHaveBeenCalled ( )
1302+ } )
1303+ } )
1304+
1305+ describe ( 'when the dependabot-use-cli experiment is not set' , ( ) => {
1306+ beforeEach ( ( ) => {
1307+ jest . spyOn ( ApiClient . prototype , 'getJobDetails' ) . mockImplementationOnce (
1308+ jest . fn ( async ( ) => {
1309+ return {
1310+ 'package-manager' : 'npm_and_yarn' ,
1311+ experiments : { }
1312+ } as unknown as JobDetails
1313+ } )
1314+ )
1315+ context = new Context ( )
1316+ } )
1317+
1318+ test ( 'it follows the standard Docker-based flow' , async ( ) => {
1319+ await run ( context )
1320+
1321+ expect ( cliRunner . runDependabotCLI ) . not . toHaveBeenCalled ( )
1322+ } )
1323+ } )
1324+
1325+ describe ( 'when the CLI runner fails' , ( ) => {
1326+ beforeEach ( ( ) => {
1327+ jest . spyOn ( ApiClient . prototype , 'getJobDetails' ) . mockImplementationOnce (
1328+ jest . fn ( async ( ) => {
1329+ return {
1330+ 'package-manager' : 'npm_and_yarn' ,
1331+ experiments : { 'dependabot-use-cli' : true }
1332+ } as unknown as JobDetails
1333+ } )
1334+ )
1335+ jest
1336+ . spyOn ( cliRunner , 'runDependabotCLI' )
1337+ . mockRejectedValue ( new Error ( 'CLI failed' ) )
1338+ context = new Context ( )
1339+ } )
1340+
1341+ test ( 'it reports the error to the API' , async ( ) => {
1342+ await run ( context )
1343+
1344+ expect ( reportJobErrorSpy ) . toHaveBeenCalledWith (
1345+ expect . objectContaining ( {
1346+ 'error-type' : 'actions_workflow_updater' ,
1347+ 'error-details' : { 'action-error' : 'CLI failed' }
1348+ } )
1349+ )
1350+ expect ( markJobAsProcessedSpy ) . toHaveBeenCalled ( )
1351+ } )
1352+
1353+ test ( 'it sets the action as failed' , async ( ) => {
1354+ await run ( context )
1355+
1356+ expect ( core . setFailed ) . toHaveBeenCalledWith (
1357+ expect . stringContaining (
1358+ 'Dependabot CLI encountered an error performing the update'
1359+ )
1360+ )
1361+ } )
1362+ } )
1363+
1364+ describe ( 'when the CLI runner fails with a non-Error value' , ( ) => {
1365+ beforeEach ( ( ) => {
1366+ jest . spyOn ( ApiClient . prototype , 'getJobDetails' ) . mockImplementationOnce (
1367+ jest . fn ( async ( ) => {
1368+ return {
1369+ 'package-manager' : 'npm_and_yarn' ,
1370+ experiments : { 'dependabot-use-cli' : true }
1371+ } as unknown as JobDetails
1372+ } )
1373+ )
1374+ jest . spyOn ( cliRunner , 'runDependabotCLI' ) . mockRejectedValue ( 'CLI failed' )
1375+ context = new Context ( )
1376+ } )
1377+
1378+ test ( 'it reports the error to the API' , async ( ) => {
1379+ await run ( context )
1380+
1381+ expect ( reportJobErrorSpy ) . toHaveBeenCalledWith (
1382+ expect . objectContaining ( {
1383+ 'error-type' : 'actions_workflow_updater' ,
1384+ 'error-details' : { 'action-error' : 'CLI failed' }
1385+ } )
1386+ )
1387+ expect ( markJobAsProcessedSpy ) . toHaveBeenCalled ( )
1388+ } )
1389+
1390+ test ( 'it sets the action as failed' , async ( ) => {
1391+ await run ( context )
1392+
1393+ expect ( core . setFailed ) . toHaveBeenCalledWith (
1394+ expect . stringContaining (
1395+ 'Dependabot CLI encountered an error performing the update'
1396+ )
1397+ )
1398+ } )
1399+ } )
1400+
1401+ describe ( 'when running on GitHub Enterprise Server' , ( ) => {
1402+ beforeEach ( ( ) => {
1403+ jest
1404+ . spyOn ( inputs , 'getJobParameters' )
1405+ . mockReturnValue (
1406+ new inputs . JobParameters (
1407+ 1 ,
1408+ 'xxx' ,
1409+ 'yyy' ,
1410+ 'https://example.com' ,
1411+ '172.17.0.1' ,
1412+ 'image/name:tag' ,
1413+ 'ghes'
1414+ )
1415+ )
1416+ jest . spyOn ( ApiClient . prototype , 'getJobDetails' ) . mockImplementationOnce (
1417+ jest . fn ( async ( ) => {
1418+ return {
1419+ 'package-manager' : 'npm_and_yarn' ,
1420+ experiments : { 'dependabot-use-cli' : true }
1421+ } as unknown as JobDetails
1422+ } )
1423+ )
1424+ context = new Context ( )
1425+ } )
1426+
1427+ test ( 'it does not use the CLI runner' , async ( ) => {
1428+ await run ( context )
1429+
1430+ expect ( cliRunner . runDependabotCLI ) . not . toHaveBeenCalled ( )
1431+ } )
1432+ } )
1433+
1434+ describe ( 'when running in proxima environment' , ( ) => {
1435+ beforeEach ( ( ) => {
1436+ jest
1437+ . spyOn ( inputs , 'getJobParameters' )
1438+ . mockReturnValue (
1439+ new inputs . JobParameters (
1440+ 1 ,
1441+ 'xxx' ,
1442+ 'yyy' ,
1443+ 'https://example.com' ,
1444+ '172.17.0.1' ,
1445+ 'image/name:tag' ,
1446+ 'proxima'
1447+ )
1448+ )
1449+ jest . spyOn ( ApiClient . prototype , 'getJobDetails' ) . mockImplementationOnce (
1450+ jest . fn ( async ( ) => {
1451+ return {
1452+ 'package-manager' : 'npm_and_yarn' ,
1453+ experiments : { 'dependabot-use-cli' : true }
1454+ } as unknown as JobDetails
1455+ } )
1456+ )
1457+ jest . spyOn ( cliRunner , 'runDependabotCLI' ) . mockResolvedValue ( undefined )
1458+ context = new Context ( )
1459+ } )
1460+
1461+ test ( 'it uses the CLI runner' , async ( ) => {
1462+ await run ( context )
1463+
1464+ expect ( cliRunner . runDependabotCLI ) . toHaveBeenCalled ( )
1465+ } )
1466+ } )
1467+ } )
1468+
1469+ describe ( 'isCliAllowedForEnvironment' , ( ) => {
1470+ test ( 'returns true when environment is dotcom' , ( ) => {
1471+ expect ( isCliAllowedForEnvironment ( 'dotcom' ) ) . toBe ( true )
1472+ } )
1473+
1474+ test ( 'returns true when environment is proxima' , ( ) => {
1475+ expect ( isCliAllowedForEnvironment ( 'proxima' ) ) . toBe ( true )
1476+ } )
1477+
1478+ test ( 'returns false when environment is ghes' , ( ) => {
1479+ expect ( isCliAllowedForEnvironment ( 'ghes' ) ) . toBe ( false )
1480+ } )
1481+
1482+ test ( 'returns false when environment is undefined' , ( ) => {
1483+ expect ( isCliAllowedForEnvironment ( undefined ) ) . toBe ( false )
1484+ } )
1485+
1486+ test ( 'returns false when environment is empty string' , ( ) => {
1487+ expect ( isCliAllowedForEnvironment ( '' ) ) . toBe ( false )
1488+ } )
1489+
1490+ test ( 'returns false when environment is unknown' , ( ) => {
1491+ expect ( isCliAllowedForEnvironment ( 'unknown' ) ) . toBe ( false )
1492+ } )
1493+ } )
0 commit comments