@@ -30,7 +30,36 @@ export const PLACEHOLDERS = {
3030 downloads : '%DOWNLOADS%'
3131} ;
3232
33- export function checkRemote ( cli , repository ) {
33+ function formatCommand ( command , args ) {
34+ return [ command , ...args ] . join ( ' ' ) ;
35+ }
36+
37+ export async function confirmSecurityStep ( cli , action , detail ) {
38+ const lines = [ `Allow action: ${ action } ?` ] ;
39+ if ( detail ) {
40+ lines . push ( '' , detail ) ;
41+ }
42+ const message = lines . join ( '\n' ) ;
43+
44+ const allowed = await cli . prompt ( message , { defaultAnswer : false } ) ;
45+ if ( ! allowed ) {
46+ cli . info ( `Aborted: ${ action } .` ) ;
47+ process . exit ( 0 ) ;
48+ }
49+ }
50+
51+ export async function runSecurityGitCommand ( cli , args , detail ) {
52+ const command = formatCommand ( 'git' , args ) ;
53+ await confirmSecurityStep ( cli , `run \`${ command } \`` , detail ) ;
54+ return runSync ( 'git' , args ) ;
55+ }
56+
57+ export async function writeSecurityFile ( cli , filePath , content , detail ) {
58+ await confirmSecurityStep ( cli , `write \`${ filePath } \`` , detail ) ;
59+ return fs . writeFileSync ( filePath , content ) ;
60+ }
61+
62+ export async function checkRemote ( cli , repository ) {
3463 const remote = runSync ( 'git' , [ 'ls-remote' , '--get-url' , 'origin' ] ) . trim ( ) ;
3564 const { owner, repo } = repository ;
3665 const securityReleaseOrigin = [
@@ -44,26 +73,42 @@ export function checkRemote(cli, repository) {
4473 }
4574}
4675
47- export function checkoutOnSecurityReleaseBranch ( cli , repository ) {
48- checkRemote ( cli , repository ) ;
76+ export async function checkoutOnSecurityReleaseBranch ( cli , repository ) {
77+ await checkRemote ( cli , repository ) ;
4978 const currentBranch = runSync ( 'git' , [ 'branch' , '--show-current' ] ) . trim ( ) ;
5079 cli . info ( `Current branch: ${ currentBranch } ` ) ;
5180
5281 if ( currentBranch !== NEXT_SECURITY_RELEASE_BRANCH ) {
53- runSync ( 'git' , [ 'checkout' , '-B' , NEXT_SECURITY_RELEASE_BRANCH ] ) ;
82+ await runSecurityGitCommand (
83+ cli ,
84+ [ 'checkout' , '-B' , NEXT_SECURITY_RELEASE_BRANCH ] ,
85+ `This checks out or recreates the ${ NEXT_SECURITY_RELEASE_BRANCH } branch locally.`
86+ ) ;
5487 cli . ok ( `Checkout on branch: ${ NEXT_SECURITY_RELEASE_BRANCH } ` ) ;
5588 } ;
5689}
5790
58- export function commitAndPushVulnerabilitiesJSON ( filePath , commitMessage , { cli, repository } ) {
59- checkRemote ( cli , repository ) ;
91+ export async function commitAndPushVulnerabilitiesJSON (
92+ filePath ,
93+ commitMessage ,
94+ { cli, repository }
95+ ) {
96+ await checkRemote ( cli , repository ) ;
6097
6198 if ( Array . isArray ( filePath ) ) {
62- for ( const path of filePath ) {
63- runSync ( 'git' , [ 'add' , path ] ) ;
99+ for ( const currentPath of filePath ) {
100+ await runSecurityGitCommand (
101+ cli ,
102+ [ 'add' , currentPath ] ,
103+ `This stages ${ currentPath } for the security release commit.`
104+ ) ;
64105 }
65106 } else {
66- runSync ( 'git' , [ 'add' , filePath ] ) ;
107+ await runSecurityGitCommand (
108+ cli ,
109+ [ 'add' , filePath ] ,
110+ `This stages ${ filePath } for the security release commit.`
111+ ) ;
67112 }
68113
69114 const staged = runSync ( 'git' , [ 'diff' , '--name-only' , '--cached' ] ) . trim ( ) ;
@@ -72,15 +117,31 @@ export function commitAndPushVulnerabilitiesJSON(filePath, commitMessage, { cli,
72117 return ;
73118 }
74119
75- runSync ( 'git' , [ 'commit' , '-m' , commitMessage ] ) ;
120+ await runSecurityGitCommand (
121+ cli ,
122+ [ 'commit' , '-m' , commitMessage ] ,
123+ `This creates a local commit with message: ${ commitMessage } `
124+ ) ;
76125
77126 try {
78- runSync ( 'git' , [ 'push' , '-u' , 'origin' , NEXT_SECURITY_RELEASE_BRANCH ] ) ;
127+ await runSecurityGitCommand (
128+ cli ,
129+ [ 'push' , '-u' , 'origin' , NEXT_SECURITY_RELEASE_BRANCH ] ,
130+ `This pushes the security release branch to origin/${ NEXT_SECURITY_RELEASE_BRANCH } .`
131+ ) ;
79132 } catch ( error ) {
80133 cli . warn ( 'Rebasing...' ) ;
81134 // try to pull rebase and push again
82- runSync ( 'git' , [ 'pull' , 'origin' , NEXT_SECURITY_RELEASE_BRANCH , '--rebase' ] ) ;
83- runSync ( 'git' , [ 'push' , '-u' , 'origin' , NEXT_SECURITY_RELEASE_BRANCH ] ) ;
135+ await runSecurityGitCommand (
136+ cli ,
137+ [ 'pull' , 'origin' , NEXT_SECURITY_RELEASE_BRANCH , '--rebase' ] ,
138+ `This rebases local changes on origin/${ NEXT_SECURITY_RELEASE_BRANCH } .`
139+ ) ;
140+ await runSecurityGitCommand (
141+ cli ,
142+ [ 'push' , '-u' , 'origin' , NEXT_SECURITY_RELEASE_BRANCH ] ,
143+ `This retries pushing the security release branch to origin/${ NEXT_SECURITY_RELEASE_BRANCH } .`
144+ ) ;
84145 }
85146 cli . ok ( `Pushed commit: ${ commitMessage } to ${ NEXT_SECURITY_RELEASE_BRANCH } ` ) ;
86147}
@@ -150,6 +211,11 @@ export function promptDependencies(cli) {
150211}
151212
152213export async function createIssue ( title , content , repository , { cli, req } ) {
214+ await confirmSecurityStep (
215+ cli ,
216+ `create GitHub issue \`${ repository . owner } /${ repository . repo } : ${ title } \`` ,
217+ `This creates an issue in ${ repository . owner } /${ repository . repo } .`
218+ ) ;
153219 const data = await req . createIssue ( title , content , repository ) ;
154220 if ( data . html_url ) {
155221 cli . ok ( `Created: ${ data . html_url } ` ) ;
@@ -252,20 +318,30 @@ export class SecurityRelease {
252318 NEXT_SECURITY_RELEASE_FOLDER , 'vulnerabilities.json' ) ;
253319 }
254320
255- updateReleaseFolder ( releaseDate ) {
321+ async updateReleaseFolder ( releaseDate ) {
256322 const folder = path . join ( process . cwd ( ) ,
257323 NEXT_SECURITY_RELEASE_FOLDER ) ;
258324 const newFolder = path . join ( process . cwd ( ) , 'security-release' , releaseDate ) ;
325+ await confirmSecurityStep (
326+ this . cli ,
327+ `rename \`${ folder } \` to \`${ newFolder } \`` ,
328+ 'This moves the next-security-release folder to the dated release folder.'
329+ ) ;
259330 fs . renameSync ( folder , newFolder ) ;
260331 return newFolder ;
261332 }
262333
263- updateVulnerabilitiesJSON ( content ) {
334+ async updateVulnerabilitiesJSON ( content ) {
264335 try {
265336 const vulnerabilitiesJSONPath = this . getVulnerabilitiesJSONPath ( ) ;
266337 this . cli . startSpinner ( `Updating vulnerabilities.json from ${ vulnerabilitiesJSONPath } ...` ) ;
267- fs . writeFileSync ( vulnerabilitiesJSONPath , JSON . stringify ( content , null , 2 ) ) ;
268- commitAndPushVulnerabilitiesJSON ( vulnerabilitiesJSONPath ,
338+ await writeSecurityFile (
339+ this . cli ,
340+ vulnerabilitiesJSONPath ,
341+ JSON . stringify ( content , null , 2 ) ,
342+ 'This updates vulnerabilities.json with the latest security release data.'
343+ ) ;
344+ await commitAndPushVulnerabilitiesJSON ( vulnerabilitiesJSONPath ,
269345 'chore: updated vulnerabilities.json' ,
270346 { cli : this . cli , repository : this . repository } ) ;
271347 this . cli . stopSpinner ( `Done updating vulnerabilities.json from ${ vulnerabilitiesJSONPath } ` ) ;
0 commit comments