1
1
import path from 'node:path' ;
2
2
import { promises as fs } from 'node:fs' ;
3
+ import { createInterface } from 'node:readline' ;
4
+ import { spawn } from 'node:child_process' ;
3
5
4
6
import semver from 'semver' ;
5
7
import { replaceInFile } from 'replace-in-file' ;
@@ -19,8 +21,9 @@ import Session from './session.js';
19
21
const isWindows = process . platform === 'win32' ;
20
22
21
23
export default class ReleasePreparation extends Session {
22
- constructor ( argv , cli , dir ) {
24
+ constructor ( argv , request , cli , dir ) {
23
25
super ( cli , dir ) ;
26
+ this . req = request ;
24
27
this . isSecurityRelease = argv . security ;
25
28
this . isLTS = false ;
26
29
this . isLTSTransition = argv . startLTS ;
@@ -176,10 +179,10 @@ export default class ReleasePreparation extends Session {
176
179
// Check the branch diff to determine if the releaser
177
180
// wants to backport any more commits before proceeding.
178
181
cli . startSpinner ( 'Fetching branch-diff' ) ;
179
- const raw = await this . getBranchDiff ( {
182
+ const raw = runSync ( ... await this . getBranchDiff ( {
180
183
onlyNotableChanges : false ,
181
184
comparisonBranch : newVersion
182
- } ) ;
185
+ } ) ) ;
183
186
184
187
const diff = raw . split ( '*' ) ;
185
188
cli . stopSpinner ( 'Got branch diff' ) ;
@@ -414,6 +417,38 @@ export default class ReleasePreparation extends Session {
414
417
} ) ;
415
418
}
416
419
420
+ async fetchNotableChanges ( commitListCmd ) {
421
+ const commitListProcess = spawn ( ...commitListCmd ) ;
422
+ const commitList = createInterface ( { input : commitListProcess . stdout } ) ;
423
+ const commitPattern = / ^ \* \\ \[ \[ ` ( [ a - f 0 - 9 ] + ) ` \] \( h t t p s : \/ \/ g i t h u b \. c o m \/ ( [ ^ / ] + ) \/ ( [ ^ / ] + ) \/ c o m m i t \/ \1\) \] - (?: \* \* \( S E M V E R - M I N O R \) \* \* ) ? ( .+ ) \( ( .+ ) \) \[ # ( \d + ) \] \( h t t p s : \/ \/ g i t h u b \. c o m \/ \2\/ \3\/ p u l l \/ \6\) $ / ;
424
+ const detailsPattern = / (?: ^ | \r ? \n \r ? \n ) < d e t a i l s [ ^ > ] + > < s u m m a r y > N o t a b l e c h a n g e s ? < \/ s u m m a r y > \r ? \n \r ? \n (?: # + ( [ ^ \r \n ] + ) \r ? \n ) ? ( .+ ) \r ? \n \r ? \n < \/ d e t a i l s > (?: \r ? \n \r ? \n | $ ) / s;
425
+ let notableChangesSections = '' ;
426
+ let otherNotableChanges = '' ;
427
+ for await ( const line of commitList ) {
428
+ const { 2 : owner , 3 : repo , 4 : title , 5 : author , 6 : prId } = commitPattern . exec ( line ) ;
429
+ const { repository : { pullRequest : { body, labels } } } = await this . req . gql (
430
+ 'PRNotableChange' ,
431
+ { owner, repo, prId : Number ( prId ) } ) ;
432
+ const notableChangeMd =
433
+ labels . nodes . some ( ( { name } ) => name === 'notable-change' ) &&
434
+ detailsPattern . exec ( body ) ;
435
+ if ( notableChangeMd ) {
436
+ notableChangesSections +=
437
+ `\n#### ${ notableChangeMd [ 1 ] || title } \n${ notableChangeMd [ 2 ] } \nContributed by ${ author } in [#${ prId } ](https://github.com/${ owner } /${ repo } /pull/${ prId } ).\n` ;
438
+ } else {
439
+ otherNotableChanges += line + '\n' ;
440
+ }
441
+ }
442
+
443
+ if ( notableChangesSections . length === 0 ) {
444
+ return otherNotableChanges ;
445
+ }
446
+ if ( otherNotableChanges . length !== 0 ) {
447
+ notableChangesSections += `\n#### Other notable changes\n\n${ otherNotableChanges } ` ;
448
+ }
449
+ return notableChangesSections . slice ( 1 ) ;
450
+ }
451
+
417
452
async updateMainChangelog ( ) {
418
453
const { date, isLTSTransition, versionComponents, newVersion } = this ;
419
454
@@ -476,7 +511,8 @@ export default class ReleasePreparation extends Session {
476
511
const data = await fs . readFile ( majorChangelogPath , 'utf8' ) ;
477
512
const arr = data . split ( '\n' ) ;
478
513
const allCommits = this . getChangelog ( ) ;
479
- const notableChanges = await this . getBranchDiff ( { onlyNotableChanges : true } ) ;
514
+ const notableChanges =
515
+ await this . fetchNotableChanges ( await this . getBranchDiff ( { onlyNotableChanges : true } ) ) ;
480
516
let releaseHeader = `## ${ date } , Version ${ newVersion } ` +
481
517
` ${ releaseInfo } , @${ username } \n` ;
482
518
if ( isSecurityRelease ) {
@@ -612,10 +648,10 @@ export default class ReleasePreparation extends Session {
612
648
messageBody . push ( 'This is a security release.\n\n' ) ;
613
649
}
614
650
615
- const notableChanges = await this . getBranchDiff ( {
651
+ const notableChanges = runSync ( ... await this . getBranchDiff ( {
616
652
onlyNotableChanges : true ,
617
653
format : 'plaintext'
618
- } ) ;
654
+ } ) ) ;
619
655
messageBody . push ( 'Notable changes:\n\n' ) ;
620
656
if ( isLTSTransition ) {
621
657
messageBody . push ( `${ getStartLTSBlurb ( this ) } \n\n` ) ;
@@ -735,12 +771,13 @@ export default class ReleasePreparation extends Session {
735
771
] ;
736
772
}
737
773
738
- const branchDiff = new URL (
739
- '../node_modules/.bin/branch-diff' + ( isWindows ? '.cmd' : '' ) ,
740
- import . meta. url
741
- ) ;
742
-
743
- return runSync ( branchDiff , branchDiffOptions ) ;
774
+ return [
775
+ path . join (
776
+ import . meta. dirname ,
777
+ '../node_modules/.bin/branch-diff' + ( isWindows ? '.cmd' : '' )
778
+ ) ,
779
+ branchDiffOptions
780
+ ] ;
744
781
}
745
782
746
783
async getLastRelease ( major ) {
0 commit comments