@@ -19,7 +19,6 @@ local USAGE = [[
19
19
20
20
21
21
local KNOWN_KONGERS = { -- include kong alumni here
22
- hishamhm = true ,
23
22
p0pr0ck5 = true ,
24
23
}
25
24
@@ -129,7 +128,12 @@ local function get_comparison_commits(api, from_ref, to_ref)
129
128
local latest_ancestor_iso8601 = os.date (" !%Y-%m-%dT%TZ" , latest_ancestor_epoch )
130
129
131
130
local commits = {}
131
+ -- local count = 0
132
132
for commit in api .iterate_paged (fmt (" /repos/kong/kong/commits?since=%s" , latest_ancestor_iso8601 )) do
133
+ -- if count >= 10 then
134
+ -- return commits
135
+ -- end
136
+ -- count = count + 1
133
137
if datetime_to_epoch (commit .commit .committer .date ) > latest_ancestor_epoch then
134
138
commits [# commits + 1 ] = commit
135
139
-- print("sha: ", commit.sha, ", date: ", commit.commit.committer.date, ", epoch: ", datetime_to_epoch(commit.commit.committer.date))
@@ -171,8 +175,10 @@ local function get_prs_from_comparison_commits(api, commits)
171
175
172
176
-- optimization: preload all commits for this PR into pr_by_commit_sha to avoid unnecessary calls to /repos/kong/kong/commits/%s/pulls
173
177
local pr_commits_res = api .get (fmt (" /repos/kong/kong/pulls/%d/commits?per_page=100" , pr .number ))
174
- for _ , pr_commit in ipairs (pr_commits_res ) do
175
- pr_by_commit_sha [pr_commit .sha ] = pr
178
+ if type (pr_commits_res ) ~= " table" then
179
+ for _ , pr_commit in ipairs (pr_commits_res ) do
180
+ pr_by_commit_sha [pr_commit .sha ] = pr
181
+ end
176
182
end
177
183
end
178
184
pr .commits = pr .commits or {}
@@ -186,6 +192,29 @@ local function get_prs_from_comparison_commits(api, commits)
186
192
end
187
193
188
194
195
+ local function get_prs_from_changelog_hash ()
196
+ print (" \n\n Parsing current changelog" )
197
+ local prs_from_changelog_hash = {}
198
+
199
+ local changelog_filename = " CHANGELOG.md"
200
+
201
+ local f = assert (io.open (changelog_filename , " r" ))
202
+ local line
203
+ repeat
204
+ line = f :read (" *line" )
205
+ if line then
206
+ for pr in line :gmatch (' #(%d%d%d?%d?%d?)' ) do
207
+ io.write (" #" , pr , " , " )
208
+ prs_from_changelog_hash [assert (tonumber (pr ))] = true
209
+ end
210
+ end
211
+ until not line
212
+ f :close ()
213
+
214
+ return prs_from_changelog_hash
215
+ end
216
+
217
+
189
218
local function get_non_konger_authors (api , commits )
190
219
print (" \n\n Finding non-konger authors" )
191
220
local author_logins_hash = {}
@@ -204,7 +233,7 @@ local function get_non_konger_authors(api, commits)
204
233
local _ , status = api .get (fmt (" /orgs/kong/memberships/%s" , login ))
205
234
if status == 404 then
206
235
non_kongers [login ] = true
207
- io.stdout :write (" ✅ " )
236
+ io.stdout :write (" 🌎 " )
208
237
else
209
238
io.stdout :write (" 🦍" )
210
239
end
@@ -217,25 +246,22 @@ end
217
246
218
247
219
248
local function extract_type_and_scope_and_title (str )
220
- local typ , scope , title = string.match (str , " ^([^%(]+)%(([^%)]+)%) (.+)$" )
249
+ local typ , scope , title = string.match (str , " ^([^%(]+)%(([^%)]+)%) ? (.+)$" )
221
250
return typ , scope , title
222
251
end
223
252
224
253
225
- local function get_first_line (str )
226
- return str :match (" ^([^\n ]+)" )
227
- end
228
-
229
- -- Transforms the list of PRs into a shorter table that is easier to get a report out of
254
+ -- Transforms the list of PRs into a shorter table that is organized by author
230
255
local function categorize_prs (prs )
231
256
print (" \n\n Categorizing PRs" )
232
257
local categorized_prs = {}
233
258
local commits , authors_hash
259
+
234
260
for pr_number ,pr in pairs (prs ) do
235
261
commits = {}
236
262
authors_hash = {}
237
263
for _ ,c in ipairs (pr .commits ) do
238
- if c .author and c .author .login then
264
+ if type ( c .author ) == " table " and c .author .login then
239
265
authors_hash [c .author .login ] = true
240
266
end
241
267
commits [# commits + 1 ] = c .commit .message
@@ -257,7 +283,7 @@ local function categorize_prs(prs)
257
283
end
258
284
table.sort (authors )
259
285
260
- categorized_prs [ pr_number ] = {
286
+ table.insert ( categorized_prs , {
261
287
number = pr_number ,
262
288
title = title ,
263
289
typ = typ ,
@@ -266,198 +292,93 @@ local function categorize_prs(prs)
266
292
description = pr .body ,
267
293
commits = commits ,
268
294
authors = authors ,
269
- }
295
+ })
270
296
end
271
297
272
298
return categorized_prs
273
299
end
274
300
275
- -- to_sentence({}) = ""
276
- -- to_sentence({"a"}) = "a"
277
- -- to_sentence({"a", "b"}) = "a and b"
278
- -- to_sentence({"a", "b", "c" }) = "a, b and c"
279
- local function to_sentence (arr )
280
- local buffer = {}
281
- local len = # arr
282
- for i = 1 , len do
283
- buffer [i * 2 - 1 ] = arr [i ]
284
- if i < len - 1 then
285
- buffer [i * 2 ] = " , "
286
- elseif i == len - 1 then
287
- buffer [i * 2 ] = " and "
288
- end
289
- end
290
- return table.concat (buffer )
291
- end
292
-
293
- local function render_pr_li_thank_you (authors , non_kongers_hash )
294
- local non_kongers_links = {}
295
- for _ ,login in ipairs (authors ) do
296
- if non_kongers_hash [login ] then
297
- non_kongers_links [# non_kongers_links + 1 ] = fmt (" [%s](https://github.com/%s)" , login , login )
298
- end
299
- end
300
- if # non_kongers_links == 0 then
301
- return " ."
302
- end
303
- return fmt (" \n Thanks %s for the patch!" , to_sentence (non_kongers_links ))
304
- end
305
-
306
- local function render_pr_li_markdown (pr , non_kongers_hash )
307
- return fmt ([[
308
- - %s
309
- [#%d](%s)%s
310
- ]] , pr .title , pr .number , pr .url , render_pr_li_thank_you (pr .authors , non_kongers_hash ))
301
+ local function pr_needed_in_changelog (pr )
302
+ return pr .typ ~= " tests" and
303
+ pr .typ ~= " hotfix" and
304
+ pr .typ ~= " docs" and
305
+ pr .typ ~= " doc" and
306
+ pr .typ ~= " style" and
307
+ (pr .typ ~= " chore" or pr .scope == " deps" )
311
308
end
312
309
313
310
314
- local function print_report (categorized_prs , non_pr_commits , non_kongers_hash , to_ref )
315
- local pr_numbers = {}
316
- for pr_number in pairs (categorized_prs ) do
317
- pr_numbers [# pr_numbers + 1 ] = pr_number
318
- end
319
- table.sort (pr_numbers )
320
-
311
+ local function print_report (categorized_prs , non_pr_commits , non_kongers_hash , to_ref , prs_from_changelog_hash )
321
312
print (" =================================================" )
322
313
323
- -- Dependencies
324
- local first_dep = true
325
- for _ , pr_number in ipairs (pr_numbers ) do
326
- local pr = categorized_prs [pr_number ]
314
+ local prs_by_author = {}
327
315
328
- if pr .typ == " chore" and (pr .scope == " deps" or pr .scope == " rockspec" ) then
329
- if first_dep then
330
- first_dep = false
331
- print (" \n\n ### Dependencies\n " )
332
- end
333
- pr .reported = true
334
- print (render_pr_li_markdown (pr , non_kongers_hash ))
316
+ for _ ,pr in pairs (categorized_prs ) do
317
+ for _ ,a in ipairs (pr .authors ) do
318
+ prs_by_author [a ] = prs_by_author [a ] or {}
319
+ table.insert (prs_by_author [a ], pr )
335
320
end
336
321
end
337
322
338
-
339
- local categories_markdown = [[
340
- ##### Core
341
-
342
- ##### CLI
343
-
344
- ##### Configuration
345
-
346
- ##### Admin API
347
-
348
- ##### PDK
349
-
350
- ##### Plugins
351
- ]]
352
-
353
- local feats = {}
354
- local fixes = {}
355
- local unknown = {}
356
- for _ , pr_number in ipairs (pr_numbers ) do
357
- local pr = categorized_prs [pr_number ]
358
- if pr .typ == " feat" then
359
- feats [# feats + 1 ] = pr
360
- elseif pr .typ == " fix" then
361
- fixes [# fixes + 1 ] = pr
362
- elseif not pr .reported then
363
- unknown [# unknown + 1 ] = pr
364
- end
323
+ for author , prs in pairs (prs_by_author ) do
324
+ table.sort (prs , function (pra , prb )
325
+ return pra .number < prb .number
326
+ end )
365
327
end
366
328
367
- local sort_by_scope = function (a ,b )
368
- if a .scope == b .scope then
369
- return a .number < b .number
370
- end
371
- return a .scope < b .scope
329
+ local authors_array = {}
330
+ for author in pairs (prs_by_author ) do
331
+ table.insert (authors_array , author )
372
332
end
373
- table.sort (feats , sort_by_scope )
374
- table.sort (fixes , sort_by_scope )
375
- table.sort (unknown , sort_by_scope )
376
-
377
- for i , pr in ipairs (feats ) do
378
- if i == 1 then
379
- print ([[
380
-
381
-
382
- ### Additions
383
-
384
- Note: Categorize the additions below into one of these categories (add categories if needed).
385
- Remove this note
386
-
387
- ]] , categories_markdown )
333
+ table.sort (authors_array , function (a ,b )
334
+ return non_kongers_hash [a ] or non_kongers_hash [b ] or a < b
335
+ end )
336
+
337
+ for _ ,author in ipairs (authors_array ) do
338
+ print (" \n\n ## " , author , non_kongers_hash [author ] and " 🌎" or " 🦍" , " \n " )
339
+
340
+ local prs = prs_by_author [author ]
341
+ local in_changelog_prs = {}
342
+ local non_changelog_prs = {}
343
+ local candidate_changelog_prs = {}
344
+ for _ ,pr in ipairs (prs ) do
345
+ if (prs_from_changelog_hash [pr .number ]) then
346
+ table.insert (in_changelog_prs , pr )
347
+ elseif pr_needed_in_changelog (pr ) then
348
+ table.insert (candidate_changelog_prs , pr )
349
+ else
350
+ table.insert (non_changelog_prs , pr )
351
+ end
388
352
end
389
- print (render_pr_li_markdown (pr , non_kongers_hash ))
390
- end
391
353
392
- for i , pr in ipairs (fixes ) do
393
- if i == 1 then
394
- print ([[
395
-
396
-
397
- ### Fixes
398
-
399
- Note: Categorize the fixes below into one of these categories (add categories if needed).
400
- Remove this note
401
-
402
- ]] , categories_markdown )
354
+ if # candidate_changelog_prs > 0 then
355
+ print (" \n Probably need to be in changelog:" )
356
+ for i ,pr in ipairs (candidate_changelog_prs ) do
357
+ print (fmt (" - [#%d %s/%s %s](%s)" , pr .number , pr .typ , pr .scope , pr .title , pr .url ))
358
+ -- print(pr.description)
359
+ -- for _,c in ipairs(pr.commits) do
360
+ -- print(fmt(" - %s", c))
361
+ -- end
362
+ end
403
363
end
404
- print (render_pr_li_markdown (pr , non_kongers_hash ))
405
- end
406
-
407
-
408
- for i , pr in ipairs (unknown ) do
409
- if i == 1 then
410
- print ([[
411
364
412
-
413
- ### Unknown PRs
414
-
415
- The following PRs could not be identified as either fixes or feats. Please move them to their appropiate place or discard them.
416
- Remove this whole section afterwards.
417
-
418
- ]] )
365
+ if # non_changelog_prs > 0 then
366
+ print (" \n Probably *not* needed on changelog (by type of pr):" )
367
+ for i ,pr in ipairs (non_changelog_prs ) do
368
+ print (fmt (" - [#%d %s/%s %s](%s)" , pr .number , pr .typ , pr .scope , pr .title , pr .url ))
369
+ end
419
370
end
420
371
421
- print (fmt ([[
422
- - %s
423
- [#%d](%s)%s
424
- Categorization: %s(%s)
425
- Commits:]] ,
426
- pr .title , pr .number , pr .url , render_pr_li_thank_you (pr .authors , non_kongers_hash ), pr .typ , pr .scope ))
427
-
428
- for _ , commit in ipairs (pr .commits ) do
429
- print (fmt ([[
430
- - %s]] , get_first_line (commit )))
372
+ if # in_changelog_prs > 0 then
373
+ print (" \n Already detected in changelog (by PR number): " )
374
+ for i ,pr in ipairs (in_changelog_prs ) do
375
+ print (fmt (" - [#%d %s/%s %s](%s)" , pr .number , pr .typ , pr .scope , pr .title , pr .url ))
376
+ end
431
377
end
432
- end
433
-
434
378
435
- for i ,commit in ipairs (non_pr_commits ) do
436
- if i == 1 then
437
- print (fmt ([[
438
379
439
- ### Non-PR commits
440
380
441
- I could not find the PR for the following commits. They are likely direct pushes against %s.
442
-
443
- ]] , to_ref ))
444
- end
445
-
446
- local msg = commit .commit .message
447
- local typ , scope = extract_type_and_scope_and_title (msg )
448
- if not typ then
449
- typ , scope = " unknown" , " unknown"
450
- end
451
- local author = commit .author and (commit .author .login or commit .author .name ) or " unknown"
452
-
453
- print (fmt ([[
454
- - %s
455
- [%s](%s)
456
- Categorization: %s(%s)
457
- Author: %s
458
- ]] , get_first_line (msg ), commit .sha , commit .html_url , typ , scope , author ))
459
381
end
460
-
461
382
end
462
383
463
384
@@ -477,8 +398,10 @@ local commits = get_comparison_commits(api, from_ref, to_ref)
477
398
478
399
local prs , non_pr_commits = get_prs_from_comparison_commits (api , commits )
479
400
401
+ local prs_from_changelog_hash = get_prs_from_changelog_hash ()
402
+
480
403
local categorized_prs = categorize_prs (prs )
481
404
482
405
local non_kongers_hash = get_non_konger_authors (api , commits )
483
406
484
- print_report (categorized_prs , non_pr_commits , non_kongers_hash , to_ref )
407
+ print_report (categorized_prs , non_pr_commits , non_kongers_hash , to_ref , prs_from_changelog_hash )
0 commit comments