require 'rubygems' require 'pathname' require 'fileutils' require 'thread' require 'evrone/ci/common/error_notifier' require 'evrone/ci/build_configuration' require File.expand_path("../..", __FILE__) + "/ci/router/ext/string.rb" require File.expand_path("../..", __FILE__) + "/ci/router/ext/array.rb" module Evrone module CI class Router autoload :Configuration, File.expand_path("../router/configuration", __FILE__) autoload :Build, File.expand_path("../router/build", __FILE__) autoload :ScriptBuilder, File.expand_path("../router/script_builder", __FILE__) autoload :CLI, File.expand_path("../router/cli", __FILE__) autoload :BuildLogsConsumer, File.expand_path("../router/consumers/build_logs_consumer", __FILE__) autoload :BuildStatusConsumer, File.expand_path("../router/consumers/build_status_consumer", __FILE__) autoload :BuildsConsumer, File.expand_path("../router/consumers/builds_consumer", __FILE__) autoload :JobsConsumer, File.expand_path("../router/consumers/jobs_consumer", __FILE__) autoload :JobStatusConsumer, File.expand_path("../router/consumers/job_status_consumer", __FILE__) module Helper autoload :Config, File.expand_path("../router/helper/config", __FILE__) autoload :Logger, File.expand_path("../router/helper/logger", __FILE__) autoload :TraceShCommand, File.expand_path("../router/helper/trace_sh_command", __FILE__) end @@root = Pathname.new File.expand_path('../../../..', __FILE__) @@config_mutex = Mutex.new class << self def root @@root end def logger config.logger end def configure yield config config end def config @config ||= begin @@config_mutex.synchronize do Configuration.new end end end def reset_config! @config = nil end def initialize! root.join("lib/evrone/ci/router/initializers").children.each do |e| require e end end end include Helper::Logger include Helper::Config attr_reader :build, :configuration def initialize(build) @build = build @configuration = nil end def perform log_build do update_build_status do load_configuration && create_and_delivery_build_matrix end end build.release end def create_and_delivery_build_matrix matrix = BuildConfiguration::Matrix.new configuration build.jobs_count = matrix.configurations.size matrix.configurations.each_with_index do |c, idx| number = idx + 1 message = build.to_perform_job_message c, number logger.info "delivery job #{message.id}.#{number} #{c.to_matrix_s}" JobsConsumer.publish message publish_job_status_message build, c, number end true end def load_configuration @configuration = BuildConfiguration.from_yaml build.message.travis @configuration end def log_build logger.tagged("build #{build.message.id}") do logger.info "starting build" rs = yield logger.info "done build" rs end end def update_build_status publish_build_status_message Build::STARTED rs = false begin rs = yield rescue Exception => e logger.error("ERROR: #{e.inspect}\n BACKTRACE:\n#{e.backtrace.map{|i| " #{i}" }.join("\n")}") Common::ErrorNotifier.notify(e) end if rs publish_build_status_message Build::FINISHED else publish_build_status_message Build::FAILED end rs end private def publish_build_status_message(status) message = build.to_build_status_message(status) logger.info "delivered build status #{message.inspect}" BuildStatusConsumer.publish message end def publish_job_status_message(build, travis, job_number) message = Message::JobStatus.new( build_id: build.message.id, job_id: job_number, status: Build::INITIALIED, tm: Time.now.to_i, matrix: travis.matrix_keys ) logger.info "delivery job status #{message.inspect}" JobStatusConsumer.publish message end end end end