Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CI Stages #24

Merged
merged 31 commits into from
Dec 8, 2023
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
163d81c
CI Stages
RodrigoMNardi Nov 8, 2023
35a87ef
Console
RodrigoMNardi Nov 8, 2023
940baea
CI Stages
RodrigoMNardi Nov 8, 2023
c594910
Rubocop
RodrigoMNardi Nov 9, 2023
5ed1a21
GitHub update issue.
RodrigoMNardi Nov 9, 2023
045fb6d
Watchdog
RodrigoMNardi Nov 9, 2023
62b9cbb
Summary and Action
RodrigoMNardi Nov 10, 2023
f796a4d
Summary and Action
RodrigoMNardi Nov 10, 2023
82842b0
Summary and Action
RodrigoMNardi Nov 10, 2023
52acd34
CiJob
RodrigoMNardi Nov 13, 2023
6d98a2f
CiJob
RodrigoMNardi Nov 13, 2023
bacd88b
Merge remote-tracking branch 'origin/master' into bug/ci_summary_check
RodrigoMNardi Nov 17, 2023
8d99e17
Merge remote-tracking branch 'origin/master' into bug/ci_summary_check
RodrigoMNardi Nov 23, 2023
918b459
3 Stages CI
RodrigoMNardi Nov 27, 2023
c828480
Rubocop
RodrigoMNardi Nov 28, 2023
84a854f
Merge branch 'master' into bug/ci_summary_check
RodrigoMNardi Nov 28, 2023
97ea688
Build logs
RodrigoMNardi Nov 29, 2023
3d5b110
Download Unit Tests
RodrigoMNardi Dec 1, 2023
82d8d88
Merge remote-tracking branch 'origin/master' into bug/ci_summary_check
RodrigoMNardi Dec 7, 2023
02d357c
New CI output
RodrigoMNardi Dec 7, 2023
b34f6dc
ReRun::Base
RodrigoMNardi Dec 7, 2023
0bb0f50
Ci Job
RodrigoMNardi Dec 8, 2023
1ab58b2
Watchdog
RodrigoMNardi Dec 8, 2023
6dc29bb
Watchdog
RodrigoMNardi Dec 8, 2023
649a26b
Ci Job Factory
RodrigoMNardi Dec 8, 2023
b5c7abc
Summary
RodrigoMNardi Dec 8, 2023
44db317
Stages
RodrigoMNardi Dec 8, 2023
7330dfc
Unavailable Jobs
RodrigoMNardi Dec 8, 2023
104e67c
Merge branch 'master' into bug/ci_summary_check
RodrigoMNardi Dec 8, 2023
cf59ca1
Ci Job
RodrigoMNardi Dec 8, 2023
c0675a3
Merge remote-tracking branch 'origin/bug/ci_summary_check' into bug/c…
RodrigoMNardi Dec 8, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions bin/console.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,8 @@

require_relative '../database_loader'
require_relative '../lib/helpers/configuration'
require_relative '../lib/github/check'
require_relative '../lib/github/build/action'
require_relative '../lib/github/build/summary'

IRB.start
15 changes: 15 additions & 0 deletions db/migrate/20231108100757_add_ci_job_stage.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# SPDX-License-Identifier: BSD-2-Clause
#
# 20231023090822_create_pull_request_subscribe.rb
# Part of NetDEF CI System
#
# Copyright (c) 2023 by
# Network Device Education Foundation, Inc. ("NetDEF")
#
# frozen_string_literal: true

class AddCiJobStage < ActiveRecord::Migration[6.0]
def change
add_column :ci_jobs, :stage, :boolean, default: false
end
end
3 changes: 2 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

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

Expand Down Expand Up @@ -40,6 +40,7 @@
t.datetime "updated_at", null: false
t.bigint "check_suite_id"
t.integer "retry", default: 0
t.boolean "stage", default: false
t.index ["check_suite_id"], name: "index_ci_jobs_on_check_suite_id"
end

Expand Down
89 changes: 89 additions & 0 deletions lib/github/build/action.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# SPDX-License-Identifier: BSD-2-Clause
#
# action.rb
# Part of NetDEF CI System
#
# Copyright (c) 2023 by
# Network Device Education Foundation, Inc. ("NetDEF")
#
# frozen_string_literal: true

module Github
module Build
class Action
BUILD_STAGE = 'Build Stage'
TESTS_STAGE = 'Tests Stage'
SUMMARY = [BUILD_STAGE, TESTS_STAGE].freeze

def initialize(check_suite, github, logger_level: Logger::INFO)
@check_suite = check_suite
@github = github
@loggers = []

%w[github_app.log github_build_action.log].each do |filename|
logger_app = Logger.new(filename, 1, 1_024_000)
logger_app.level = logger_level

@loggers << logger_app
end
end

def create_summary
SUMMARY.each do |name|
stage = CiJob.find_by(name: name, check_suite: @check_suite)

logger(Logger::INFO, "STAGE #{name} #{stage.inspect}")

stage = create_stage(name) if stage.nil?

next if stage.nil?

logger(Logger::INFO, ">>> Enqueued #{stage.inspect}")

stage.enqueue(@github)
end
end

def create_stage(name)
bamboo_ci = @check_suite.bamboo_ci_ref.split('-').last

stage =
CiJob.create(check_suite: @check_suite, name: name, job_ref: "#{name}-#{bamboo_ci}", stage: true)

return stage if stage.persisted?

logger(Logger::ERROR, "Failed to created: #{stage.inspect} -> #{stage.errors.inspect}")

nil
end

def create_jobs(jobs, rerun: false)
jobs.each do |job|
ci_job = CiJob.create(check_suite: @check_suite, name: job[:name], job_ref: job[:job_ref])

next unless ci_job.persisted?

if rerun
url = "https://ci1.netdef.org/browse/#{ci_job.job_ref}"
ci_job.enqueue(@github, { title: ci_job.name, summary: "Details at [#{url}](#{url})" })
else
ci_job.create_check_run
end

next unless ci_job.checkout_code?

url = "https://ci1.netdef.org/browse/#{ci_job.job_ref}"
ci_job.in_progress(@github, { title: ci_job.name, summary: "Details at [#{url}](#{url})" })
end
end

private

def logger(severity, message)
@loggers.each do |logger_object|
logger_object.add(severity, message)
end
end
end
end
end
160 changes: 160 additions & 0 deletions lib/github/build/summary.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
# SPDX-License-Identifier: BSD-2-Clause
#
# summary.rb
# Part of NetDEF CI System
#
# Copyright (c) 2023 by
# Network Device Education Foundation, Inc. ("NetDEF")
#
# frozen_string_literal: true

require_relative '../../github/check'

module Github
module Build
class Summary
def initialize(job, logger_level: Logger::INFO)
@job = job.reload
@check_suite = @job.check_suite
@github = Github::Check.new(@check_suite)
@loggers = []

%w[github_app.log github_build_summary.log].each do |filename|
logger_app = Logger.new(filename, 1, 1_024_000)
logger_app.level = logger_level

@loggers << logger_app
end
end

def build_summary(name)
stage = @check_suite.ci_jobs.find_by(name: name)

return if stage.nil?

update_summary(stage, name)
finished_summary(stage)
missing_stage(stage)
end

def missing_stage(stage)
missing_test_stage(stage)
missing_build_stage
end

def missing_test_stage(stage)
tests_stage = @check_suite.ci_jobs.find_by(name: Github::Build::Action::TESTS_STAGE)
tests_failure = {
title: "#{Github::Build::Action::TESTS_STAGE} summary",
summary: 'Build Stage failed so it will not be possible to run the tests'
}

return tests_stage.failure(@github, tests_failure) if stage.build? and stage.failure?
return tests_stage.in_progress(@github) if stage.build? and stage.success?

return unless stage.test?
return unless @check_suite.finished?

update_tests_stage(tests_stage)
end

def missing_build_stage
build_stage = @check_suite.ci_jobs.find_by(name: Github::Build::Action::BUILD_STAGE)
failure = {
title: "#{Github::Build::Action::BUILD_STAGE} summary",
summary: 'Build stage failure. Please check Bamboo CI'
}

return if build_stage.nil?
return if build_stage.success? or build_stage.failure?
return unless @check_suite.build_stage_finished?

success = @check_suite.build_stage_success?
logger(Logger::INFO, "missing_build_stage: #{build_stage.inspect}, success: #{success}")

success ? build_stage.success(@github) : build_stage.failure(@github, failure)
end

def update_tests_stage(stage)
success = @check_suite.ci_jobs.skip_checkout_code.where(status: %w[failure cancelled]).empty?

output = { title: "#{stage.name} summary", summary: summary_failures_message(stage.name) }

logger(Logger::INFO, "update_tests_stage: #{stage.inspect}, success: #{success}")

success ? stage.success(@github) : stage.failure(@github, output)
end

def finished_summary(stage)
logger(Logger::INFO, "Finished stage: #{stage.inspect}, CiJob status: #{@job.status}")
return if @job.in_progress? or stage.failure?

finished_build_summary(stage)
finished_tests_summary(stage)
end

def finished_build_summary(stage)
return unless stage.build?
return unless @check_suite.build_stage_finished?

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

stage.success(@github)
end

def finished_tests_summary(stage)
return unless stage.test?
return unless @check_suite.finished?

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

stage.success(@github)
end

def update_summary(stage, name)
return unless %w[failure in_progress].include? @job.status

logger(Logger::INFO, "Updating summary status #{stage.inspect} -> @job.status: #{@job.status}")

output = { title: "#{name} summary", summary: summary_failures_message(name) }
stage.in_progress(@github, output) if stage.queued? and @job.in_progress?

return unless @job.failure?

logger(Logger::INFO, "(Failure) #{stage.inspect} -> @job.status: #{@job.status}")

stage.failure(@github, output)
end

def summary_failures_message(name)
filter = Github::Build::Action::BUILD_STAGE.include?(name) ? '.* (B|b)uild' : '(TopoTest|Check|Static)'

@check_suite.ci_jobs.skip_checkout_code.filter_by(filter).where(status: :failure).map do |job|
generate_message(name, job)
end.join("\n")[0..65_535]
end

private

def generate_message(name, job)
failures = name.downcase.match?('build') ? '' : tests_message(job)

"- #{job.name} #{job.status} -> https://ci1.netdef.org/browse/#{job.job_ref}\n#{failures}"
end

def tests_message(job)
failure = job.topotest_failures.first

return '' if failure.nil?

"\t :no_entry_sign: #{failure.test_suite} #{failure.test_case} \n```\n#{failure.message}\n```\n"
end

def logger(severity, message)
@loggers.each do |logger_object|
logger_object.add(severity, message)
end
end
end
end
end
22 changes: 5 additions & 17 deletions lib/github/build_plan.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
require_relative '../bamboo_ci/running_plan'
require_relative '../bamboo_ci/plan_run'
require_relative 'check'
require_relative 'build/action'

module Github
class BuildPlan
Expand Down Expand Up @@ -104,7 +105,7 @@ def stop_previous_execution
@logger.info @last_check_suite.inspect
@logger.info @check_suite.inspect

@last_check_suite.ci_jobs.where(status: %w[queued in_progress]).each do |ci_job|
@last_check_suite.ci_jobs.skip_stages.where(status: %w[queued in_progress]).each do |ci_job|
BambooCi::StopPlan.stop(ci_job.job_ref)

@logger.warn("Cancelling Job #{ci_job.inspect}")
Expand Down Expand Up @@ -141,26 +142,13 @@ def ci_jobs

return [422, 'Failed to fetch RunningPlan'] if jobs.nil? or jobs.empty?

create_ci_jobs(jobs)
action = Github::Build::Action.new(@check_suite, @github_check)
action.create_jobs(jobs)
action.create_summary

[200, 'Pull Request created']
end

def create_ci_jobs(jobs)
jobs.each do |job|
ci_job = CiJob.create(check_suite: @check_suite, name: job[:name], job_ref: job[:job_ref])

next unless ci_job.persisted?

ci_job.create_check_run

next unless ci_job.checkout_code?

url = "https://ci1.netdef.org/browse/#{ci_job.job_ref}"
ci_job.in_progress(@github_check, { title: ci_job.name, summary: "Details at [#{url}](#{url})" })
end
end

def ci_vars
ci_vars = []
ci_vars << { value: @github_check.signature, name: 'signature_secret' }
Expand Down
Loading