@@ -26,6 +26,8 @@ type Config struct {
2626 StopAt int
2727 // IncludeCommits will include commmits messages for each PR.
2828 IncludeCommits bool
29+ // StopAtLatestRelease will stop at latest release commit.
30+ StopAtLatestRelease bool
2931}
3032
3133// BuildReleaseNotes lists GitHub Pull Requests and writes formatted release notes
@@ -53,6 +55,27 @@ func BuildReleaseNotes(ctx context.Context, w io.Writer, conf Config) error {
5355 State : "closed" ,
5456 }
5557
58+ repo , _ , err := cl .Repositories .Get (ctx , conf .Org , conf .Repo )
59+ if err != nil {
60+ return fmt .Errorf ("get repository: %+v" , err )
61+ }
62+
63+ rls , _ , err := cl .Repositories .GetLatestRelease (ctx , conf .Org , conf .Repo )
64+ if err != nil {
65+ return fmt .Errorf ("get latest release: %+v" , err )
66+ }
67+
68+ comp , _ , err := cl .Repositories .CompareCommits (ctx , conf .Org , conf .Repo , rls .GetTagName (), repo .GetDefaultBranch ())
69+ if err != nil {
70+ return fmt .Errorf ("compare commitse: %s..%s %+v" , rls .GetTagName (), repo .GetDefaultBranch (), err )
71+ }
72+
73+ // new commits from latest release to default branch
74+ var newCommits []string
75+ for _ , commit := range comp .Commits {
76+ newCommits = append (newCommits , commit .GetSHA ())
77+ }
78+
5679 // Iterate over all PRs
5780 for {
5881 prs , resp , err := cl .PullRequests .List (ctx , conf .Org , conf .Repo , opt )
@@ -69,40 +92,39 @@ func BuildReleaseNotes(ctx context.Context, w io.Writer, conf Config) error {
6992 continue
7093 }
7194
95+ commits , err := commitsAll (ctx , cl , conf .Org , conf .Repo , pr .GetNumber ())
96+ if err != nil {
97+ return fmt .Errorf ("listing PR commits: %s" , err )
98+ }
99+ var prCommits []string
100+ for _ , commit := range commits {
101+ prCommits = append (prCommits , commit .GetSHA ())
102+ }
103+
104+ if conf .StopAtLatestRelease && ! any (prCommits , newCommits ) {
105+ // stop any new commits do not contains pr commits
106+ return nil
107+ }
108+
72109 fmt .Fprintf (w , "- PR #%d %s\n " , pr .GetNumber (), pr .GetTitle ())
73110
74111 if conf .IncludeCommits {
75112 // Iterate over all commits in this PR.
76- commitOpt := & github.ListOptions {PerPage : 100 }
77- for {
113+ for _ , commit := range commits {
114+ sha := * commit .SHA
115+ msg := * commit .Commit .Message
78116
79- commits , resp , err := cl . PullRequests . ListCommits ( ctx , conf . Org , conf . Repo , pr . GetNumber (), commitOpt )
80- if err != nil {
81- return fmt . Errorf ( "listing PR commits: %s" , err )
117+ // Strip multiple lines (i.e. only take first line )
118+ if i := strings . Index ( msg , " \n " ); i != - 1 {
119+ msg = msg [: i ]
82120 }
83-
84- // Iterate over commits in this page.
85- for _ , commit := range commits {
86- sha := * commit .SHA
87- msg := * commit .Commit .Message
88-
89- // Strip multiple lines (i.e. only take first line)
90- if i := strings .Index (msg , "\n " ); i != - 1 {
91- msg = msg [:i ]
92- }
93- // Trim long lines
94- if len (msg ) > 90 {
95- msg = msg [:90 ] + "..."
96- }
97- msg = strings .TrimSpace (msg )
98-
99- fmt .Fprintf (w , " - %s %s\n " , sha , msg )
121+ // Trim long lines
122+ if len (msg ) > 90 {
123+ msg = msg [:90 ] + "..."
100124 }
125+ msg = strings .TrimSpace (msg )
101126
102- if resp .NextPage == 0 {
103- break
104- }
105- commitOpt .Page = resp .NextPage
127+ fmt .Fprintf (w , " - %s %s\n " , sha , msg )
106128 }
107129 fmt .Fprintln (w )
108130 }
@@ -115,3 +137,40 @@ func BuildReleaseNotes(ctx context.Context, w io.Writer, conf Config) error {
115137 }
116138 return nil
117139}
140+
141+ func contains (a []string , e string ) bool {
142+ for _ , v := range a {
143+ if e == v {
144+ return true
145+ }
146+ }
147+ return false
148+ }
149+
150+ func any (a []string , b []string ) bool {
151+ for _ , c := range a {
152+ if contains (b , c ) {
153+ return true
154+ }
155+ }
156+ return false
157+ }
158+
159+ func commitsAll (ctx context.Context , cl * github.Client , owner string , repo string , num int ) ([]* github.RepositoryCommit , error ) {
160+ var list []* github.RepositoryCommit
161+ commitOpt := & github.ListOptions {PerPage : 100 }
162+ for {
163+ commits , resp , err := cl .PullRequests .ListCommits (ctx , owner , repo , num , commitOpt )
164+ if err != nil {
165+ return nil , fmt .Errorf ("listing PR commits: %s" , err )
166+ }
167+
168+ list = append (list , commits ... )
169+
170+ if resp .NextPage == 0 {
171+ break
172+ }
173+ commitOpt .Page = resp .NextPage
174+ }
175+ return list , nil
176+ }
0 commit comments