Skip to content

Commit 6d553f3

Browse files
Merge pull request #105 from RodrigoMNardi/bug/github/watchdog
WatchDog
2 parents bdaecf0 + fdebf0a commit 6d553f3

File tree

11 files changed

+277
-59
lines changed

11 files changed

+277
-59
lines changed

config/delayed_job.rb

-2
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,6 @@ 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-
3937
# Load the database configuration
4038

4139
config = YAML.load_file('config/database.yml')[ENV.fetch('RACK_ENV', 'development')]

lib/github/build/action.rb

+65
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,17 @@
33
# action.rb
44
# Part of NetDEF CI System
55
#
6+
# This class handles the build action for a given CheckSuite.
7+
# It creates summaries, jobs, and timeout workers for the CheckSuite.
8+
#
9+
# Methods:
10+
# - initialize(check_suite, github, jobs, logger_level: Logger::INFO): Initializes the Action class with the
11+
# given parameters.
12+
# - create_summary(rerun: false): Creates a summary for the CheckSuite, including jobs and timeout workers.
13+
#
14+
# Example usage:
15+
# Github::Build::Action.new(check_suite, github, jobs).create_summary
16+
#
617
# Copyright (c) 2023 by
718
# Network Device Education Foundation, Inc. ("NetDEF")
819
#
@@ -11,6 +22,13 @@
1122
module Github
1223
module Build
1324
class Action
25+
##
26+
# Initializes the Action class with the given parameters.
27+
#
28+
# @param [CheckSuite] check_suite The CheckSuite to handle.
29+
# @param [Github] github The Github instance to use.
30+
# @param [Array] jobs The jobs to create for the CheckSuite.
31+
# @param [Integer] logger_level The logging level to use (default: Logger::INFO).
1432
def initialize(check_suite, github, jobs, logger_level: Logger::INFO)
1533
@check_suite = check_suite
1634
@github = github
@@ -26,6 +44,10 @@ def initialize(check_suite, github, jobs, logger_level: Logger::INFO)
2644
logger(Logger::WARN, ">>>> Building action to CheckSuite: #{@check_suite.inspect}")
2745
end
2846

47+
##
48+
# Creates a summary for the CheckSuite, including jobs and timeout workers.
49+
#
50+
# @param [Boolean] rerun Indicates if the jobs should be rerun (default: false).
2951
def create_summary(rerun: false)
3052
logger(Logger::INFO, "SUMMARY #{@stages.inspect}")
3153

@@ -37,10 +59,15 @@ def create_summary(rerun: false)
3759

3860
logger(Logger::INFO, "@jobs - #{@jobs.inspect}")
3961
create_jobs(rerun)
62+
create_timeout_worker
4063
end
4164

4265
private
4366

67+
##
68+
# Creates jobs for the CheckSuite.
69+
#
70+
# @param [Boolean] rerun Indicates if the jobs should be rerun.
4471
def create_jobs(rerun)
4572
@jobs.each do |job|
4673
ci_job = create_ci_job(job)
@@ -60,13 +87,32 @@ def create_jobs(rerun)
6087
end
6188
end
6289

90+
##
91+
# Creates a timeout worker for the CheckSuite.
92+
def create_timeout_worker
93+
logger(Logger::INFO, "CiJobStatus::Update: TimeoutExecution for '#{@check_suite.id}'")
94+
95+
TimeoutExecution
96+
.delay(run_at: 30.minute.from_now.utc, queue: 'timeout_execution')
97+
.timeout(@check_suite.id)
98+
end
99+
100+
##
101+
# Starts the stage in progress if configured to do so.
102+
#
103+
# @param [CiJob] ci_job The CI job to start in progress.
63104
def stage_with_start_in_progress(ci_job)
64105
return unless !ci_job.stage.nil? and ci_job.stage.configuration.start_in_progress?
65106

66107
ci_job.in_progress(@github)
67108
ci_job.stage.in_progress(@github, output: {})
68109
end
69110

111+
##
112+
# Creates a CI job for the given job parameters.
113+
#
114+
# @param [Hash] job The job parameters.
115+
# @return [CiJob, nil] The created CI job or nil if the stage configuration is not found.
70116
def create_ci_job(job)
71117
stage_config = StageConfiguration.find_by(bamboo_stage_name: job[:stage])
72118

@@ -79,6 +125,10 @@ def create_ci_job(job)
79125
CiJob.create(check_suite: @check_suite, name: job[:name], job_ref: job[:job_ref], stage: stage)
80126
end
81127

128+
##
129+
# Creates a check run stage for the given stage configuration.
130+
#
131+
# @param [StageConfiguration] stage_config The stage configuration.
82132
def create_check_run_stage(stage_config)
83133
stage = Stage.find_by(name: stage_config.github_check_run_name, check_suite_id: @check_suite.id)
84134

@@ -92,6 +142,11 @@ def create_check_run_stage(stage_config)
92142
stage.enqueue(@github, output: initial_output(stage))
93143
end
94144

145+
##
146+
# Creates a new stage for the given stage configuration.
147+
#
148+
# @param [StageConfiguration] stage_config The stage configuration.
149+
# @return [Stage] The created stage.
95150
def create_stage(stage_config)
96151
name = stage_config.github_check_run_name
97152

@@ -110,6 +165,11 @@ def create_stage(stage_config)
110165
stage
111166
end
112167

168+
##
169+
# Generates the initial output for a CI job.
170+
#
171+
# @param [CiJob] ci_job The CI job.
172+
# @return [Hash] The initial output.
113173
def initial_output(ci_job)
114174
output = { title: '', summary: '' }
115175
url = "https://ci1.netdef.org/browse/#{ci_job.check_suite.bamboo_ci_ref}"
@@ -120,6 +180,11 @@ def initial_output(ci_job)
120180
output
121181
end
122182

183+
##
184+
# Logs a message with the given severity.
185+
#
186+
# @param [Integer] severity The severity level.
187+
# @param [String] message The message to log.
123188
def logger(severity, message)
124189
@loggers.each do |logger_object|
125190
logger_object.add(severity, message)

lib/github/plan_execution/finished.rb

+79-6
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,18 @@
33
# check_suite_finished.rb
44
# Part of NetDEF CI System
55
#
6+
# This class handles the logic for determining if a CheckSuite has finished execution.
7+
# It interacts with the Bamboo CI system to fetch the build status and updates the CheckSuite accordingly.
8+
#
9+
# Methods:
10+
# - initialize(payload): Initializes the Finished class with the given payload.
11+
# - finished: Main method to handle the completion logic for a CheckSuite.
12+
# - fetch_build_status: Fetches the build status from Bamboo CI.
13+
# - in_progress?(build_status): Checks if the CI build is still in progress.
14+
#
15+
# Example usage:
16+
# Github::PlanExecution::Finished.new(payload).finished
17+
#
618
# Copyright (c) 2024 by
719
# Network Device Education Foundation, Inc. ("NetDEF")
820
#
@@ -17,12 +29,22 @@ module PlanExecution
1729
class Finished
1830
include BambooCi::Api
1931

32+
##
33+
# Initializes the Finished class with the given payload.
34+
#
35+
# @param [Hash] payload The payload containing information about the CheckSuite.
2036
def initialize(payload)
21-
@check_suite = CheckSuite.find_by(bamboo_ci_ref: payload['bamboo_ref'])
37+
@check_suite = CheckSuite.find_by(bamboo_ci_ref: payload['bamboo_ref']) if payload['bamboo_ref']
38+
@check_suite = CheckSuite.find(payload['check_suite_id']) if payload['check_suite_id']
2239
@logger = GithubLogger.instance.create('github_plan_execution_finished.log', Logger::INFO)
2340
@hanged = payload['hanged'] || false
2441
end
2542

43+
##
44+
# Main method to handle the completion logic for a CheckSuite.
45+
# Fetches the CI execution status and updates the CheckSuite accordingly.
46+
#
47+
# @return [Array] An array containing the status code and message.
2648
def finished
2749
@logger.info ">>> Check Suite: #{@check_suite.inspect}"
2850

@@ -31,9 +53,9 @@ def finished
3153
fetch_ci_execution
3254
build_status = fetch_build_status
3355

34-
@logger.info ">>> build_status: #{build_status.inspect}"
56+
@logger.info ">>> build_status: #{build_status.inspect}. Hanged? #{@hanged}"
3557

36-
return [200, 'Still running'] if in_progress?(build_status)
58+
return [200, 'Still running'] if in_progress?(build_status) and !@hanged
3759

3860
check_stages
3961
clear_deleted_jobs
@@ -42,11 +64,19 @@ def finished
4264
[200, 'Finished']
4365
end
4466

67+
##
68+
# Fetches the build status from Bamboo CI.
69+
#
70+
# @return [Hash] The build status.
4571
def fetch_build_status
4672
get_request(URI("https://127.0.0.1/rest/api/latest/result/status/#{@check_suite.bamboo_ci_ref}"))
4773
end
4874

49-
# Checks if CI still running
75+
##
76+
# Checks if the CI build is still in progress.
77+
#
78+
# @param [Hash] build_status The build status.
79+
# @return [Boolean] Returns true if the build is still in progress, false otherwise.
5080
def in_progress?(build_status)
5181
@logger.info ">>> ci_stopped?: #{ci_stopped?(build_status)}"
5282
@logger.info ">>> ci_hanged?: #{ci_hanged?(build_status)}"
@@ -59,6 +89,9 @@ def in_progress?(build_status)
5989

6090
private
6191

92+
##
93+
# Updates the status of all stages for the CheckSuite.
94+
# Builds a summary for the last stage's last job.
6295
def update_all_stages
6396
last_stage =
6497
Stage
@@ -71,8 +104,8 @@ def update_all_stages
71104
build_summary(last_stage.jobs.last)
72105
end
73106

74-
# This method will move all tests that no longer exist in BambooCI to the skipped state,
75-
# because there are no executions for them.
107+
##
108+
# Moves all tests that no longer exist in BambooCI to the skipped state.
76109
def clear_deleted_jobs
77110
github_check = Github::Check.new(@check_suite)
78111

@@ -81,22 +114,44 @@ def clear_deleted_jobs
81114
end
82115
end
83116

117+
##
118+
# Checks if the CI build has stopped.
119+
#
120+
# @param [Hash] build_status The build status.
121+
# @return [Boolean] Returns true if the build has stopped, false otherwise.
84122
def ci_stopped?(build_status)
85123
build_status.key?('message') and !build_status.key?('finished')
86124
end
87125

126+
##
127+
# Checks if the CI build has hanged.
128+
#
129+
# @param [Hash] build_status The build status.
130+
# @return [Boolean] Returns true if the build has hanged, false otherwise.
88131
def ci_hanged?(build_status)
89132
return true if ci_stopped?(build_status)
90133

91134
build_status.dig('progress', 'percentageCompleted').to_f >= 2.0
92135
end
93136

137+
##
138+
# Updates the status of a stage based on the CI job result.
139+
#
140+
# @param [CiJob] ci_job The CI job to update.
141+
# @param [Hash] result The result of the CI job.
142+
# @param [Github::Check] github The Github check instance.
94143
def update_stage_status(ci_job, result, github)
95144
return if ci_job.nil? || (ci_job.finished? && !ci_job.job_ref.nil?)
96145

97146
update_ci_job_status(github, ci_job, result['state'])
98147
end
99148

149+
##
150+
# Updates the status of a CI job based on the state.
151+
#
152+
# @param [Github::Check] github_check The Github check instance.
153+
# @param [CiJob] ci_job The CI job to update.
154+
# @param [String] state The state of the CI job.
100155
def update_ci_job_status(github_check, ci_job, state)
101156
ci_job.enqueue(github_check) if ci_job.job_ref.nil?
102157

@@ -119,6 +174,11 @@ def update_ci_job_status(github_check, ci_job, state)
119174
build_summary(ci_job)
120175
end
121176

177+
##
178+
# Creates an output message for a CI job.
179+
#
180+
# @param [CiJob] ci_job The CI job to create the message for.
181+
# @return [Hash] The output message.
122182
def create_output_message(ci_job)
123183
url = "https://ci1.netdef.org/browse/#{ci_job.job_ref}"
124184

@@ -128,13 +188,22 @@ def create_output_message(ci_job)
128188
}
129189
end
130190

191+
##
192+
# Builds a summary for a CI job.
193+
#
194+
# @param [CiJob] ci_job The CI job to build the summary for.
131195
def build_summary(ci_job)
132196
summary = Github::Build::Summary.new(ci_job, agent: 'WatchDog')
133197
summary.build_summary
134198

135199
finished_execution?(ci_job.check_suite)
136200
end
137201

202+
##
203+
# Checks if the execution of the CheckSuite has finished.
204+
#
205+
# @param [CheckSuite] check_suite The CheckSuite to check.
206+
# @return [Boolean] Returns true if the execution has finished, false otherwise.
138207
def finished_execution?(check_suite)
139208
return false unless check_suite.pull_request.current_execution?(check_suite)
140209
return false unless check_suite.finished?
@@ -154,6 +223,8 @@ def slack_notify_cancelled(job)
154223
SlackBot.instance.notify_cancelled(job)
155224
end
156225

226+
##
227+
# Checks the stages of the CheckSuite and updates their status.
157228
def check_stages
158229
github_check = Github::Check.new(@check_suite)
159230
@logger.info ">>> @result: #{@result.inspect}"
@@ -168,6 +239,8 @@ def check_stages
168239
end
169240
end
170241

242+
##
243+
# Fetches the CI execution status for the CheckSuite.
171244
def fetch_ci_execution
172245
@result = get_status(@check_suite.bamboo_ci_ref)
173246
end

0 commit comments

Comments
 (0)