Skip to content

Commit

Permalink
Merge pull request #47 from RodrigoMNardi/bug/build/summary/github_do…
Browse files Browse the repository at this point in the history
…es_not_update

Summary - Audit Status
  • Loading branch information
RodrigoMNardi authored Feb 16, 2024
2 parents 10503cb + 7838be8 commit d53670d
Show file tree
Hide file tree
Showing 15 changed files with 268 additions and 58 deletions.
21 changes: 21 additions & 0 deletions db/migrate/20240207070831_create_audit_status.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# SPDX-License-Identifier: BSD-2-Clause
#
# 20231214093515_create_stages.rb
# Part of NetDEF CI System
#
# Copyright (c) 2023 by
# Network Device Education Foundation, Inc. ("NetDEF")
#
# frozen_string_literal: true

class CreateAuditStatus < ActiveRecord::Migration[6.0]
def change
create_table :audit_statuses do |t|
t.integer :status, null: false, default: 0
t.string :agent
t.datetime :created_at, null: false, precision: 6

t.references :auditable, polymorphic: true, index: true, null: false
end
end
end
11 changes: 10 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,19 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema[7.0].define(version: 2023_12_14_094534) do
ActiveRecord::Schema[7.0].define(version: 2024_02_07_070831) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"

create_table "audit_statuses", force: :cascade do |t|
t.integer "status", default: 0, null: false
t.string "agent"
t.datetime "created_at", null: false
t.string "auditable_type", null: false
t.bigint "auditable_id", null: false
t.index ["auditable_type", "auditable_id"], name: "index_audit_statuses_on_auditable_type_and_auditable_id"
end

create_table "check_suites", force: :cascade do |t|
t.string "author", null: false
t.string "commit_sha_ref", null: false
Expand Down
5 changes: 3 additions & 2 deletions lib/github/build/action.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@ def initialize(check_suite, github, jobs, logger_level: Logger::INFO)
%w[github_app.log github_build_action.log].each do |filename|
@loggers << GithubLogger.instance.create(filename, logger_level)
end
@loggers << GithubLogger.instance.create("pr#{@check_suite.pull_request.github_pr_id}.log", logger_level)

logger(Logger::INFO, "Building action to CheckSuite @#{@check_suite.inspect}")
logger(Logger::WARN, ">>>> Building action to CheckSuite: #{@check_suite.inspect}")
end

def create_summary(rerun: false)
Expand Down Expand Up @@ -59,7 +60,7 @@ def stage_with_start_in_progress(ci_job)
return unless !ci_job.stage.nil? and ci_job.stage.configuration.start_in_progress?

ci_job.in_progress(@github)
ci_job.stage.in_progress(@github, output: {}, job: ci_job)
ci_job.stage.in_progress(@github, output: {})
end

def create_ci_job(job)
Expand Down
2 changes: 2 additions & 0 deletions lib/github/build/retry.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ def initialize(check_suite, github, logger_level: Logger::INFO)
%w[github_app.log github_build_retry.log].each do |filename|
@loggers << GithubLogger.instance.create(filename, logger_level)
end
@loggers << GithubLogger.instance.create("pr#{@check_suite.pull_request.github_pr_id}.log", logger_level)
logger(Logger::WARN, ">>>> Retrying check_suite: #{@check_suite.inspect}")
end

def enqueued_stages
Expand Down
50 changes: 37 additions & 13 deletions lib/github/build/summary.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,24 @@
module Github
module Build
class Summary
def initialize(job, logger_level: Logger::INFO)
def initialize(job, logger_level: Logger::INFO, agent: 'Github')
@job = job.reload
@check_suite = @job.check_suite
@github = Github::Check.new(@check_suite)
@loggers = []
@agent = agent

%w[github_app.log github_build_summary.log].each do |filename|
@loggers << GithubLogger.instance.create(filename, logger_level)
end

@loggers << GithubLogger.instance.create("pr#{@check_suite.pull_request.github_pr_id}.log", logger_level)
end

def build_summary
current_stage = @job.stage
current_stage = fetch_parent_stage if current_stage.nil?
check_and_update_github_ref(current_stage)

logger(Logger::INFO, "build_summary: #{current_stage.inspect}")

Expand All @@ -48,6 +52,22 @@ def build_summary

private

def check_and_update_github_ref(current_stage)
current_refs = @github.fetch_check_runs

logger(Logger::INFO,
'check_and_update_github_ref - current_stage: ' \
"#{current_stage.inspect} current_refs: #{current_refs.inspect}")

return if current_refs.include? current_stage.check_ref.to_i

logger(Logger::INFO,
'check_and_update_github_ref - current_stage: ' \
"#{current_stage.inspect} current_refs: #{current_refs.inspect} - Refreshing reference.")

current_stage.refresh_reference(@github)
end

def must_update_previous_stage(current_stage)
previous_stage = current_stage.previous_stage

Expand Down Expand Up @@ -87,14 +107,6 @@ def must_continue_next_stage(current_stage)
update_summary(next_stage)
end

def bamboo_stage_check_positions(pending_stage, stage)
pending_stage_position = pending_stage.configuration.position
stage_position = stage.configuration.position

pending_stage_position <= stage_position or
pending_stage_position + 1 != stage_position
end

def cancelling_next_stage(pending_stage)
url = "https://ci1.netdef.org/browse/#{pending_stage.check_suite.bamboo_ci_ref}"
output = {
Expand All @@ -112,25 +124,35 @@ def cancelling_next_stage(pending_stage)

def finished_summary(stage)
logger(Logger::INFO, "Finished stage: #{stage.inspect}, CiJob status: #{@job.status}")
logger(Logger::INFO, "Finished stage: #{stage.inspect}, jobs: #{stage.reload.jobs.inspect}")
logger(Logger::INFO, "Finished stage: #{stage.inspect}, running? #{stage.reload.running?}")

return if @job.in_progress? or stage.running?

finished_stage_summary(stage)
end

def finished_stage_summary(stage)
logger(Logger::INFO, "finished_build_summary: #{stage.inspect}. Reason Job: #{@job.inspect}")
logger(Logger::INFO, "finished_stage_summary: #{stage.inspect}. Reason Job: #{@job.inspect}")

url = "https://ci1.netdef.org/browse/#{stage.check_suite.bamboo_ci_ref}"
output = {
title: "#{stage.name} summary",
summary: "#{summary_basic_output(stage)}\nDetails at [#{url}](#{url}).".force_encoding('utf-8')
}

finished_stage_update(stage, output)

logger(Logger::INFO, "finished_stage_summary: #{stage.inspect} #{output.inspect}")
end

stage.jobs.failure.empty? ? stage.success(@github, output: output) : stage.failure(@github, output: output)
def finished_stage_update(stage, output)
if stage.jobs.failure.empty?
logger(Logger::WARN, "Stage: #{stage.name} finished - failure")
stage.success(@github, output: output, agent: @agent)
else
logger(Logger::WARN, "Stage: #{stage.name} finished - success")
stage.failure(@github, output: output, agent: @agent)
end
end

def update_summary(stage)
Expand All @@ -144,7 +166,9 @@ def update_summary(stage)

logger(Logger::INFO, "update_summary: #{stage.inspect} #{output.inspect}")

stage.in_progress(@github, output: output, job: @job)
logger(Logger::WARN, "Updating stage: #{stage.name} to in_progress")
stage.in_progress(@github, output: output)
stage.update_output(@github, output: output)
end

def summary_basic_output(stage)
Expand Down
2 changes: 1 addition & 1 deletion lib/github/build/unavailable_jobs.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def update(new_check_suite: nil)
BambooCi::RunningPlan.fetch(@check_suite.bamboo_ci_ref).map { |entry| entry[:job_ref] }

@check_suite.ci_jobs.where.not(job_ref: running_jobs).each do |unavailable_job|
unavailable_job.skipped(@github, output(unavailable_job))
unavailable_job.skipped(@github, output: output(unavailable_job))
unavailable_job.update(check_suite: new_check_suite) unless new_check_suite.nil?
end
end
Expand Down
11 changes: 11 additions & 0 deletions lib/github/check.rb
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,17 @@ def get_check_run(check_ref)
@app.check_run(@check_suite.pull_request.repository, check_ref).to_h
end

def fetch_check_runs
return [] if @check_suite.nil?

@app
.check_runs_for_ref(@check_suite.pull_request.repository, @check_suite.pull_request.branch_name)
.to_h[:check_runs]
.map do |check_run|
check_run[:id]
end
end

def installation_id
@authenticate_app.find_app_installations.first['id'].to_i
end
Expand Down
46 changes: 36 additions & 10 deletions lib/github/update_status.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ module Github
class UpdateStatus
def initialize(payload)
@status = payload['status']
@logger = GithubLogger.instance.create('github_update_status.log', Logger::INFO)

@output =
if payload.dig('output', 'title').nil? and payload.dig('output', 'summary').nil?
Expand All @@ -28,13 +27,18 @@ def initialize(payload)
{ title: payload.dig('output', 'title'), summary: payload.dig('output', 'summary') }
end

@reference = payload['bamboo_ref'] || 'invalid_reference'
@job = CiJob.find_by(job_ref: payload['bamboo_ref'])
@check_suite = @job&.check_suite
@failures = payload['failures']

logger_initializer
logger(Logger::WARN, "UpdateStatus: #{@reference} #{@status} (Output in info log)")
logger(Logger::INFO, "UpdateStatus: #{@reference} #{@status} #{@output}")
end

def update
return [404, 'CI JOB not found'] if @job.nil?
return job_not_found if @job.nil?
return [304, 'Not Modified'] if @job.queued? and @status != 'in_progress' and @job.name != 'Checkout Code'
return [304, 'Not Modified'] if @job.in_progress? and !%w[success failure].include? @status

Expand All @@ -47,6 +51,12 @@ def update

private

def job_not_found
logger(Logger::ERROR, "CI JOB not found: '#{@reference}'")

[404, 'CI JOB not found']
end

def failures_stats
@failures.each do |failure|
TopotestFailure.create(ci_job: @job,
Expand All @@ -60,9 +70,9 @@ def failures_stats
def update_status
case @status
when 'in_progress'
@job.in_progress(@github_check, @output)
@job.in_progress(@github_check, output: @output)
when 'success'
@job.success(@github_check, @output)
@job.success(@github_check, output: @output)
slack_notify_success
else
failure
Expand All @@ -79,8 +89,8 @@ def finished_execution?
return false unless current_execution?
return false unless @check_suite.finished?

@logger.info ">>> @check_suite#{@check_suite.inspect} -> finished? #{@check_suite.finished?}"
@logger.info @check_suite.ci_jobs.last.inspect
logger Logger::INFO, ">>> @check_suite#{@check_suite.inspect} -> finished? #{@check_suite.finished?}"
logger Logger::INFO, @check_suite.ci_jobs.last.inspect

SlackBot.instance.execution_finished_notification(@check_suite)
end
Expand All @@ -89,8 +99,8 @@ def current_execution?
pull_request = @check_suite.pull_request
last_check_suite = pull_request.check_suites.reload.all.order(:created_at).last

@logger.info "last_check_suite: #{last_check_suite.inspect}"
@logger.info "@check_suite: #{@check_suite.inspect}"
logger Logger::INFO, "last_check_suite: #{last_check_suite.inspect}"
logger Logger::INFO, "@check_suite: #{@check_suite.inspect}"

@check_suite.id == last_check_suite.id
end
Expand All @@ -101,7 +111,7 @@ def failure
unable2find = "There was some test that failed, but I couldn't find the log."
fetch_and_update_failures(unable2find) if !@output.empty? and @output[:summary].match?(unable2find)

@job.failure(@github_check, @output)
@job.failure(@github_check, output: @output)
failures_stats if @job.name.downcase.match? 'topotest' and @failures.is_a? Array
end

Expand All @@ -113,7 +123,7 @@ def fetch_and_update_failures(to_be_replaced)

@output[:summary] = @output[:summary].sub(to_be_replaced, fetch_failures(output))[0..65_535]
rescue NoMethodError => e
@logger.error "#{e.class} #{e.message}"
logger Logger::ERROR, "#{e.class} #{e.message}"
count += 1
sleep 5
retry if count <= 10
Expand Down Expand Up @@ -151,5 +161,21 @@ def slack_notify_failure

SlackBot.instance.notify_errors(@job)
end

def logger(severity, message)
@loggers.each do |logger_object|
logger_object.add(severity, message)
end
end

def logger_initializer
@loggers = []
@loggers << GithubLogger.instance.create('github_update_status.log', Logger::INFO)
@loggers << if @job.nil?
GithubLogger.instance.create(@reference, Logger::INFO)
else
GithubLogger.instance.create("pr#{@job.check_suite.pull_request.github_pr_id}.log", Logger::INFO)
end
end
end
end
17 changes: 17 additions & 0 deletions lib/models/audit_status.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# SPDX-License-Identifier: BSD-2-Clause
#
# audit_status.rb
# Part of NetDEF CI System
#
# Copyright (c) 2024 by
# Network Device Education Foundation, Inc. ("NetDEF")
#
# frozen_string_literal: true

require 'otr-activerecord'

class AuditStatus < ActiveRecord::Base
enum status: { queued: 0, in_progress: 1, success: 2, refresh: 3, cancelled: -1, failure: -2, skipped: -3 }

belongs_to :auditable, polymorphic: true
end
Loading

0 comments on commit d53670d

Please sign in to comment.