Skip to content

Commit ec9d473

Browse files
authored
Merge pull request #1436 from Shopify/katestud/address-unbounded-paginated-check-runs
Refactor paginated_check_runs to use lazy pagination
2 parents 65e71f5 + 2996d7b commit ec9d473

File tree

2 files changed

+76
-9
lines changed

2 files changed

+76
-9
lines changed

app/models/shipit/commit.rb

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -173,23 +173,21 @@ def paginated_check_runs
173173
stack.github_api.check_runs(github_repo_name, sha, per_page: 100)
174174
end
175175

176-
return response if stack.github_api.last_response.rels[:next].nil?
176+
yield response.check_runs
177177

178-
loop do
178+
until stack.github_api.last_response.rels[:next].nil?
179179
page = stack.handle_github_redirections do
180180
stack.github_api.get(stack.github_api.last_response.rels[:next].href)
181181
end
182-
response.check_runs.concat(page.check_runs)
183-
break if stack.github_api.last_response.rels[:next].nil?
182+
yield page.check_runs
184183
end
185-
186-
response
187184
end
188185

189186
def refresh_check_runs!
190-
response = paginated_check_runs
191-
response.check_runs.each do |check_run|
192-
create_or_update_check_run_from_github!(check_run)
187+
paginated_check_runs do |check_runs|
188+
check_runs.each do |check_run|
189+
create_or_update_check_run_from_github!(check_run)
190+
end
193191
end
194192
end
195193

test/models/commits_test.rb

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,75 @@ class CommitsTest < ActiveSupport::TestCase
367367
assert_equal 'success', @commit.check_runs.first.state
368368
end
369369

370+
test "refresh_check_runs! handles paginated responses from github" do
371+
# First page check runs
372+
check_run1 = mock(
373+
id: 111_111_111_111_111,
374+
name: 'Test suite 1',
375+
conclusion: 'success',
376+
details_url: 'https://example.com/details/1',
377+
html_url: 'https://example.com/run/1',
378+
output: mock(
379+
title: 'Tests build 1 ran successfully'
380+
),
381+
completed_at: Time.now,
382+
started_at: Time.now - 1.minute
383+
)
384+
check_run2 = mock(
385+
id: 222_222_222_222_222,
386+
name: 'Test suite 2',
387+
conclusion: 'failure',
388+
details_url: 'https://example.com/details/2',
389+
html_url: 'https://example.com/run/2',
390+
output: mock(
391+
title: 'Tests build 2 failed'
392+
),
393+
completed_at: Time.now,
394+
started_at: Time.now - 2.minutes
395+
)
396+
397+
# Second page check runs
398+
check_run3 = mock(
399+
id: 333_333_333_333_333,
400+
name: 'Test suite 3',
401+
conclusion: 'success',
402+
details_url: 'https://example.com/details/3',
403+
html_url: 'https://example.com/run/3',
404+
output: mock(
405+
title: 'Tests build 3 skipped'
406+
),
407+
completed_at: Time.now,
408+
started_at: Time.now - 3.minutes
409+
)
410+
411+
next_link = stub(href: 'https://api.github.com/repos/test/repo/check-runs?page=2')
412+
first_response = stub(rels: { next: next_link }, data: mock(check_runs: [check_run1, check_run2]))
413+
second_response = stub(rels: {}, data: mock(check_runs: [check_run3]))
414+
415+
call_sequence = sequence('api_calls')
416+
Shipit.github.api.expects(:check_runs).with(@stack.github_repo_name, @commit.sha, per_page: 100).returns(first_response.data).in_sequence(call_sequence)
417+
Shipit.github.api.expects(:last_response).returns(first_response).in_sequence(call_sequence)
418+
Shipit.github.api.expects(:last_response).returns(first_response).in_sequence(call_sequence)
419+
Shipit.github.api.expects(:get).with(next_link.href).returns(second_response.data).in_sequence(call_sequence)
420+
Shipit.github.api.expects(:last_response).returns(second_response).in_sequence(call_sequence)
421+
422+
assert_difference -> { @commit.check_runs.count }, 3 do
423+
@commit.refresh_check_runs!
424+
end
425+
426+
check1 = @commit.check_runs.find_by(github_id: 111_111_111_111_111)
427+
assert_not_nil check1
428+
assert_equal 'success', check1.state
429+
430+
check2 = @commit.check_runs.find_by(github_id: 222_222_222_222_222)
431+
assert_not_nil check2
432+
assert_equal 'failure', check2.state
433+
434+
check3 = @commit.check_runs.find_by(github_id: 333_333_333_333_333)
435+
assert_not_nil check3
436+
assert_equal 'success', check3.state
437+
end
438+
370439
test "#creating a commit update the undeployed_commits_count" do
371440
walrus = shipit_users(:walrus)
372441
assert_equal 2, @stack.undeployed_commits_count

0 commit comments

Comments
 (0)