Skip to content

Commit 18cb47d

Browse files
committed
zerocracy#188: implement calculate average hoc and number of files changed in recent merged PRs
1 parent daf2d30 commit 18cb47d

File tree

3 files changed

+159
-0
lines changed

3 files changed

+159
-0
lines changed

judges/quality-of-service/quality-of-service.rb

+16
Original file line numberDiff line numberDiff line change
@@ -95,4 +95,20 @@
9595
)[:total_count]
9696
end
9797
f.average_pull_rejection_rate = pulls.zero? ? 0 : rejected.to_f / pulls
98+
99+
# Average HOC and number of files changed in recent merged PRs
100+
hocs = []
101+
files = []
102+
Fbe.unmask_repos.each do |repo|
103+
Fbe.octo.search_issues(
104+
"repo:#{repo} type:pr is:merged closed:>#{f.since.utc.iso8601[0..9]}"
105+
)[:items].each do |json|
106+
Fbe.octo.pull_request(repo, json[:number]).then do |pull|
107+
hocs << (pull[:additions] + pull[:deletions])
108+
files << pull[:changed_files]
109+
end
110+
end
111+
end
112+
f.average_pull_hoc_size = hocs.empty? ? 0 : hocs.inject(&:+).to_f / hocs.size
113+
f.average_pull_files_size = files.empty? ? 0 : files.inject(&:+).to_f / files.size
98114
end

judges/quality-of-service/simple-collect.yml

+2
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,5 @@ expected:
4646
- /fb/f[average_build_duration != 0]
4747
- /fb/f[average_backlog_size != 0]
4848
- /fb/f[average_pull_rejection_rate != 0]
49+
- /fb/f[average_pull_hoc_size != 0]
50+
- /fb/f[average_pull_files_size != 0]

test/judges/test-quality-of-service.rb

+141
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,17 @@ def test_runs_when_run_duration_ms_is_nil
113113
'content-type': 'application/json'
114114
}
115115
)
116+
stub_github(
117+
'https://api.github.com/search/issues?per_page=100&' \
118+
'q=repo:foo/foo%20type:pr%20is:merged%20closed:%3E2024-07-15',
119+
body: {
120+
total_count: 1, incomplete_results: false, items: [{ id: 50, number: 12, title: 'Awesome 12' }]
121+
}
122+
)
123+
stub_github(
124+
'https://api.github.com/repos/foo/foo/pulls/12',
125+
body: { id: 50, number: 12, additions: 12, deletions: 5, changed_files: 3 }
126+
)
116127
fb = Factbase.new
117128
Time.stub(:now, Time.parse('2024-08-12 21:00:00 UTC')) do
118129
load_it('quality-of-service', fb)
@@ -272,6 +283,18 @@ def test_quality_of_service_average_issues
272283
total_count: 1, incomplete_results: false, items: [{ id: 42, number: 10, title: 'Awesome 10' }]
273284
}
274285
)
286+
stub_github(
287+
'https://api.github.com/search/issues?per_page=100&' \
288+
'q=repo:foo/foo%20type:pr%20is:merged%20closed:%3E2024-08-02',
289+
body: {
290+
total_count: 1, incomplete_results: false,
291+
items: [{ id: 50, number: 12, title: 'Awesome 12' }]
292+
}
293+
)
294+
stub_github(
295+
'https://api.github.com/repos/foo/foo/pulls/12',
296+
body: { id: 50, number: 12, additions: 12, deletions: 5, changed_files: 3 }
297+
)
275298
fb = Factbase.new
276299
f = fb.insert
277300
f.what = 'pmp'
@@ -287,6 +310,124 @@ def test_quality_of_service_average_issues
287310
end
288311
end
289312

313+
def test_quality_of_service_average_hocs_and_files
314+
WebMock.disable_net_connect!
315+
stub_github('https://api.github.com/repos/foo/foo', body: { id: 42, full_name: 'foo/foo' })
316+
stub_github(
317+
'https://api.github.com/repos/foo/foo/actions/runs?created=%3E2024-08-02&per_page=100',
318+
body: { total_count: 0, workflow_runs: [] }
319+
)
320+
stub_github(
321+
'https://api.github.com/repos/foo/foo/releases?per_page=100',
322+
body: []
323+
)
324+
stub_github(
325+
'https://api.github.com/search/issues?per_page=100&q=repo:foo/foo%20type:issue%20closed:%3E2024-08-02',
326+
body: {
327+
total_count: 1, incomplete_results: false, items: [{ number: 42, labels: [{ name: 'bug' }] }]
328+
}
329+
)
330+
stub_github(
331+
'https://api.github.com/search/issues?per_page=100&q=repo:foo/foo%20type:pr%20closed:%3E2024-08-02',
332+
body: {
333+
total_count: 2, incomplete_results: false,
334+
items: [{ id: 42, number: 10, title: 'Awesome 10' }, { id: 43, number: 11, title: 'Awesome 11' }]
335+
}
336+
)
337+
(Date.parse('2024-08-02')..Date.parse('2024-08-09')).each do |date|
338+
stub_github(
339+
'https://api.github.com/search/issues?per_page=100&' \
340+
"q=repo:foo/foo%20type:issue%20created:2024-08-02..#{date}",
341+
body: { total_count: 0, items: [] }
342+
)
343+
end
344+
stub_github(
345+
'https://api.github.com/search/issues?per_page=100&' \
346+
'q=repo:foo/foo%20type:pr%20is:unmerged%20closed:%3E2024-08-02',
347+
body: {
348+
total_count: 1, incomplete_results: false, items: [{ id: 42, number: 10, title: 'Awesome 10' }]
349+
}
350+
)
351+
stub_github(
352+
'https://api.github.com/search/issues?per_page=100&' \
353+
'q=repo:foo/foo%20type:pr%20is:merged%20closed:%3E2024-08-02',
354+
body: {
355+
total_count: 1, incomplete_results: false,
356+
items: [
357+
{ id: 50, number: 12, title: 'Awesome 12' },
358+
{ id: 52, number: 14, title: 'Awesome 14' },
359+
{ id: 54, number: 16, title: 'Awesome 16' },
360+
{ id: 56, number: 18, title: 'Awesome 18' },
361+
{ id: 58, number: 20, title: 'Awesome 20' }
362+
]
363+
}
364+
)
365+
stub_github(
366+
'https://api.github.com/repos/foo/foo/pulls/12',
367+
body: {
368+
id: 50,
369+
number: 12,
370+
additions: 10,
371+
deletions: 5,
372+
changed_files: 1
373+
}
374+
)
375+
stub_github(
376+
'https://api.github.com/repos/foo/foo/pulls/14',
377+
body: {
378+
id: 52,
379+
number: 14,
380+
additions: 0,
381+
deletions: 3,
382+
changed_files: 2
383+
}
384+
)
385+
stub_github(
386+
'https://api.github.com/repos/foo/foo/pulls/16',
387+
body: {
388+
id: 54,
389+
number: 16,
390+
additions: 8,
391+
deletions: 9,
392+
changed_files: 3
393+
}
394+
)
395+
stub_github(
396+
'https://api.github.com/repos/foo/foo/pulls/18',
397+
body: {
398+
id: 56,
399+
number: 18,
400+
additions: 30,
401+
deletions: 7,
402+
changed_files: 4
403+
}
404+
)
405+
stub_github(
406+
'https://api.github.com/repos/foo/foo/pulls/20',
407+
body: {
408+
id: 58,
409+
number: 20,
410+
additions: 20,
411+
deletions: 0,
412+
changed_files: 4
413+
}
414+
)
415+
fb = Factbase.new
416+
f = fb.insert
417+
f.what = 'pmp'
418+
f.area = 'quality'
419+
f.qos_days = 7
420+
f.qos_interval = 3
421+
Time.stub(:now, Time.parse('2024-08-09 21:00:00 UTC')) do
422+
load_it('quality-of-service', fb)
423+
f = fb.query('(eq what "quality-of-service")').each.to_a.first
424+
assert_equal(Time.parse('2024-08-02 21:00:00 UTC'), f.since)
425+
assert_equal(Time.parse('2024-08-09 21:00:00 UTC'), f.when)
426+
assert_in_delta(18.4, f.average_pull_hoc_size)
427+
assert_in_delta(2.8, f.average_pull_files_size)
428+
end
429+
end
430+
290431
def stub_github(url, method = :get, body:, headers: { 'content-type': 'application/json' })
291432
stub_request(method, url).to_return(body: body.to_json, headers:)
292433
end

0 commit comments

Comments
 (0)