@@ -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,262 @@ 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 . spyOn ( inputs , 'getJobParameters' ) . mockReturnValue (
1248+ new inputs . JobParameters (
1249+ 1 ,
1250+ 'xxx' ,
1251+ 'yyy' ,
1252+ 'https://example.com' ,
1253+ '172.17.0.1' ,
1254+ 'image/name:tag' ,
1255+ 'dotcom'
1256+ )
1257+ )
1258+
1259+ markJobAsProcessedSpy = jest . spyOn (
1260+ ApiClient . prototype ,
1261+ 'markJobAsProcessed'
1262+ )
1263+ markJobAsProcessedSpy . mockImplementation ( jest . fn ( ) )
1264+ reportJobErrorSpy = jest . spyOn ( ApiClient . prototype , 'reportJobError' )
1265+ reportJobErrorSpy . mockImplementation ( jest . fn ( ) )
1266+ jest
1267+ . spyOn ( ApiClient . prototype , 'getCredentials' )
1268+ . mockImplementation ( jest . fn ( async ( ) => [ ] ) )
1269+
1270+ jest . spyOn ( core , 'info' ) . mockImplementation ( jest . fn ( ) )
1271+ jest . spyOn ( core , 'warning' ) . mockImplementation ( jest . fn ( ) )
1272+ jest . spyOn ( core , 'setFailed' ) . mockImplementation ( jest . fn ( ) )
1273+ jest . spyOn ( core , 'startGroup' ) . mockImplementation ( jest . fn ( ) )
1274+ jest . spyOn ( core , 'endGroup' ) . mockImplementation ( jest . fn ( ) )
1275+ } )
1276+
1277+ afterEach ( async ( ) => {
1278+ jest . clearAllMocks ( )
1279+ } )
1280+
1281+ describe ( 'when the dependabot-use-cli experiment is enabled' , ( ) => {
1282+ beforeEach ( ( ) => {
1283+ jest . spyOn ( ApiClient . prototype , 'getJobDetails' ) . mockImplementationOnce (
1284+ jest . fn ( async ( ) => {
1285+ return {
1286+ 'package-manager' : 'npm_and_yarn' ,
1287+ experiments : { 'dependabot-use-cli' : true }
1288+ } as unknown as JobDetails
1289+ } )
1290+ )
1291+ jest . spyOn ( cliRunner , 'runDependabotCLI' ) . mockResolvedValue ( undefined )
1292+ context = new Context ( )
1293+ } )
1294+
1295+ test ( 'it uses the CLI runner with hyphenated experiment name' , async ( ) => {
1296+ await run ( context )
1297+
1298+ expect ( cliRunner . runDependabotCLI ) . toHaveBeenCalled ( )
1299+ expect ( Updater ) . not . toHaveBeenCalled ( )
1300+ } )
1301+ } )
1302+
1303+ describe ( 'when the dependabot-use-cli experiment is not set' , ( ) => {
1304+ beforeEach ( ( ) => {
1305+ jest . spyOn ( ApiClient . prototype , 'getJobDetails' ) . mockImplementationOnce (
1306+ jest . fn ( async ( ) => {
1307+ return {
1308+ 'package-manager' : 'npm_and_yarn' ,
1309+ experiments : { }
1310+ } as unknown as JobDetails
1311+ } )
1312+ )
1313+ context = new Context ( )
1314+ } )
1315+
1316+ test ( 'it follows the standard Docker-based flow' , async ( ) => {
1317+ await run ( context )
1318+
1319+ expect ( cliRunner . runDependabotCLI ) . not . toHaveBeenCalled ( )
1320+ } )
1321+ } )
1322+
1323+ describe ( 'when the CLI runner fails' , ( ) => {
1324+ beforeEach ( ( ) => {
1325+ jest . spyOn ( ApiClient . prototype , 'getJobDetails' ) . mockImplementationOnce (
1326+ jest . fn ( async ( ) => {
1327+ return {
1328+ 'package-manager' : 'npm_and_yarn' ,
1329+ experiments : { 'dependabot-use-cli' : true }
1330+ } as unknown as JobDetails
1331+ } )
1332+ )
1333+ jest
1334+ . spyOn ( cliRunner , 'runDependabotCLI' )
1335+ . mockRejectedValue ( new Error ( 'CLI failed' ) )
1336+ context = new Context ( )
1337+ } )
1338+
1339+ test ( 'it reports the error to the API' , async ( ) => {
1340+ await run ( context )
1341+
1342+ expect ( reportJobErrorSpy ) . toHaveBeenCalledWith (
1343+ expect . objectContaining ( {
1344+ 'error-type' : 'actions_workflow_updater' ,
1345+ 'error-details' : { 'action-error' : 'CLI failed' }
1346+ } )
1347+ )
1348+ expect ( markJobAsProcessedSpy ) . toHaveBeenCalled ( )
1349+ } )
1350+
1351+ test ( 'it sets the action as failed' , async ( ) => {
1352+ await run ( context )
1353+
1354+ expect ( core . setFailed ) . toHaveBeenCalledWith (
1355+ expect . stringContaining (
1356+ 'Dependabot CLI encountered an error performing the update'
1357+ )
1358+ )
1359+ } )
1360+ } )
1361+
1362+ describe ( 'when the CLI runner fails with a non-Error value' , ( ) => {
1363+ beforeEach ( ( ) => {
1364+ jest . spyOn ( ApiClient . prototype , 'getJobDetails' ) . mockImplementationOnce (
1365+ jest . fn ( async ( ) => {
1366+ return {
1367+ 'package-manager' : 'npm_and_yarn' ,
1368+ experiments : { 'dependabot-use-cli' : true }
1369+ } as unknown as JobDetails
1370+ } )
1371+ )
1372+ jest . spyOn ( cliRunner , 'runDependabotCLI' ) . mockRejectedValue ( 'CLI failed' )
1373+ context = new Context ( )
1374+ } )
1375+
1376+ test ( 'it reports the error to the API' , async ( ) => {
1377+ await run ( context )
1378+
1379+ expect ( reportJobErrorSpy ) . toHaveBeenCalledWith (
1380+ expect . objectContaining ( {
1381+ 'error-type' : 'actions_workflow_updater' ,
1382+ 'error-details' : { 'action-error' : 'CLI failed' }
1383+ } )
1384+ )
1385+ expect ( markJobAsProcessedSpy ) . toHaveBeenCalled ( )
1386+ } )
1387+
1388+ test ( 'it sets the action as failed' , async ( ) => {
1389+ await run ( context )
1390+
1391+ expect ( core . setFailed ) . toHaveBeenCalledWith (
1392+ expect . stringContaining (
1393+ 'Dependabot CLI encountered an error performing the update'
1394+ )
1395+ )
1396+ } )
1397+ } )
1398+
1399+ describe ( 'when running on GitHub Enterprise Server' , ( ) => {
1400+ beforeEach ( ( ) => {
1401+ jest . spyOn ( inputs , 'getJobParameters' ) . mockReturnValue (
1402+ new inputs . JobParameters (
1403+ 1 ,
1404+ 'xxx' ,
1405+ 'yyy' ,
1406+ 'https://example.com' ,
1407+ '172.17.0.1' ,
1408+ 'image/name:tag' ,
1409+ 'ghes'
1410+ )
1411+ )
1412+ jest . spyOn ( ApiClient . prototype , 'getJobDetails' ) . mockImplementationOnce (
1413+ jest . fn ( async ( ) => {
1414+ return {
1415+ 'package-manager' : 'npm_and_yarn' ,
1416+ experiments : { 'dependabot-use-cli' : true }
1417+ } as unknown as JobDetails
1418+ } )
1419+ )
1420+ context = new Context ( )
1421+ } )
1422+
1423+ test ( 'it does not use the CLI runner' , async ( ) => {
1424+ await run ( context )
1425+
1426+ expect ( cliRunner . runDependabotCLI ) . not . toHaveBeenCalled ( )
1427+ } )
1428+ } )
1429+
1430+ describe ( 'when running in proxima environment' , ( ) => {
1431+ beforeEach ( ( ) => {
1432+ jest . spyOn ( inputs , 'getJobParameters' ) . mockReturnValue (
1433+ new inputs . JobParameters (
1434+ 1 ,
1435+ 'xxx' ,
1436+ 'yyy' ,
1437+ 'https://example.com' ,
1438+ '172.17.0.1' ,
1439+ 'image/name:tag' ,
1440+ 'proxima'
1441+ )
1442+ )
1443+ jest . spyOn ( ApiClient . prototype , 'getJobDetails' ) . mockImplementationOnce (
1444+ jest . fn ( async ( ) => {
1445+ return {
1446+ 'package-manager' : 'npm_and_yarn' ,
1447+ experiments : { 'dependabot-use-cli' : true }
1448+ } as unknown as JobDetails
1449+ } )
1450+ )
1451+ jest . spyOn ( cliRunner , 'runDependabotCLI' ) . mockResolvedValue ( undefined )
1452+ context = new Context ( )
1453+ } )
1454+
1455+ test ( 'it uses the CLI runner' , async ( ) => {
1456+ await run ( context )
1457+
1458+ expect ( cliRunner . runDependabotCLI ) . toHaveBeenCalled ( )
1459+ } )
1460+ } )
1461+ } )
1462+
1463+ describe ( 'isCliAllowedForEnvironment' , ( ) => {
1464+ test ( 'returns true when environment is dotcom' , ( ) => {
1465+ expect ( isCliAllowedForEnvironment ( 'dotcom' ) ) . toBe ( true )
1466+ } )
1467+
1468+ test ( 'returns true when environment is proxima' , ( ) => {
1469+ expect ( isCliAllowedForEnvironment ( 'proxima' ) ) . toBe ( true )
1470+ } )
1471+
1472+ test ( 'returns false when environment is ghes' , ( ) => {
1473+ expect ( isCliAllowedForEnvironment ( 'ghes' ) ) . toBe ( false )
1474+ } )
1475+
1476+ test ( 'returns false when environment is undefined' , ( ) => {
1477+ expect ( isCliAllowedForEnvironment ( undefined ) ) . toBe ( false )
1478+ } )
1479+
1480+ test ( 'returns false when environment is empty string' , ( ) => {
1481+ expect ( isCliAllowedForEnvironment ( '' ) ) . toBe ( false )
1482+ } )
1483+
1484+ test ( 'returns false when environment is unknown' , ( ) => {
1485+ expect ( isCliAllowedForEnvironment ( 'unknown' ) ) . toBe ( false )
1486+ } )
1487+ } )
0 commit comments