@@ -118,17 +118,8 @@ export default class ReleasePromotion extends Session {
118
118
await this . setupForNextRelease ( ) ;
119
119
cli . stopSpinner ( 'Successfully set up for next release' ) ;
120
120
121
- const shouldMergeProposalBranch = await cli . prompt (
122
- 'Merge proposal branch into staging branch?' ) ;
123
- if ( ! shouldMergeProposalBranch ) {
124
- cli . warn ( `Aborting release promotion for version ${ version } ` ) ;
125
- throw new Error ( 'Aborted' ) ;
126
- }
127
-
128
121
// Merge vX.Y.Z-proposal into vX.x.
129
- cli . startSpinner ( 'Merging proposal branch' ) ;
130
122
await this . mergeProposalBranch ( ) ;
131
- cli . stopSpinner ( 'Merged proposal branch' ) ;
132
123
133
124
// Cherry pick release commit to master.
134
125
const shouldCherryPick = await cli . prompt (
@@ -147,7 +138,7 @@ export default class ReleasePromotion extends Session {
147
138
// need to resolve, so confirm they've been resolved before
148
139
// proceeding with next steps.
149
140
cli . separator ( ) ;
150
- cli . info ( 'Resovle the conflicts and commit the result' ) ;
141
+ cli . info ( 'Resolve the conflicts and commit the result' ) ;
151
142
cli . separator ( ) ;
152
143
const didResolveConflicts = await cli . prompt (
153
144
'Finished resolving cherry-pick conflicts?' , { defaultAnswer : true } ) ;
@@ -170,42 +161,11 @@ export default class ReleasePromotion extends Session {
170
161
}
171
162
}
172
163
173
- // Push to the remote default branch
174
- const shouldPushDefaultBranch = await cli . prompt ( `Push to ${ this . branch } ?` ,
175
- { defaultAnswer : true } ) ;
176
- if ( ! shouldPushDefaultBranch ) {
177
- cli . warn ( `Aborting release promotion for version ${ version } ` ) ;
178
- throw new Error ( 'Aborted' ) ;
179
- }
180
- if ( this . dryRun ) {
181
- cli . info ( `Skipping pushing to ${ this . branch } in dry-run mode` ) ;
182
- } else {
183
- await forceRunAsync ( 'git' , [ 'push' , this . upstream , this . branch ] , { ignoreFailure : false } ) ;
184
- }
185
-
186
- // Push release tag.
187
- const shouldPushTag = await cli . prompt ( 'Push release tag?' ,
188
- { defaultAnswer : true } ) ;
189
- if ( ! shouldPushTag ) {
190
- cli . warn ( `Aborting release promotion for version ${ version } ` ) ;
191
- throw new Error ( 'Aborted' ) ;
192
- }
193
- await this . pushReleaseTag ( ) ;
164
+ // Push to the remote default branch and release tag.
165
+ await this . pushTagAndDefaultBranchToRemote ( ) ;
194
166
195
167
// Promote and sign the release builds.
196
- const shouldPromote = await cli . prompt ( 'Promote and sign release builds?' ,
197
- { defaultAnswer : true } ) ;
198
- if ( ! shouldPromote ) {
199
- cli . warn ( `Aborting release promotion for version ${ version } ` ) ;
200
- throw new Error ( 'Aborted' ) ;
201
- }
202
-
203
- // TODO: move this to .ncurc
204
- const defaultKeyPath = '~/.ssh/node_id_rsa' ;
205
- const keyPath = await cli . prompt (
206
- `Please enter the path to your ssh key (Default ${ defaultKeyPath } ): ` ,
207
- { questionType : 'input' , defaultAnswer : defaultKeyPath } ) ;
208
- await this . promoteAndSignRelease ( keyPath ) ;
168
+ await this . promoteAndSignRelease ( ) ;
209
169
210
170
cli . separator ( ) ;
211
171
cli . ok ( `Release promotion for ${ version } complete.\n` ) ;
@@ -218,16 +178,16 @@ export default class ReleasePromotion extends Session {
218
178
' 5. Tag @nodejs-social-team on #nodejs-release Slack channel.\n' ) ;
219
179
220
180
cli . separator ( ) ;
221
- cli . info ( 'Use the following command to create the release:' ) ;
181
+ cli . info ( 'Use the following command to create the GitHub release:' ) ;
222
182
cli . separator ( ) ;
223
183
cli . info (
224
184
'awk \'' +
225
185
`/^## ${ this . date } , Version ${ this . version . replaceAll ( '.' , '\\.' ) } /,` +
226
186
'/^<a id="[0-9]+\\.[0-9]+\\.[0-9]+"><\\x2fa>$/{' +
227
187
'print buf; if(firstLine == "") firstLine = $0; else buf = $0' +
228
188
`}' doc/changelogs/CHANGELOG_V${
229
- this . versionComponents . major } .md | gh release create ${ this . version } --verify-tag --latest= ${
230
- ! this . isLTS } --title=${ JSON . stringify ( this . releaseTitle ) } --notes-file -`) ;
189
+ this . versionComponents . major } .md | gh release create ${ this . version } --verify-tag --latest${
190
+ this . isLTS ? '=false' : '' } --title=${ JSON . stringify ( this . releaseTitle ) } --notes-file -`) ;
231
191
}
232
192
233
193
async verifyPRAttributes ( ) {
@@ -399,42 +359,91 @@ export default class ReleasePromotion extends Session {
399
359
] , { ignoreFailure : false } ) ;
400
360
}
401
361
402
- mergeProposalBranch ( ) {
362
+ async mergeProposalBranch ( ) {
403
363
const { cli, dryRun, stagingBranch, versionComponents } = this ;
364
+ const releaseBranch = `v${ versionComponents . major } .x` ;
365
+
366
+ let prompt = 'Merge proposal branch into staging branch?' ;
404
367
if ( dryRun ) {
405
- cli . info ( 'Skipping merging the proposal branch in dry-run mode' ) ;
406
- return ;
368
+ cli . info ( 'Run the following commands to merge the staging branch:' ) ;
369
+ cli . info ( `git push ${ this . upstream } HEAD:refs/heads/${ releaseBranch } ` ) ;
370
+ cli . info ( `git push ${ this . upstream } HEAD:refs/heads/${ stagingBranch } ` ) ;
371
+ prompt = 'Ready to continue?' ;
407
372
}
408
373
409
- const releaseBranch = `v${ versionComponents . major } .x` ;
374
+ const shouldMergeProposalBranch = await cli . prompt ( prompt , { defaultAnswer : true } ) ;
375
+ if ( ! shouldMergeProposalBranch ) {
376
+ cli . warn ( 'Aborting release promotion' ) ;
377
+ throw new Error ( 'Aborted' ) ;
378
+ } else if ( dryRun ) {
379
+ return ;
380
+ }
410
381
411
382
// TODO: find a solution for key passphrase from the terminal
412
- return Promise . all ( [
383
+ cli . startSpinner ( 'Merging proposal branch' ) ;
384
+ await Promise . all ( [
413
385
forceRunAsync ( 'git' , [ 'push' , this . upstream , `HEAD:refs/heads/${ releaseBranch } ` ] ,
414
386
{ ignoreFailure : false } ) ,
415
387
forceRunAsync ( 'git' , [ 'push' , this . upstream , `HEAD:refs/heads/${ stagingBranch } ` ] ,
416
388
{ ignoreFailure : false } )
417
389
] ) ;
390
+ cli . stopSpinner ( 'Merged proposal branch' ) ;
418
391
}
419
392
420
- pushReleaseTag ( ) {
393
+ async pushTagAndDefaultBranchToRemote ( ) {
421
394
const { cli, dryRun, version } = this ;
395
+ const tagVersion = `v${ version } ` ;
396
+
397
+ let prompt = `Push release tag and ${ this . branch } to ${ this . upstream } ?` ;
422
398
if ( dryRun ) {
423
- cli . info ( 'Skipping pushing the tag in dry-run mode' ) ;
399
+ cli . info ( 'Run the following commands to push to remote:' ) ;
400
+ cli . info ( `git push ${ this . upstream } ${ this . branch } ` ) ;
401
+ cli . info ( `git push ${ this . upstream } ${ tagVersion } ` ) ;
402
+ prompt = 'Ready to continue?' ;
403
+ }
404
+
405
+ const shouldPushTag = await cli . prompt ( prompt , { defaultAnswer : true } ) ;
406
+ if ( ! shouldPushTag ) {
407
+ cli . warn ( 'Aborting release promotion' ) ;
408
+ throw new Error ( 'Aborted' ) ;
409
+ } else if ( dryRun ) {
424
410
return ;
425
411
}
426
412
427
- const tagVersion = `v${ version } ` ;
428
- return forceRunAsync ( 'git' , [ 'push' , this . upstream , tagVersion ] , { ignoreFailure : false } ) ;
413
+ cli . startSpinner ( 'Pushing to remote' ) ;
414
+ await Promise . all ( [
415
+ forceRunAsync ( 'git' , [ 'push' , this . upstream , this . branch ] , { ignoreFailure : false } ) ,
416
+ forceRunAsync ( 'git' , [ 'push' , this . upstream , tagVersion ] , { ignoreFailure : false } )
417
+ ] ) ;
418
+ cli . stopSpinner ( `Pushed ${ tagVersion } and ${ this . branch } to remote` ) ;
429
419
}
430
420
431
- async promoteAndSignRelease ( keyPath ) {
421
+ async promoteAndSignRelease ( ) {
432
422
const { cli, dryRun } = this ;
423
+ let prompt = 'Promote and sign release builds?' ;
424
+
433
425
if ( dryRun ) {
434
- cli . info ( 'Skipping promoting the release in dry-run mode' ) ;
426
+ cli . info ( 'Run the following command to sign and promote the release:' ) ;
427
+ cli . info ( './tools/release.sh -i <keyPath>' ) ;
428
+ prompt = 'Ready to continue?' ;
429
+ }
430
+ const shouldPromote = await cli . prompt ( prompt , { defaultAnswer : true } ) ;
431
+ if ( ! shouldPromote ) {
432
+ cli . warn ( 'Aborting release promotion' ) ;
433
+ throw new Error ( 'Aborted' ) ;
434
+ } else if ( dryRun ) {
435
435
return ;
436
436
}
437
+
438
+ // TODO: move this to .ncurc
439
+ const defaultKeyPath = '~/.ssh/node_id_rsa' ;
440
+ const keyPath = await cli . prompt (
441
+ `Please enter the path to your ssh key (Default ${ defaultKeyPath } ): ` ,
442
+ { questionType : 'input' , defaultAnswer : defaultKeyPath } ) ;
443
+
444
+ cli . startSpinner ( 'Signing and promoting the release' ) ;
437
445
await forceRunAsync ( './tools/release.sh' , [ '-i' , keyPath ] , { ignoreFailure : false } ) ;
446
+ cli . stopSpinner ( 'Release has been signed and promoted' ) ;
438
447
}
439
448
440
449
async cherryPickToDefaultBranch ( ) {
0 commit comments