require 'rubygems' require 'pathname' require 'fileutils' require 'thread' require 'bundler' Bundler.require :default 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 :BuildMatrix, File.expand_path("../router/build_matrix", __FILE__) autoload :ScriptBuilder, File.expand_path("../router/script_builder", __FILE__) autoload :Travis, File.expand_path("../router/travis", __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__) 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, :path_prefix, :repo_dir, :travis def initialize(build, path_prefix) @build = build @path_prefix = Pathname.new(path_prefix).expand_path @repo_dir = @path_prefix.join(config.repo_dir_name) .join(build.message.name) @travis = nil end def perform log_build do update_build_status do create_repo_dir && fetch_repo && assign_commit_info && load_travis && create_and_delivery_build_matrix end end end def create_and_delivery_build_matrix matrix = BuildMatrix.new travis build.jobs_count = matrix.travises.size matrix.travises.each_with_index do |travis, idx| number = idx + 1 message = build.to_perform_job_message travis, number logger.info "delivery job #{message.id}.#{number} #{travis.to_matrix_s}" JobsConsumer.publish message end true end def load_travis @travis = Travis.from_file repo_dir.join(".travis.yml") @travis end def create_repo_dir FileUtils.mkdir_p(repo_dir) unless repo_dir.directory? true end def fetch_repo scm.fetch == 0 end def assign_commit_info build.commit_info = scm.commit_info true 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")}") end if rs publish_build_status_message Build::FINISHED else publish_build_status_message Build::FAILED end rs end private def scm @scm ||= SCM::Git.new( build.message.src, build.message.sha, repo_dir, deploy_key: build.message.deploy_key, &build.method(:add_to_output) ) end def publish_build_status_message(status) message = build.to_build_status_message(status) logger.info "delivered build status #{message.inspect}" BuildStatusConsumer.publish message end end end end