evrone-ci-router 0.2.0.pre0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +7 -0
- data/.rspec +3 -0
- data/Gemfile +7 -0
- data/README.md +1 -0
- data/Rakefile +22 -0
- data/bin/cli +3 -0
- data/bin/git_ssh +3 -0
- data/bin/jobs_publisher +12 -0
- data/bin/workers +13 -0
- data/evrone-ci-router.gemspec +30 -0
- data/fixtures/travis.yml +5 -0
- data/lib/evrone/ci/router.rb +100 -0
- data/lib/evrone/ci/router/build.rb +60 -0
- data/lib/evrone/ci/router/build_matrix.rb +89 -0
- data/lib/evrone/ci/router/configuration.rb +27 -0
- data/lib/evrone/ci/router/consumers/build_logs_consumer.rb +15 -0
- data/lib/evrone/ci/router/consumers/build_status_consumer.rb +15 -0
- data/lib/evrone/ci/router/consumers/builds_consumer.rb +28 -0
- data/lib/evrone/ci/router/consumers/jobs_consumer.rb +15 -0
- data/lib/evrone/ci/router/ext/array.rb +5 -0
- data/lib/evrone/ci/router/ext/string.rb +9 -0
- data/lib/evrone/ci/router/helper/config.rb +13 -0
- data/lib/evrone/ci/router/helper/logger.rb +13 -0
- data/lib/evrone/ci/router/helper/trace_sh_command.rb +14 -0
- data/lib/evrone/ci/router/initializers/amqp.rb +63 -0
- data/lib/evrone/ci/router/middleware/create_build_matrix.rb +54 -0
- data/lib/evrone/ci/router/middleware/create_dirs.rb +25 -0
- data/lib/evrone/ci/router/middleware/fetch_commit_info.rb +22 -0
- data/lib/evrone/ci/router/middleware/fetch_source.rb +36 -0
- data/lib/evrone/ci/router/middleware/log_build.rb +24 -0
- data/lib/evrone/ci/router/middleware/travis/env.rb +21 -0
- data/lib/evrone/ci/router/middleware/travis/ruby.rb +55 -0
- data/lib/evrone/ci/router/middleware/travis/script.rb +25 -0
- data/lib/evrone/ci/router/middleware/update_build_status.rb +75 -0
- data/lib/evrone/ci/router/queue.rb +58 -0
- data/lib/evrone/ci/router/travis.rb +104 -0
- data/lib/evrone/ci/router/travis/serializable.rb +45 -0
- data/lib/evrone/ci/router/version.rb +7 -0
- data/spec/lib/build_matrix_spec.rb +145 -0
- data/spec/lib/build_spec.rb +75 -0
- data/spec/lib/configuration_spec.rb +22 -0
- data/spec/lib/middleware/create_build_matrix_spec.rb +73 -0
- data/spec/lib/middleware/create_dirs_spec.rb +26 -0
- data/spec/lib/middleware/fetch_commit_info_spec.rb +23 -0
- data/spec/lib/middleware/fetch_source_spec.rb +27 -0
- data/spec/lib/middleware/log_build_spec.rb +14 -0
- data/spec/lib/middleware/update_build_status_spec.rb +70 -0
- data/spec/lib/queue_spec.rb +55 -0
- data/spec/lib/travis_spec.rb +182 -0
- data/spec/spec_helper.rb +17 -0
- data/spec/support/create.rb +47 -0
- data/spec/support/fixture.rb +7 -0
- data/spec/support/shared_examples/update_build_status_message.rb +5 -0
- metadata +228 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: bfbf13a7842e030d4d20aa825df0c5aede860177
|
4
|
+
data.tar.gz: da99904e2ddeacee3c87c9b9c56a63e6981dd860
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d645737756afe9953e85d2054fe436dff8b3dd8b5e7aa209d9f023e2f732c114809db6ded81b28a5f708c7f71405791b69cbdccf3574934e3ee9ff599be9f5e5
|
7
|
+
data.tar.gz: 9cc5c15fb61e8ffb93809e24c6a979f5218bfca721fceb676456c2b1e6a44831759b38b5ea2359a75753cc773af41ec776ead1df21e9130822376bde7245e3a4
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
Bundler.require
|
4
|
+
require 'rspec/core/rake_task'
|
5
|
+
require "bundler/gem_tasks"
|
6
|
+
|
7
|
+
RSpec::Core::RakeTask.new(:spec)
|
8
|
+
|
9
|
+
task :default => ["test:create_repo", :spec]
|
10
|
+
|
11
|
+
namespace :test do
|
12
|
+
task :create_repo do
|
13
|
+
dir = "fixtures/repo"
|
14
|
+
unless File.directory? dir
|
15
|
+
cmd = "git clone https://github.com/evrone/ci-worker-test-repo.git fixtures/repo"
|
16
|
+
puts cmd
|
17
|
+
system cmd
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
task :travis => :default
|
data/bin/cli
ADDED
data/bin/git_ssh
ADDED
data/bin/jobs_publisher
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require File.expand_path("../../lib/evrone/ci/router", __FILE__)
|
4
|
+
|
5
|
+
require File.expand_path("../../spec/support/fixture", __FILE__)
|
6
|
+
require File.expand_path("../../spec/support/create", __FILE__)
|
7
|
+
|
8
|
+
require 'evrone/ci/message/testing'
|
9
|
+
|
10
|
+
include Evrone::CI
|
11
|
+
|
12
|
+
Router::BuildsConsumer.publish Message::PerformBuild.test_message
|
data/bin/workers
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require File.expand_path("../../lib/evrone/ci/router", __FILE__)
|
4
|
+
|
5
|
+
trap('INT') {
|
6
|
+
Thread.new do
|
7
|
+
Evrone::Common::AMQP.shutdown
|
8
|
+
end.join
|
9
|
+
}
|
10
|
+
|
11
|
+
Evrone::Common::AMQP::Supervisor::Threaded.build(
|
12
|
+
Evrone::CI::Router::BuildsConsumer => 1,
|
13
|
+
).run
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require File.expand_path('../lib/evrone/ci/router/version.rb', __FILE__)
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "evrone-ci-router"
|
8
|
+
spec.version = Evrone::CI::Router::VERSION
|
9
|
+
spec.authors = ["Dmitry Galinsky"]
|
10
|
+
spec.email = ["dima.exe@gmail.com"]
|
11
|
+
spec.description = %q{ ci router }
|
12
|
+
spec.summary = %q{ ci router }
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_runtime_dependency 'evrone-ci-common', "= #{Evrone::CI::Router::VERSION}"
|
22
|
+
spec.add_runtime_dependency 'evrone-ci-message', "= #{Evrone::CI::Router::VERSION}"
|
23
|
+
spec.add_runtime_dependency 'evrone-common-amqp', '~> 0.1.1'
|
24
|
+
spec.add_runtime_dependency 'hashr', '= 0.0.22'
|
25
|
+
|
26
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
27
|
+
spec.add_development_dependency "rake"
|
28
|
+
spec.add_development_dependency "rspec"
|
29
|
+
spec.add_development_dependency "rr"
|
30
|
+
end
|
data/fixtures/travis.yml
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
Bundler.require :default
|
4
|
+
|
5
|
+
require 'pathname'
|
6
|
+
|
7
|
+
require File.expand_path("../..", __FILE__) + "/ci/router/ext/string.rb"
|
8
|
+
require File.expand_path("../..", __FILE__) + "/ci/router/ext/array.rb"
|
9
|
+
|
10
|
+
module Evrone
|
11
|
+
module CI
|
12
|
+
class Router
|
13
|
+
|
14
|
+
autoload :Configuration, File.expand_path("../router/configuration", __FILE__)
|
15
|
+
autoload :Build, File.expand_path("../router/build", __FILE__)
|
16
|
+
autoload :BuildMatrix, File.expand_path("../router/build_matrix", __FILE__)
|
17
|
+
autoload :Queue, File.expand_path("../router/queue", __FILE__)
|
18
|
+
autoload :Travis, File.expand_path("../router/travis", __FILE__)
|
19
|
+
|
20
|
+
autoload :BuildLogsConsumer, File.expand_path("../router/consumers/build_logs_consumer", __FILE__)
|
21
|
+
autoload :BuildStatusConsumer, File.expand_path("../router/consumers/build_status_consumer", __FILE__)
|
22
|
+
autoload :BuildsConsumer, File.expand_path("../router/consumers/builds_consumer", __FILE__)
|
23
|
+
autoload :JobsConsumer, File.expand_path("../router/consumers/jobs_consumer", __FILE__)
|
24
|
+
|
25
|
+
module Helper
|
26
|
+
autoload :Config, File.expand_path("../router/helper/config", __FILE__)
|
27
|
+
autoload :Logger, File.expand_path("../router/helper/logger", __FILE__)
|
28
|
+
autoload :TraceShCommand, File.expand_path("../router/helper/trace_sh_command", __FILE__)
|
29
|
+
end
|
30
|
+
|
31
|
+
module Middleware
|
32
|
+
module Travis
|
33
|
+
autoload :Env, File.expand_path("../router/middleware/travis/env", __FILE__)
|
34
|
+
autoload :Ruby, File.expand_path("../router/middleware/travis/ruby", __FILE__)
|
35
|
+
autoload :Script, File.expand_path("../router/middleware/travis/script", __FILE__)
|
36
|
+
end
|
37
|
+
autoload :CreateBuildMatrix, File.expand_path("../router/middleware/create_build_matrix", __FILE__)
|
38
|
+
autoload :FetchSource, File.expand_path("../router/middleware/fetch_source", __FILE__)
|
39
|
+
autoload :FetchCommitInfo, File.expand_path("../router/middleware/fetch_commit_info", __FILE__)
|
40
|
+
autoload :LogBuild, File.expand_path("../router/middleware/log_build", __FILE__)
|
41
|
+
autoload :UpdateBuildStatus, File.expand_path("../router/middleware/update_build_status", __FILE__)
|
42
|
+
autoload :CreateDirs, File.expand_path("../router/middleware/create_dirs", __FILE__)
|
43
|
+
end
|
44
|
+
|
45
|
+
@@root = Pathname.new File.expand_path('../../../..', __FILE__)
|
46
|
+
@@config = Configuration.new
|
47
|
+
|
48
|
+
class << self
|
49
|
+
def root
|
50
|
+
@@root
|
51
|
+
end
|
52
|
+
|
53
|
+
def logger
|
54
|
+
config.logger
|
55
|
+
end
|
56
|
+
|
57
|
+
def configure
|
58
|
+
yield config
|
59
|
+
config
|
60
|
+
end
|
61
|
+
|
62
|
+
def config
|
63
|
+
@@config
|
64
|
+
end
|
65
|
+
|
66
|
+
def reset_config!
|
67
|
+
@@config = Configuration.new
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
include Common::Helper::Middlewares
|
72
|
+
|
73
|
+
middlewares do
|
74
|
+
use Middleware::LogBuild
|
75
|
+
use Middleware::UpdateBuildStatus
|
76
|
+
use Middleware::CreateDirs
|
77
|
+
use Middleware::FetchSource
|
78
|
+
use Middleware::FetchCommitInfo
|
79
|
+
use Middleware::CreateBuildMatrix
|
80
|
+
end
|
81
|
+
|
82
|
+
attr_reader :build, :path_prefix
|
83
|
+
|
84
|
+
def initialize(build, path_prefix)
|
85
|
+
@build = build
|
86
|
+
@path_prefix = Pathname.new(path_prefix).expand_path
|
87
|
+
end
|
88
|
+
|
89
|
+
def perform
|
90
|
+
env = OpenStruct.new build: build, path_prefix: path_prefix
|
91
|
+
run_middlewares(env) { |_| 0 }
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
Evrone::CI::Router.root.join("lib/evrone/ci/router/initializers").children.each do |e|
|
99
|
+
require e
|
100
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'evrone/ci/message'
|
2
|
+
require 'evrone/ci/common'
|
3
|
+
|
4
|
+
module Evrone
|
5
|
+
module CI
|
6
|
+
class Router
|
7
|
+
class Build
|
8
|
+
|
9
|
+
include Router::Helper::Logger
|
10
|
+
include Router::Helper::Config
|
11
|
+
|
12
|
+
attr_reader :message, :output
|
13
|
+
attr_accessor :matrix, :jobs_count, :commit_info
|
14
|
+
|
15
|
+
def initialize(perform_build_message)
|
16
|
+
@output = ''
|
17
|
+
@message = perform_build_message
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_perform_job_message(travis, job_id)
|
21
|
+
queue = travis.to_queue
|
22
|
+
job_message = Message::PerformJob.new(
|
23
|
+
id: message.id,
|
24
|
+
name: message.name,
|
25
|
+
src: message.src,
|
26
|
+
sha: message.sha,
|
27
|
+
pull_request_id: message.pull_request_id,
|
28
|
+
deploy_key: message.deploy_key,
|
29
|
+
job_id: job_id,
|
30
|
+
before_script: queue.to_before_script,
|
31
|
+
script: queue.to_script,
|
32
|
+
matrix_keys: travis.matrix_keys,
|
33
|
+
)
|
34
|
+
job_message
|
35
|
+
end
|
36
|
+
|
37
|
+
def add_to_output(str)
|
38
|
+
output << str
|
39
|
+
logger.debug str.strip if logger.level == 0
|
40
|
+
BuildLogsConsumer.publish create_build_log_message(str)
|
41
|
+
end
|
42
|
+
|
43
|
+
def add_command_to_output(cmd)
|
44
|
+
add_to_output "$ #{cmd}\n"
|
45
|
+
end
|
46
|
+
|
47
|
+
def create_build_log_message(data)
|
48
|
+
tm = Time.now
|
49
|
+
Message::BuildLog.new(
|
50
|
+
build_id: message.id,
|
51
|
+
tm: tm.to_i,
|
52
|
+
tm_usec: tm.usec,
|
53
|
+
log: data
|
54
|
+
)
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module Evrone
|
2
|
+
module CI
|
3
|
+
class Router
|
4
|
+
class BuildMatrix
|
5
|
+
|
6
|
+
KEYS = (Travis::LANGS + %w{ env }).freeze
|
7
|
+
|
8
|
+
attr_reader :travis
|
9
|
+
|
10
|
+
def initialize(travis)
|
11
|
+
@travis = travis
|
12
|
+
end
|
13
|
+
|
14
|
+
def keys
|
15
|
+
extract_pair_of_key_and_values.map(&:first).sort
|
16
|
+
end
|
17
|
+
|
18
|
+
def travises
|
19
|
+
attributes_for_new_travises.map do |attrs|
|
20
|
+
Travis.new attrs
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def attributes_for_new_travises
|
25
|
+
permutate_and_build_values.inject([]) do |ac, values|
|
26
|
+
ac << values.inject({}) do |a,val|
|
27
|
+
a[val.key] = val.value
|
28
|
+
a
|
29
|
+
end
|
30
|
+
ac
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def permutate_and_build_values
|
35
|
+
values = extract_pair_of_key_and_values.map do |key, vals|
|
36
|
+
vals.map{|it| Value.new(key, it) }
|
37
|
+
end
|
38
|
+
if matrix_values?(values)
|
39
|
+
array_permutations(values).map do |it|
|
40
|
+
if it.is_a?(Array)
|
41
|
+
it.flatten
|
42
|
+
else
|
43
|
+
[it]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
else
|
47
|
+
values
|
48
|
+
end.sort_by(&:to_s)
|
49
|
+
end
|
50
|
+
|
51
|
+
def extract_pair_of_key_and_values
|
52
|
+
KEYS.map.inject([]) do |a, k|
|
53
|
+
if (val = travis[k]) && !val.empty?
|
54
|
+
a << [k, val]
|
55
|
+
end
|
56
|
+
a
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def matrix_values?(values)
|
63
|
+
!values.all?{|i| i.size == 1 }
|
64
|
+
end
|
65
|
+
|
66
|
+
def array_permutations array, index=0
|
67
|
+
# index is 0 by default : start at the beginning, more elegant.
|
68
|
+
return array[-1] if index == array.size - 1 # Return last element if at end.
|
69
|
+
|
70
|
+
result = []
|
71
|
+
|
72
|
+
array[index].each do |element| # For each array
|
73
|
+
array_permutations(array, index + 1).each do |x| # Permute permute permute
|
74
|
+
result << [element, x]
|
75
|
+
end
|
76
|
+
end
|
77
|
+
result
|
78
|
+
end
|
79
|
+
|
80
|
+
Value = Struct.new(:key, :value) do
|
81
|
+
def to_s
|
82
|
+
[key, value].join(":")
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'hashr'
|
2
|
+
require 'logger'
|
3
|
+
require 'evrone/ci/common/tagged_logging'
|
4
|
+
|
5
|
+
module Evrone
|
6
|
+
module CI
|
7
|
+
class Router
|
8
|
+
class Configuration < ::Hashr
|
9
|
+
|
10
|
+
extend Hashr::EnvDefaults
|
11
|
+
|
12
|
+
self.env_namespace = 'ci_router'
|
13
|
+
self.raise_missing_keys = true
|
14
|
+
|
15
|
+
define amqp_url: nil,
|
16
|
+
timeout: 30 * 60,
|
17
|
+
logger: Common::TaggedLogging.new(Logger.new STDOUT),
|
18
|
+
repo_dir_name: "repo"
|
19
|
+
|
20
|
+
def timeout
|
21
|
+
self[:timeout].to_i
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|