11'use strict'
2+
23/*
34Usage:
45
@@ -13,107 +14,87 @@ the result to the changelog.
1314*/
1415const execSync = require ( 'child_process' ) . execSync
1516const branch = process . argv [ 2 ] || 'origin/latest'
16- const log = execSync ( `git log --reverse --pretty='format:%h %H%d %s (%aN)%n%b%n---%n ' ${ branch } ...` )
17+ const log = execSync ( `git log --reverse --pretty='format:%h' ${ branch } ...` )
1718 . toString ( )
1819 . split ( / \n / )
1920
20- main ( )
21-
22- function shortname ( url ) {
23- const matched =
24- url . match ( / h t t p s : \/ \/ g i t h u b \. c o m \/ ( [ ^ / ] + \/ [ ^ / ] + ) \/ (?: p u l l | i s s u e s ) \/ ( \d + ) / ) ||
25- url . match ( / h t t p s : \/ \/ ( n p m \. c o m m u n i t y ) \/ t \/ (?: [ ^ / ] + \/ ) ( \d + ) / )
26- if ( ! matched ) {
27- return false
21+ function printCommit ( c ) {
22+ console . log ( `* [\`${ c . hash } \`](${ c . url } )` )
23+ for ( const pr of c . prs ) {
24+ console . log ( ` [#${ pr . number } ](${ pr . url } )` )
2825 }
29- const repo = matched [ 1 ]
30- const id = matched [ 2 ]
31- if ( repo !== 'npm/cli' ) {
32- return ` ${ repo } # ${ id } `
33- } else {
34- return `# ${ id } `
26+ console . log ( ` ${ c . message } ` )
27+ // no credit for deps commits
28+ if ( ! c . message . startsWith ( 'deps' ) ) {
29+ for ( const user of c . credit ) {
30+ console . log ( ` ([ ${ user . name } ]( ${ user . url } ))` )
31+ }
3532 }
3633}
3734
38- function printCommit ( c ) {
39- console . log ( `* [\`${ c . shortid } \`](https://github.com/npm/cli/commit/${ c . fullid } )` )
40- if ( c . fixes . length ) {
41- for ( const fix of c . fixes ) {
42- const label = shortname ( fix )
43- if ( label ) {
44- console . log ( ` [${ label } ](${ fix } )` )
35+ const main = async ( ) => {
36+ const query = `
37+ fragment commitCredit on GitObject {
38+ ... on Commit {
39+ messageHeadline
40+ url
41+ authors (first:10) {
42+ nodes {
43+ user {
44+ login
45+ url
46+ }
47+ email
48+ name
49+ }
50+ }
51+ associatedPullRequests (first:10) {
52+ nodes {
53+ number
54+ url
55+ merged
56+ }
57+ }
4558 }
4659 }
47- } else if ( c . prurl ) {
48- const label = shortname ( c . prurl )
49- if ( label ) {
50- console . log ( ` [${ label } ](${ c . prurl } )` )
51- } else {
52- console . log ( ` [#](${ c . prurl } )` )
60+
61+ query {
62+ repository (owner:"npm", name:"cli") {
63+ ${ log . map ( ( sha ) => `_${ sha } : object (expression: "${ sha } ") {
64+ ...commitCredit
65+ }` ) . join ( '\n' ) }
66+ }
5367 }
54- }
55- const msg = c . message
56- . replace ( / ^ \s + / gm, '' )
57- . replace ( / ^ [ - a - z ] + : / , '' )
58- . replace ( / ^ / gm, ' ' )
59- . replace ( / ^ { 2 } R e v i e w e d - b y : @ .* / gm, '' )
60- . replace ( / \n $ / , '' )
61- // backtickify package@version
62- . replace ( / ^ ( \s * @ ? [ ^ @ \s ] + @ \d + [ . ] \d + [ . ] \d + ) \b ( \s * \S ) / g, '$1:$2' )
63- . replace ( / ( (?: \b | @ ) [ ^ @ \s ] + @ \d + [ . ] \d + [ . ] \d + ) \b / g, '`$1`' )
64- // linkify commitids
65- . replace ( / \b ( [ a - f 0 - 9 ] { 7 , 8 } ) \b / g, '[`$1`](https://github.com/npm/cli/commit/$1)' )
66- console . log ( msg )
67- // don't assign credit for dep updates
68- if ( ! / ^ { 2 } ` [ ^ ` ] + @ \d + \. \d + \. \d + [ ^ ` ] * ` : ? $ / m. test ( msg ) ) {
69- if ( c . credit ) {
70- c . credit . forEach ( function ( credit ) {
71- console . log ( ` ([@${ credit } ](https://github.com/${ credit } ))` )
72- } )
73- } else {
74- console . log ( ` ([@${ c . author } ](https://github.com/${ c . author } ))` )
68+ `
69+
70+ const response = execSync ( `gh api graphql -f query='${ query } '` ) . toString ( )
71+ const body = JSON . parse ( response )
72+
73+ for ( const [ hash , data ] of Object . entries ( body . data . repository ) ) {
74+ const commit = {
75+ hash : hash . slice ( 1 ) , // remove leading _
76+ url : data . url ,
77+ message : data . messageHeadline . replace ( / \( # \d + \) $ / , '' ) ,
78+ prs : data . associatedPullRequests . nodes . filter ( ( pull ) => pull . merged ) ,
79+ credit : data . authors . nodes . map ( ( author ) => {
80+ if ( author . user && author . user . login ) {
81+ return {
82+ name : `@${ author . user . login } ` ,
83+ url : author . user . url ,
84+ }
85+ }
86+ // if the commit used an email that's not associated with a github account
87+ // then the user field will be empty, so we fall back to using the committer's
88+ // name and email as specified by git
89+ return {
90+ name : author . name ,
91+ url : `mailto:${ author . email } ` ,
92+ }
93+ } ) ,
7594 }
95+
96+ printCommit ( commit )
7697 }
7798}
7899
79- function main ( ) {
80- let commit
81- log . forEach ( function ( line ) {
82- line = line . replace ( / \r / g, '' )
83- let m
84- /* eslint no-cond-assign:0 */
85- if ( / ^ - - - $ / . test ( line ) ) {
86- printCommit ( commit )
87- } else if (
88- ( m = line . match ( / ^ ( [ a - f 0 - 9 ] { 7 , 10 } ) ( [ a - f 0 - 9 ] + ) (?: [ ( ] ( [ ^ ) ] + ) [ ) ] ) ? ( .* ?) [ ( ] ( .* ?) [ ) ] / ) )
89- ) {
90- commit = {
91- shortid : m [ 1 ] ,
92- fullid : m [ 2 ] ,
93- branch : m [ 3 ] ,
94- message : m [ 4 ] ,
95- author : m [ 5 ] ,
96- prurl : null ,
97- fixes : [ ] ,
98- credit : null ,
99- }
100- } else if ( ( m = line . match ( / ^ P R - U R L : ( .* ) / ) ) ) {
101- commit . prurl = m [ 1 ]
102- } else if ( ( m = line . match ( / ^ C r e d i t : @ ( .* ) / ) ) ) {
103- if ( ! commit . credit ) {
104- commit . credit = [ ]
105- }
106- commit . credit . push ( m [ 1 ] )
107- } else if ( ( m = line . match ( / ^ (?: F i x (?: e s ) | C l o s e s ? ) : # ? ( [ 0 - 9 ] + ) / ) ) ) {
108- commit . fixes . push ( `https://github.com/npm/cli/issues/${ m [ 1 ] } ` )
109- } else if ( ( m = line . match ( / ^ (?: F i x (?: e s ) | C l o s e s ? ) : ( [ ^ # ] + ) # ( [ 0 - 9 ] * ) / ) ) ) {
110- commit . fixes . push ( `https://github.com/${ m [ 1 ] } /issues/${ m [ 2 ] } ` )
111- } else if ( ( m = line . match ( / ^ (?: F i x (?: e s ) | C l o s e s ? ) : ( h t t p s ? : \/ \/ .* ) / ) ) ) {
112- commit . fixes . push ( m [ 1 ] )
113- } else if ( ( m = line . match ( / ^ R e v i e w e d - B y : @ ( .* ) / ) ) ) {
114- commit . reviewed = m [ 1 ]
115- } else if ( / \S / . test ( line ) ) {
116- commit . message += `\n${ line } `
117- }
118- } )
119- }
100+ main ( )
0 commit comments