@@ -11,8 +11,11 @@ import {
11
11
checkoutOnSecurityReleaseBranch ,
12
12
commitAndPushVulnerabilitiesJSON ,
13
13
getSummary ,
14
- validateDate
14
+ validateDate ,
15
+ promptDependencies ,
16
+ getSupportedVersions
15
17
} from './security-release/security-release.js' ;
18
+ import _ from 'lodash' ;
16
19
17
20
export default class SecurityReleaseSteward {
18
21
repository = NEXT_SECURITY_RELEASE_REPOSITORY ;
@@ -54,9 +57,11 @@ export default class SecurityReleaseSteward {
54
57
55
58
// choose the reports to include in the security release
56
59
const reports = await release . chooseReports ( cli ) ;
60
+ const depUpdates = await release . getDependencyUpdates ( { cli } ) ;
61
+ const deps = _ . groupBy ( depUpdates , 'name' ) ;
57
62
58
63
// create the vulnerabilities.json file in the security-release repo
59
- const filePath = await release . createVulnerabilitiesJSON ( reports , { cli } ) ;
64
+ const filePath = await release . createVulnerabilitiesJSON ( reports , deps , { cli } ) ;
60
65
61
66
// review the vulnerabilities.json file
62
67
const review = await release . promptReviewVulnerabilitiesJSON ( cli ) ;
@@ -212,10 +217,11 @@ class PrepareSecurityRelease {
212
217
return selectedReports ;
213
218
}
214
219
215
- async createVulnerabilitiesJSON ( reports , { cli } ) {
220
+ async createVulnerabilitiesJSON ( reports , dependencies , { cli } ) {
216
221
cli . separator ( 'Creating vulnerabilities.json...' ) ;
217
222
const file = JSON . stringify ( {
218
- reports
223
+ reports,
224
+ dependencies
219
225
} , null , 2 ) ;
220
226
221
227
const folderPath = path . join ( process . cwd ( ) , NEXT_SECURITY_RELEASE_FOLDER ) ;
@@ -259,4 +265,54 @@ class PrepareSecurityRelease {
259
265
}
260
266
process . exit ( 1 ) ;
261
267
}
268
+
269
+ async getDependencyUpdates ( { cli } ) {
270
+ const deps = [ ] ;
271
+ cli . log ( '\n' ) ;
272
+ cli . separator ( 'Dependency Updates' ) ;
273
+ const updates = await cli . prompt ( 'Are there dependency updates in this security release?' , {
274
+ defaultAnswer : true ,
275
+ questionType : 'confirm'
276
+ } ) ;
277
+
278
+ if ( ! updates ) return deps ;
279
+
280
+ const supportedVersions = await getSupportedVersions ( ) ;
281
+
282
+ let asking = true ;
283
+ while ( asking ) {
284
+ const dep = await promptDependencies ( cli ) ;
285
+ if ( ! dep ) {
286
+ asking = false ;
287
+ break ;
288
+ }
289
+
290
+ const name = await cli . prompt ( 'What is the name of the dependency that has been updated?' , {
291
+ defaultAnswer : '' ,
292
+ questionType : 'input'
293
+ } ) ;
294
+
295
+ const versions = await cli . prompt ( 'Which release line does this dependency update affect?' , {
296
+ defaultAnswer : supportedVersions ,
297
+ questionType : 'input'
298
+ } ) ;
299
+
300
+ try {
301
+ const prUrl = dep . replace ( 'https://github.com/' , 'https://api.github.com/repos/' ) . replace ( 'pull' , 'pulls' ) ;
302
+ const res = await this . req . getPullRequest ( prUrl ) ;
303
+ const { html_url, title } = res ;
304
+ deps . push ( {
305
+ name,
306
+ url : html_url ,
307
+ title,
308
+ affectedVersions : versions . split ( ',' ) . map ( ( v ) => v . replace ( 'v' , '' ) . trim ( ) )
309
+ } ) ;
310
+ cli . separator ( ) ;
311
+ } catch ( error ) {
312
+ this . cli . error ( 'Invalid PR url. Please provide a valid PR url.' ) ;
313
+ this . cli . error ( error ) ;
314
+ }
315
+ }
316
+ return deps ;
317
+ }
262
318
}
0 commit comments