Skip to content

Commit 2479a84

Browse files
Merge pull request #98 from RodrigoMNardi/bug/github/check_run/failed_to_update_ci
GitHub CI Sync
2 parents 3c1d6bf + 869e387 commit 2479a84

9 files changed

Lines changed: 95 additions & 61 deletions

File tree

.simplecov

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
SimpleCov.start do
1212
enable_coverage :branch
1313
primary_coverage :branch
14-
add_filter %r{^/spec/}
14+
add_filter %r{^/(spec|config)/}
1515
add_filter 'database_loader.rb'
1616
add_group 'Models', 'lib/models'
1717
add_group 'GitHub Functions', 'lib/github'

config/delayed_job.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ class << self
2020
end
2121
end
2222

23-
DELAYED_JOB_TIMER = 5
23+
DELAYED_JOB_TIMER = 30
2424

2525
Rails.logger = GithubLogger.instance.create('delayed_job.log', Logger::INFO)
2626
ActiveRecord::Base.logger = GithubLogger.instance.create('delayed_job.log', Logger::INFO)
@@ -34,5 +34,9 @@ class << self
3434
Delayed::Worker.max_attempts = 5
3535
Delayed::Worker.max_run_time = 5.minutes
3636

37+
Delayed::Job.delete_all unless ENV.fetch('RAILS_ENV', 'test') == 'test'
38+
39+
# Load the database configuration
40+
3741
config = YAML.load_file('config/database.yml')[ENV.fetch('RACK_ENV', 'development')]
3842
ActiveRecord::Base.establish_connection(config)

lib/github/build/summary.rb

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ def initialize(job, logger_level: Logger::INFO, agent: 'Github')
3434
def build_summary
3535
current_stage = @job.stage
3636
current_stage = fetch_parent_stage if current_stage.nil?
37-
current_stage.refresh_reference(@github)
3837

3938
logger(Logger::INFO, "build_summary: #{current_stage.inspect}")
4039
msg = "Github::Build::Summary - #{@job.inspect}, #{current_stage.inspect}, bamboo info: #{bamboo_info}"
@@ -81,8 +80,6 @@ def must_cancel_next_stages(current_stage)
8180
.where(check_suite: @check_suite)
8281
.where(configuration: { position: [(current_stage.configuration.position + 1)..] })
8382
.each do |stage|
84-
next if stage.cancelled?
85-
8683
cancelling_next_stage(stage)
8784
end
8885
end
@@ -98,7 +95,7 @@ def must_continue_next_stage(current_stage)
9895
.where(configuration: { position: current_stage.configuration.position + 1 })
9996
.first
10097

101-
return if next_stage.nil? or next_stage.cancelled?
98+
return if next_stage.nil? or next_stage.finished?
10299

103100
update_summary(next_stage)
104101
end

lib/github/check.rb

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -138,25 +138,29 @@ def basic_status(check_ref, status, output)
138138
def completed(check_ref, status, conclusion, output)
139139
return if check_ref.nil?
140140

141-
opts = {
142-
status: status,
143-
conclusion: conclusion
144-
}
141+
retry_count = 0
145142

146-
opts[:output] = output unless output.empty?
143+
begin
144+
opts = {
145+
status: status,
146+
conclusion: conclusion
147147

148-
resp =
149-
@app.update_check_run(
150-
@check_suite.pull_request.repository,
151-
check_ref,
152-
opts
153-
).to_h
148+
}
154149

155-
@logger.info("completed: #{check_ref}, status: #{status}, conclusion: #{conclusion} -> resp: #{resp}")
150+
opts[:output] = output unless output.empty?
156151

157-
resp
158-
rescue Octokit::NotFound
159-
@logger.error "#{check_ref} not found at GitHub"
152+
send_update(check_ref, opts, conclusion)
153+
rescue Octokit::NotFound, RuntimeError
154+
retry_count += 1
155+
156+
sleep retry_count * 5
157+
158+
retry if retry_count <= 3
159+
160+
@logger.error "#{check_ref} not found at GitHub"
161+
162+
{}
163+
end
160164
end
161165

162166
def authenticate_app
@@ -190,5 +194,20 @@ def authenticate(jwt)
190194

191195
@app = Octokit::Client.new(bearer_token: token)
192196
end
197+
198+
def send_update(check_ref, opts, conclusion)
199+
resp =
200+
@app.update_check_run(
201+
@check_suite.pull_request.repository,
202+
check_ref,
203+
opts
204+
).to_h
205+
206+
raise 'GitHub failed to update status' if resp[:conclusion] != conclusion
207+
208+
@logger.info("completed: #{check_ref}, conclusion: #{conclusion} -> resp: #{resp}")
209+
210+
resp
211+
end
193212
end
194213
end

lib/github/update_status.rb

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -82,26 +82,17 @@ def update_status
8282
def insert_new_delayed_job
8383
queue = @job.check_suite.pull_request.github_pr_id % 10
8484

85-
if can_add_new_job?
86-
return CiJobStatus
87-
.delay(run_at: DELAYED_JOB_TIMER.seconds.from_now, queue: queue)
88-
.update(@job.check_suite.id, @job.id)
89-
end
90-
9185
delete_and_create_delayed_job(queue)
9286
end
9387

9488
def delete_and_create_delayed_job(queue)
95-
fetch_delayed_job.destroy_all
89+
fetch_delayed_job&.destroy_all
90+
9691
CiJobStatus
9792
.delay(run_at: DELAYED_JOB_TIMER.seconds.from_now, queue: queue)
9893
.update(@job.check_suite.id, @job.id)
9994
end
10095

101-
def can_add_new_job?
102-
fetch_delayed_job.empty?
103-
end
104-
10596
def fetch_delayed_job
10697
Delayed::Job.where('handler LIKE ?', "%method_name: :update\nargs:\n- #{@job.check_suite.id}%")
10798
end

lib/models/stage.rb

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -55,43 +55,39 @@ def update_output(github, output: output_in_progress)
5555
end
5656

5757
def cancelled(github, output: {}, agent: 'Github')
58-
return if cancelled?
58+
check_run = refresh_reference(github)
59+
github.cancelled(check_run.id, output)
5960

60-
create_github_check(github)
61-
github.cancelled(check_ref, output)
62-
update(status: :cancelled)
61+
update(status: :cancelled, check_ref: check_run.id)
6362
AuditStatus.create(auditable: self, status: :cancelled, agent: agent, created_at: Time.now)
6463
notification
6564
end
6665

6766
def failure(github, output: {}, agent: 'Github')
68-
return if failure?
67+
check_run = refresh_reference(github)
68+
github.failure(check_run.id, output)
6969

70-
create_github_check(github)
71-
github.failure(check_ref, output)
72-
update(status: :failure)
70+
update(status: :failure, check_ref: check_run.id)
7371
AuditStatus.create(auditable: self, status: :failure, agent: agent, created_at: Time.now)
7472
notification
7573
end
7674

7775
def success(github, output: {}, agent: 'Github')
78-
return if success?
76+
check_run = refresh_reference(github)
77+
github.success(check_run.id, output)
7978

80-
create_github_check(github)
81-
github.success(check_ref, output)
82-
update(status: :success)
79+
reload
80+
update(status: :success, check_ref: check_run.id)
8381
AuditStatus.create(auditable: self, status: :success, agent: agent, created_at: Time.now)
8482
notification
8583
end
8684

87-
def refresh_reference(github, agent: 'Github')
88-
check_run = github.create(github_stage_full_name(name))
89-
update(check_ref: check_run.id)
90-
AuditStatus.create(auditable: self, status: :refresh, agent: agent, created_at: Time.now)
91-
end
92-
9385
private
9486

87+
def refresh_reference(github)
88+
github.create(github_stage_full_name(name))
89+
end
90+
9591
def in_progress_notification
9692
SlackBot.instance.stage_in_progress_notification(self)
9793
end

spec/lib/github/build/unavailable_jobs_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
allow(Octokit::Client).to receive(:new).and_return(fake_client)
2020
allow(fake_client).to receive(:find_app_installations).and_return([{ 'id' => 1 }])
2121
allow(fake_client).to receive(:create_app_installation_access_token).and_return({ 'token' => 1 })
22-
allow(fake_client).to receive(:update_check_run)
22+
allow(fake_client).to receive(:update_check_run).and_return({ conclusion: 'skipped' })
2323
allow(File).to receive(:read).and_return('')
2424
allow(OpenSSL::PKey::RSA).to receive(:new).and_return(OpenSSL::PKey::RSA.new(2048))
2525
end

spec/lib/github/check_spec.rb

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@
104104
context 'when call create' do
105105
let(:pr_id) { 1 }
106106
let(:name) { 'test' }
107-
let(:pr_info) { { name: name } }
107+
let(:pr_info) { { name: name, conclusion: 'success' } }
108108

109109
before do
110110
allow(fake_client).to receive(:create_check_run)
@@ -141,7 +141,7 @@
141141
context 'when call in_progress' do
142142
let(:id) { 1 }
143143
let(:status) { 'in_progress' }
144-
let(:pr_info) { { status: status } }
144+
let(:pr_info) { { status: status, conclusion: status } }
145145
let(:output) { { title: 'Title', summary: 'Summary' } }
146146

147147
before do
@@ -173,11 +173,11 @@
173173
status: status,
174174
conclusion: conclusion
175175
})
176-
.and_return({})
176+
.and_return({ conclusion: conclusion })
177177
end
178178

179179
it 'must returns success' do
180-
expect(check.cancelled(id)).to eq({})
180+
expect(check.cancelled(id)).to eq({ conclusion: conclusion })
181181
end
182182
end
183183

@@ -194,11 +194,11 @@
194194
status: status,
195195
conclusion: conclusion
196196
})
197-
.and_return({})
197+
.and_return({ conclusion: conclusion })
198198
end
199199

200200
it 'must returns success' do
201-
expect(check.success(id)).to eq({})
201+
expect(check.success(id)).to eq({ conclusion: conclusion })
202202
end
203203
end
204204

@@ -238,11 +238,11 @@
238238
conclusion: conclusion,
239239
output: output
240240
})
241-
.and_return({})
241+
.and_return({ conclusion: conclusion })
242242
end
243243

244244
it 'must returns success' do
245-
expect(check.failure(id, output)).to eq({})
245+
expect(check.failure(id, output)).to eq({ conclusion: conclusion })
246246
end
247247
end
248248

@@ -259,11 +259,11 @@
259259
status: status,
260260
conclusion: conclusion
261261
})
262-
.and_return({})
262+
.and_return({ conclusion: conclusion })
263263
end
264264

265265
it 'must returns success' do
266-
expect(check.skipped(id)).to eq({})
266+
expect(check.skipped(id)).to eq({ conclusion: conclusion })
267267
end
268268
end
269269

@@ -350,4 +350,30 @@
350350
end
351351
end
352352
end
353+
354+
describe 'retry send_update ' do
355+
let(:id) { 1 }
356+
let(:status) { 'completed' }
357+
let(:conclusion) { 'success' }
358+
359+
context 'when send_update returns error' do
360+
before do
361+
allow(fake_client).to receive(:update_check_run).and_raise(Octokit::NotFound)
362+
end
363+
364+
it 'must returns raise' do
365+
expect(check.skipped(id)).to eq({})
366+
end
367+
end
368+
369+
context 'when send_update returns error and success' do
370+
before do
371+
allow(fake_client).to receive(:update_check_run).and_return({}, { conclusion: conclusion })
372+
end
373+
374+
it 'must returns a valid data' do
375+
expect(check.skipped(id)).to eq({})
376+
end
377+
end
378+
end
353379
end

spec/spec_helper.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ def app
6161
end
6262

6363
config.before(:each) do
64+
allow_any_instance_of(Object).to receive(:sleep)
6465
Delayed::Worker.delay_jobs = false
6566
end
6667

0 commit comments

Comments
 (0)