pipely 0.6.2 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/pipely/deploy/bootstrap.rb +115 -0
- data/lib/pipely/deploy/client.rb +2 -0
- data/lib/pipely/tasks.rb +1 -0
- data/lib/pipely/tasks/upload_pipeline_as_gem.rb +81 -0
- data/lib/pipely/tasks/upload_steps.rb +7 -6
- data/lib/pipely/version.rb +1 -1
- data/spec/fixtures/vcr_cassettes/build_and_upload_gems.yml +47 -0
- data/spec/lib/pipely/deploy/bootstrap_spec.rb +86 -0
- data/spec/spec_helper.rb +23 -1
- metadata +50 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ffc556ad3308b03b691185eb21f4ee10f26592f9
|
4
|
+
data.tar.gz: caf8a2a7b8c63c281979bde1ad75f75bdc0f963f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3b6a6b168162ec377f29e5f416a956fa90c3a1d7a21c462f5104d0ebf8db11d340e95b90ddbaf6a5de74f21673cb15084e2a99eb156d200b69acc54d6243bd06
|
7
|
+
data.tar.gz: 7b659bdb5a01ebe0b4306a3a8c8ec7c426df709e3e56df95a50c1f7134fa3c7d5235efd887b187d1ebbf1c545c2d57d50c33bcb6fa4599a167e6b5930271eda6
|
@@ -0,0 +1,115 @@
|
|
1
|
+
module Pipely
|
2
|
+
module Deploy
|
3
|
+
|
4
|
+
# Helps bootstrap a pipeline
|
5
|
+
class Bootstrap
|
6
|
+
|
7
|
+
attr_reader :bucket_name
|
8
|
+
attr_reader :s3_gems_path
|
9
|
+
attr_reader :project_spec
|
10
|
+
attr_reader :gem_files
|
11
|
+
|
12
|
+
def initialize(s3_bucket, s3_gems_path)
|
13
|
+
@s3_bucket = s3_bucket
|
14
|
+
@bucket_name = s3_bucket.name
|
15
|
+
@s3_gems_path = s3_gems_path
|
16
|
+
end
|
17
|
+
|
18
|
+
# Builds the project's gem from gemspec, uploads the gem to s3, and
|
19
|
+
# uploads all the gem dependences to S3
|
20
|
+
def build_and_upload_gems
|
21
|
+
|
22
|
+
# placeholder, name will be nil if a gemspec is not defined
|
23
|
+
project_gem_name = nil
|
24
|
+
|
25
|
+
gem_spec = Dir.glob("*.gemspec").first
|
26
|
+
if gem_spec
|
27
|
+
|
28
|
+
# Build pipeline gem
|
29
|
+
@project_spec = Gem::Specification::load(gem_spec)
|
30
|
+
# build the gem
|
31
|
+
project_gem_file =
|
32
|
+
`gem build ./#{gem_spec}`.scan(
|
33
|
+
/File:(.+.gem)$/).flatten.first.strip
|
34
|
+
project_gem_name = @project_spec.name
|
35
|
+
upload_gem(project_gem_file)
|
36
|
+
end
|
37
|
+
|
38
|
+
@gem_files = upload_gems_from_bundler(project_gem_name)
|
39
|
+
|
40
|
+
# project gem has to be loaded last
|
41
|
+
@gem_files << project_gem_file if @project_spec
|
42
|
+
end
|
43
|
+
|
44
|
+
def context
|
45
|
+
BootstrapContext.new(
|
46
|
+
@gem_files.map{ |file|
|
47
|
+
File.join("s3://", @s3_bucket.name, gem_s3_path(file) )
|
48
|
+
} )
|
49
|
+
end
|
50
|
+
|
51
|
+
def gem_s3_path(gem_file)
|
52
|
+
filename = File.basename(gem_file)
|
53
|
+
File.join(@s3_gems_path, filename)
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def s3_gem_exists?( gem_file )
|
59
|
+
!@s3_bucket.objects[gem_s3_path(gem_file)].nil?
|
60
|
+
end
|
61
|
+
|
62
|
+
def upload_gem( gem_file )
|
63
|
+
puts "uploading #{gem_file} to #{gem_s3_path(gem_file)}"
|
64
|
+
@s3_bucket.objects[gem_s3_path(gem_file)].write(File.open(gem_file))
|
65
|
+
end
|
66
|
+
|
67
|
+
def upload_gems_from_bundler(project_gem_name)
|
68
|
+
gem_files = []
|
69
|
+
Bundler.definition.specs_for([:default]).each do |spec|
|
70
|
+
# Exclude project from gem deps
|
71
|
+
unless spec.name == project_gem_name
|
72
|
+
gem_file = spec.cache_file
|
73
|
+
|
74
|
+
# XXX: Some gems do not exist in the cache, e.g. json. Looks the
|
75
|
+
# gem is already packaged with the ruby dist
|
76
|
+
if File.exists? gem_file
|
77
|
+
gem_files << gem_file
|
78
|
+
|
79
|
+
# only upload gem if it doesnt exist already
|
80
|
+
unless s3_gem_exists?( gem_file )
|
81
|
+
upload_gem(gem_file)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
gem_files
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
# Context passed to the erb templates
|
92
|
+
class BootstrapContext
|
93
|
+
attr_reader :gem_files
|
94
|
+
|
95
|
+
def initialize(gem_files)
|
96
|
+
@gem_files = gem_files
|
97
|
+
end
|
98
|
+
|
99
|
+
def install_gems_script
|
100
|
+
script = ""
|
101
|
+
|
102
|
+
@gem_files.each do |gem_file|
|
103
|
+
filename = File.basename(gem_file)
|
104
|
+
script << %Q[
|
105
|
+
# #{filename}
|
106
|
+
hadoop fs -copyToLocal #{gem_file} /home/hadoop/#{filename}
|
107
|
+
gem install --local /home/hadoop/#{filename} --no-ri --no-rdoc
|
108
|
+
]
|
109
|
+
end
|
110
|
+
|
111
|
+
script
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
data/lib/pipely/deploy/client.rb
CHANGED
data/lib/pipely/tasks.rb
CHANGED
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'aws'
|
3
|
+
require 'pipely/deploy/bootstrap'
|
4
|
+
|
5
|
+
module Pipely
|
6
|
+
module Tasks
|
7
|
+
class UploadPipelineAsGem < ::Rake::TaskLib
|
8
|
+
include ::Rake::DSL if defined?(::Rake::DSL)
|
9
|
+
|
10
|
+
# Name of this rake task
|
11
|
+
attr_accessor :name
|
12
|
+
|
13
|
+
attr_accessor :bucket_name
|
14
|
+
attr_accessor :s3_steps_path
|
15
|
+
attr_accessor :s3_gems_path
|
16
|
+
attr_accessor :config
|
17
|
+
|
18
|
+
def initialize(*args, &task_block)
|
19
|
+
setup_ivars(args)
|
20
|
+
|
21
|
+
task name, *args do |_, task_args|
|
22
|
+
RakeFileUtils.send(:verbose, verbose) do
|
23
|
+
if task_block
|
24
|
+
task_block.call(*[self, task_args].slice(0, task_block.arity))
|
25
|
+
end
|
26
|
+
|
27
|
+
run_task verbose
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
Rake::Task["upload_steps"].enhance [name]
|
32
|
+
end
|
33
|
+
|
34
|
+
def setup_ivars(args)
|
35
|
+
@name = args.shift || 'deploy:upload_pipeline_as_gem'
|
36
|
+
@verbose = true
|
37
|
+
end
|
38
|
+
|
39
|
+
def run_task(verbose)
|
40
|
+
context = build_bootstrap_context
|
41
|
+
|
42
|
+
Dir.glob("templates/*.erb").each do |erb_file|
|
43
|
+
upload_filename = File.basename(erb_file).sub( /\.erb$/, '' )
|
44
|
+
|
45
|
+
# Exclude the pipeline.json
|
46
|
+
if upload_filename == 'pipeline.json'
|
47
|
+
next
|
48
|
+
end
|
49
|
+
|
50
|
+
template_erb = Erubis::Eruby.new( File.read(erb_file) )
|
51
|
+
upload_to_s3( upload_filename, template_erb.result(context) )
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
def s3_bucket
|
57
|
+
s3 = AWS::S3.new
|
58
|
+
s3.buckets[@bucket_name]
|
59
|
+
end
|
60
|
+
|
61
|
+
def build_bootstrap_context
|
62
|
+
bootstrap_helper =
|
63
|
+
Pipely::Deploy::Bootstrap.new(s3_bucket, @s3_gems_path)
|
64
|
+
bootstrap_helper.build_and_upload_gems
|
65
|
+
|
66
|
+
# erb context
|
67
|
+
{
|
68
|
+
bootstrap: bootstrap_helper.context,
|
69
|
+
config: config
|
70
|
+
}
|
71
|
+
end
|
72
|
+
|
73
|
+
def upload_to_s3( upload_filename, body )
|
74
|
+
|
75
|
+
s3_dest = File.join(@s3_steps_path, upload_filename)
|
76
|
+
puts "uploading #{s3_dest}" if verbose
|
77
|
+
s3_bucket.objects[s3_dest].write(body)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -1,6 +1,5 @@
|
|
1
1
|
require 'rake'
|
2
2
|
require 'rake/tasklib'
|
3
|
-
require 'fog'
|
4
3
|
|
5
4
|
module Pipely
|
6
5
|
module Tasks
|
@@ -57,11 +56,11 @@ module Pipely
|
|
57
56
|
end
|
58
57
|
|
59
58
|
def run_task(verbose)
|
60
|
-
with_bucket do |
|
59
|
+
with_bucket do |bucket|
|
61
60
|
step_files.each do |file_name|
|
62
61
|
dest = file_name.sub(/^#{local_path}/, s3_path)
|
63
62
|
puts "uploading #{dest}" if verbose
|
64
|
-
|
63
|
+
bucket.objects[dest].write(File.read(file_name))
|
65
64
|
end
|
66
65
|
end
|
67
66
|
end
|
@@ -69,9 +68,11 @@ module Pipely
|
|
69
68
|
private
|
70
69
|
|
71
70
|
def with_bucket
|
72
|
-
|
73
|
-
|
74
|
-
|
71
|
+
s3 = AWS::S3.new
|
72
|
+
bucket = s3.buckets[s3_bucket_name]
|
73
|
+
|
74
|
+
if bucket.exists?
|
75
|
+
yield(bucket)
|
75
76
|
else
|
76
77
|
raise "Couldn't find S3 bucket '#{s3_bucket_name}'"
|
77
78
|
end
|
data/lib/pipely/version.rb
CHANGED
@@ -0,0 +1,47 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: put
|
5
|
+
uri: https://a-test-bucket.s3.amazonaws.com/test_path/gems/pipely-0.7.0.gem
|
6
|
+
body:
|
7
|
+
encoding: UTF-8
|
8
|
+
string: !binary |-
|
9
|
+
bWV0YWRhdGEuZ3oAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
10
|
+
headers:
|
11
|
+
Content-Type:
|
12
|
+
- ''
|
13
|
+
Accept-Encoding:
|
14
|
+
- ''
|
15
|
+
Content-Length:
|
16
|
+
- '21504'
|
17
|
+
User-Agent:
|
18
|
+
- aws-sdk-ruby/1.50.0 ruby/2.0.0 x86_64-darwin13.3.0
|
19
|
+
Date:
|
20
|
+
- Wed, 10 Sep 2014 00:58:35 GMT
|
21
|
+
Authorization:
|
22
|
+
- AWS 123
|
23
|
+
Accept:
|
24
|
+
- '*/*'
|
25
|
+
response:
|
26
|
+
status:
|
27
|
+
code: 200
|
28
|
+
message: OK
|
29
|
+
headers:
|
30
|
+
X-Amz-Id-2:
|
31
|
+
- 123
|
32
|
+
X-Amz-Request-Id:
|
33
|
+
- 123
|
34
|
+
Date:
|
35
|
+
- Wed, 10 Sep 2014 00:58:36 GMT
|
36
|
+
Etag:
|
37
|
+
- '"123"'
|
38
|
+
Content-Length:
|
39
|
+
- '0'
|
40
|
+
Server:
|
41
|
+
- AmazonS3
|
42
|
+
body:
|
43
|
+
encoding: UTF-8
|
44
|
+
string: ''
|
45
|
+
http_version:
|
46
|
+
recorded_at: Wed, 10 Sep 2014 00:58:35 GMT
|
47
|
+
recorded_with: VCR 2.9.2
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# Copyright Swipely, Inc. All rights reserved.
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
require 'pipely/deploy/bootstrap'
|
5
|
+
require 'fog'
|
6
|
+
require 'fileutils'
|
7
|
+
|
8
|
+
module Pipely
|
9
|
+
describe Deploy::Bootstrap do
|
10
|
+
subject { described_class.new(s3_bucket, 'test_path/gems') }
|
11
|
+
let(:s3_bucket) do
|
12
|
+
s3 = AWS::S3.new
|
13
|
+
s3.buckets['a-test-bucket']
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should have bucket name" do
|
17
|
+
expect(subject.bucket_name).to eql 'a-test-bucket'
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should have a s3 gems path" do
|
21
|
+
expect(subject.s3_gems_path).to eql 'test_path/gems'
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "#build_and_upload_gems" do
|
25
|
+
let(:build_and_upload_gems) do
|
26
|
+
VCR.use_cassette('build_and_upload_gems') do
|
27
|
+
subject.build_and_upload_gems
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should create project gem" do
|
32
|
+
build_and_upload_gems
|
33
|
+
|
34
|
+
expect(File).to exist(subject.project_spec.file_name)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should upload gems" do
|
38
|
+
specs = Bundler.definition.specs_for([:default])
|
39
|
+
|
40
|
+
gems = specs.map(&:file_name).reject do |g|
|
41
|
+
# Ignore bundler, since it could be a system installed gem (travis)
|
42
|
+
# without a cache file
|
43
|
+
g.match(/^json-\d+\.\d+\.\d+\.gem$/) or
|
44
|
+
g.match(/^bundler-\d+\.\d+\.\d+\.gem$/)
|
45
|
+
end
|
46
|
+
|
47
|
+
objects = double(:objects)
|
48
|
+
s3_object = double('s3_object', write: nil)
|
49
|
+
|
50
|
+
allow(objects).to receive(:[]) { s3_object }
|
51
|
+
|
52
|
+
gems.each do |gem|
|
53
|
+
expect(objects).to receive(:[]).with(subject.gem_s3_path(gem))
|
54
|
+
end
|
55
|
+
|
56
|
+
expect(s3_bucket).to(receive(:objects)).
|
57
|
+
at_least(gems.size).times.
|
58
|
+
at_most(gems.size + 1).times. # allow for Bundler
|
59
|
+
and_return(objects)
|
60
|
+
|
61
|
+
build_and_upload_gems
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe "#context" do
|
66
|
+
let(:context) { subject.context}
|
67
|
+
|
68
|
+
before do
|
69
|
+
VCR.use_cassette('build_and_upload_gems') do
|
70
|
+
subject.build_and_upload_gems
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should have gem_files" do
|
75
|
+
expect(context.gem_files).to_not be_nil
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should be an s3 url" do
|
79
|
+
expect(context.gem_files.first).to(
|
80
|
+
match( /^s3:\/\/#{subject.bucket_name}\/#{subject.s3_gems_path}/ )
|
81
|
+
)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,9 +1,31 @@
|
|
1
1
|
require 'timecop'
|
2
|
+
require 'aws-sdk'
|
2
3
|
require 'fog'
|
4
|
+
require 'rspec'
|
5
|
+
require 'vcr'
|
6
|
+
|
7
|
+
$LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'lib')
|
8
|
+
|
9
|
+
AWS.config(
|
10
|
+
access_key_id: "xxx",
|
11
|
+
secret_access_key: "xxx"
|
12
|
+
)
|
3
13
|
|
4
14
|
Fog.credentials = {
|
5
15
|
aws_access_key_id: "xxx",
|
6
16
|
aws_secret_access_key: "xxx"
|
7
17
|
}
|
8
18
|
|
9
|
-
|
19
|
+
VCR.configure do |c|
|
20
|
+
c.allow_http_connections_when_no_cassette = true
|
21
|
+
c.cassette_library_dir = 'spec/fixtures/vcr_cassettes'
|
22
|
+
c.hook_into :webmock
|
23
|
+
end
|
24
|
+
|
25
|
+
class WebMock::StubSocket
|
26
|
+
attr_accessor :continue_timeout, :read_timeout
|
27
|
+
|
28
|
+
def closed?
|
29
|
+
true
|
30
|
+
end
|
31
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pipely
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matt Gillooly
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-09-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ruby-graphviz
|
@@ -122,6 +122,20 @@ dependencies:
|
|
122
122
|
- - ">="
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: erubis
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :runtime
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
125
139
|
- !ruby/object:Gem::Dependency
|
126
140
|
name: rspec
|
127
141
|
requirement: !ruby/object:Gem::Requirement
|
@@ -164,6 +178,34 @@ dependencies:
|
|
164
178
|
- - ">="
|
165
179
|
- !ruby/object:Gem::Version
|
166
180
|
version: '0'
|
181
|
+
- !ruby/object:Gem::Dependency
|
182
|
+
name: vcr
|
183
|
+
requirement: !ruby/object:Gem::Requirement
|
184
|
+
requirements:
|
185
|
+
- - ">="
|
186
|
+
- !ruby/object:Gem::Version
|
187
|
+
version: '0'
|
188
|
+
type: :development
|
189
|
+
prerelease: false
|
190
|
+
version_requirements: !ruby/object:Gem::Requirement
|
191
|
+
requirements:
|
192
|
+
- - ">="
|
193
|
+
- !ruby/object:Gem::Version
|
194
|
+
version: '0'
|
195
|
+
- !ruby/object:Gem::Dependency
|
196
|
+
name: webmock
|
197
|
+
requirement: !ruby/object:Gem::Requirement
|
198
|
+
requirements:
|
199
|
+
- - ">="
|
200
|
+
- !ruby/object:Gem::Version
|
201
|
+
version: '0'
|
202
|
+
type: :development
|
203
|
+
prerelease: false
|
204
|
+
version_requirements: !ruby/object:Gem::Requirement
|
205
|
+
requirements:
|
206
|
+
- - ">="
|
207
|
+
- !ruby/object:Gem::Version
|
208
|
+
version: '0'
|
167
209
|
description:
|
168
210
|
email:
|
169
211
|
- matt@swipely.com
|
@@ -192,6 +234,7 @@ files:
|
|
192
234
|
- lib/pipely/definition.rb
|
193
235
|
- lib/pipely/dependency.rb
|
194
236
|
- lib/pipely/deploy.rb
|
237
|
+
- lib/pipely/deploy/bootstrap.rb
|
195
238
|
- lib/pipely/deploy/client.rb
|
196
239
|
- lib/pipely/fog_client.rb
|
197
240
|
- lib/pipely/graph_builder.rb
|
@@ -205,8 +248,10 @@ files:
|
|
205
248
|
- lib/pipely/tasks/definition.rb
|
206
249
|
- lib/pipely/tasks/deploy.rb
|
207
250
|
- lib/pipely/tasks/graph.rb
|
251
|
+
- lib/pipely/tasks/upload_pipeline_as_gem.rb
|
208
252
|
- lib/pipely/tasks/upload_steps.rb
|
209
253
|
- lib/pipely/version.rb
|
254
|
+
- spec/fixtures/vcr_cassettes/build_and_upload_gems.yml
|
210
255
|
- spec/lib/pipely/build/daily_scheduler_spec.rb
|
211
256
|
- spec/lib/pipely/build/right_now_scheduler_spec.rb
|
212
257
|
- spec/lib/pipely/build/s3_path_builder_spec.rb
|
@@ -215,6 +260,7 @@ files:
|
|
215
260
|
- spec/lib/pipely/component_spec.rb
|
216
261
|
- spec/lib/pipely/definition_spec.rb
|
217
262
|
- spec/lib/pipely/dependency_spec.rb
|
263
|
+
- spec/lib/pipely/deploy/bootstrap_spec.rb
|
218
264
|
- spec/lib/pipely/deploy/client_spec.rb
|
219
265
|
- spec/lib/pipely/graph_builder_spec.rb
|
220
266
|
- spec/lib/pipely/reference_list_spec.rb
|
@@ -245,6 +291,7 @@ signing_key:
|
|
245
291
|
specification_version: 4
|
246
292
|
summary: Generate dependency graphs from pipeline definitions.
|
247
293
|
test_files:
|
294
|
+
- spec/fixtures/vcr_cassettes/build_and_upload_gems.yml
|
248
295
|
- spec/lib/pipely/build/daily_scheduler_spec.rb
|
249
296
|
- spec/lib/pipely/build/right_now_scheduler_spec.rb
|
250
297
|
- spec/lib/pipely/build/s3_path_builder_spec.rb
|
@@ -253,6 +300,7 @@ test_files:
|
|
253
300
|
- spec/lib/pipely/component_spec.rb
|
254
301
|
- spec/lib/pipely/definition_spec.rb
|
255
302
|
- spec/lib/pipely/dependency_spec.rb
|
303
|
+
- spec/lib/pipely/deploy/bootstrap_spec.rb
|
256
304
|
- spec/lib/pipely/deploy/client_spec.rb
|
257
305
|
- spec/lib/pipely/graph_builder_spec.rb
|
258
306
|
- spec/lib/pipely/reference_list_spec.rb
|