capsulecd 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.coveralls.yml +2 -0
- data/.dockerignore +5 -0
- data/.gitignore +95 -0
- data/.rspec +3 -0
- data/.simplecov +9 -0
- data/Dockerfile +16 -0
- data/Dockerfile.chef +26 -0
- data/Dockerfile.javascript +7 -0
- data/Dockerfile.node +7 -0
- data/Dockerfile.python +7 -0
- data/Dockerfile.ruby +4 -0
- data/FEATURES.md +12 -0
- data/Gemfile +26 -0
- data/LICENSE.md +22 -0
- data/README.md +227 -0
- data/Rakefile +43 -0
- data/bin/capsulecd +4 -0
- data/capsulecd.gemspec +27 -0
- data/circle.yml +24 -0
- data/lib/capsulecd/base/common/git_utils.rb +90 -0
- data/lib/capsulecd/base/common/validation_utils.rb +22 -0
- data/lib/capsulecd/base/configuration.rb +151 -0
- data/lib/capsulecd/base/engine.rb +163 -0
- data/lib/capsulecd/base/runner/circleci.rb +37 -0
- data/lib/capsulecd/base/runner/default.rb +38 -0
- data/lib/capsulecd/base/source/github.rb +183 -0
- data/lib/capsulecd/base/transform_engine.rb +62 -0
- data/lib/capsulecd/chef/chef_engine.rb +172 -0
- data/lib/capsulecd/chef/chef_helper.rb +29 -0
- data/lib/capsulecd/cli.rb +64 -0
- data/lib/capsulecd/error.rb +51 -0
- data/lib/capsulecd/javascript/javascript_engine.rb +213 -0
- data/lib/capsulecd/node/node_engine.rb +141 -0
- data/lib/capsulecd/python/python_engine.rb +157 -0
- data/lib/capsulecd/ruby/ruby_engine.rb +191 -0
- data/lib/capsulecd/ruby/ruby_helper.rb +60 -0
- data/lib/capsulecd/version.rb +3 -0
- data/lib/capsulecd.rb +16 -0
- data/logo.svg +1 -0
- data/spec/fixtures/chef/cookbook_analogj_test/CHANGELOG.md +3 -0
- data/spec/fixtures/chef/cookbook_analogj_test/Gemfile +18 -0
- data/spec/fixtures/chef/cookbook_analogj_test/LICENSE +21 -0
- data/spec/fixtures/chef/cookbook_analogj_test/README.md +13 -0
- data/spec/fixtures/chef/cookbook_analogj_test/Rakefile +1 -0
- data/spec/fixtures/chef/cookbook_analogj_test/Thorfile +12 -0
- data/spec/fixtures/chef/cookbook_analogj_test/chefignore +94 -0
- data/spec/fixtures/chef/cookbook_analogj_test/metadata.rb +5 -0
- data/spec/fixtures/chef/cookbook_analogj_test/recipes/default.rb +6 -0
- data/spec/fixtures/incorrect_configuration.yml +4 -0
- data/spec/fixtures/javascript/javascript_analogj_test/LICENSE +21 -0
- data/spec/fixtures/javascript/javascript_analogj_test/README.md +2 -0
- data/spec/fixtures/javascript/javascript_analogj_test/package.json +19 -0
- data/spec/fixtures/node/npm_analogj_test/LICENSE +21 -0
- data/spec/fixtures/node/npm_analogj_test/README.md +2 -0
- data/spec/fixtures/node/npm_analogj_test/package.json +19 -0
- data/spec/fixtures/python/pip_analogj_test/LICENSE +21 -0
- data/spec/fixtures/python/pip_analogj_test/MANIFEST.in +1 -0
- data/spec/fixtures/python/pip_analogj_test/README.md +1 -0
- data/spec/fixtures/python/pip_analogj_test/VERSION +1 -0
- data/spec/fixtures/python/pip_analogj_test/setup.cfg +5 -0
- data/spec/fixtures/python/pip_analogj_test/setup.py +80 -0
- data/spec/fixtures/python/pip_analogj_test/tox.ini +14 -0
- data/spec/fixtures/ruby/gem_analogj_test/Gemfile +4 -0
- data/spec/fixtures/ruby/gem_analogj_test/LICENSE.txt +21 -0
- data/spec/fixtures/ruby/gem_analogj_test/README.md +41 -0
- data/spec/fixtures/ruby/gem_analogj_test/Rakefile +6 -0
- data/spec/fixtures/ruby/gem_analogj_test/bin/console +14 -0
- data/spec/fixtures/ruby/gem_analogj_test/bin/setup +8 -0
- data/spec/fixtures/ruby/gem_analogj_test/gem_analogj_test.gemspec +25 -0
- data/spec/fixtures/ruby/gem_analogj_test/lib/gem_analogj_test/version.rb +3 -0
- data/spec/fixtures/ruby/gem_analogj_test/lib/gem_analogj_test.rb +5 -0
- data/spec/fixtures/ruby/gem_analogj_test/spec/gem_analogj_test_spec.rb +7 -0
- data/spec/fixtures/ruby/gem_analogj_test/spec/spec_helper.rb +2 -0
- data/spec/fixtures/ruby/gem_analogj_test-0.1.4.gem +0 -0
- data/spec/fixtures/sample_chef_configuration.yml +8 -0
- data/spec/fixtures/sample_configuration.yml +7 -0
- data/spec/fixtures/sample_global_configuration.yml +23 -0
- data/spec/fixtures/sample_node_configuration.yml +7 -0
- data/spec/fixtures/sample_python_configuration.yml +8 -0
- data/spec/fixtures/sample_repo_configuration.yml +22 -0
- data/spec/fixtures/sample_ruby_configuration.yml +5 -0
- data/spec/fixtures/vcr_cassettes/chef_build_step.yml +636 -0
- data/spec/fixtures/vcr_cassettes/gem_build_step.yml +653 -0
- data/spec/fixtures/vcr_cassettes/gem_build_step_without_version_rb.yml +653 -0
- data/spec/fixtures/vcr_cassettes/integration_chef.yml +1399 -0
- data/spec/fixtures/vcr_cassettes/integration_node.yml +1388 -0
- data/spec/fixtures/vcr_cassettes/integration_python.yml +1388 -0
- data/spec/fixtures/vcr_cassettes/integration_ruby.yml +1377 -0
- data/spec/fixtures/vcr_cassettes/node_build_step.yml +647 -0
- data/spec/fixtures/vcr_cassettes/pip_build_step.yml +653 -0
- data/spec/lib/capsulecd/base/configuration_spec.rb +75 -0
- data/spec/lib/capsulecd/base/engine_spec.rb +51 -0
- data/spec/lib/capsulecd/base/source/github_spec.rb +253 -0
- data/spec/lib/capsulecd/base/transform_engine_spec.rb +55 -0
- data/spec/lib/capsulecd/chef/chef_engine_spec.rb +114 -0
- data/spec/lib/capsulecd/cli_spec.rb +57 -0
- data/spec/lib/capsulecd/node/node_engine_spec.rb +113 -0
- data/spec/lib/capsulecd/python/python_engine_spec.rb +118 -0
- data/spec/lib/capsulecd/ruby/ruby_engine_spec.rb +128 -0
- data/spec/spec_helper.rb +105 -0
- data/spec/support/file_system.rb +21 -0
- data/spec/support/package_types.rb +11 -0
- metadata +281 -0
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe CapsuleCD::Configuration do
|
|
4
|
+
describe '::new' do
|
|
5
|
+
describe 'with a sample configuration file' do
|
|
6
|
+
let(:config_file_path) { 'spec/fixtures/sample_configuration.yml' }
|
|
7
|
+
subject { CapsuleCD::Configuration.new(config_file:config_file_path, source: :github, package_type: :node) }
|
|
8
|
+
|
|
9
|
+
it 'should populate github_access_token' do
|
|
10
|
+
expect(subject.source_github_access_token).to eql('sample_test_token')
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it 'should populate engine_npm_auth_token' do
|
|
14
|
+
expect(subject.npm_auth_token).to eql('sample_auth_token')
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it 'should use cli specified source' do
|
|
18
|
+
expect(subject.source).to eql(:github)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it 'should correctly base64 decode chef supermarket key' do
|
|
22
|
+
expect(subject.chef_supermarket_key).to eql("-----BEGIN RSA PRIVATE KEY-----\nsample_supermarket_key\n-----END RSA PRIVATE KEY-----\n")
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it 'should have correct defaults' do
|
|
26
|
+
expect(subject.engine_version_bump_type).to eql(:patch)
|
|
27
|
+
expect(subject.chef_supermarket_type).to eql('Other')
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
describe 'with an incorrect configuration file' do
|
|
32
|
+
let(:config_file_path) { 'spec/fixtures/incorrect_configuration.yml' }
|
|
33
|
+
subject { CapsuleCD::Configuration.new(config_file:config_file_path, source: :github, package_type: :node) }
|
|
34
|
+
|
|
35
|
+
it 'should populate github_access_token' do
|
|
36
|
+
expect(subject.source_github_access_token).to eql('sample_test_token')
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it 'should populate engine_npm_auth_token' do
|
|
40
|
+
expect(subject.npm_auth_token).to eql('sample_auth_token')
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it 'should use cli specified source' do
|
|
44
|
+
expect(subject.source).to eql(:github)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it 'should have a nil chef supermarket key' do
|
|
48
|
+
expect(subject.chef_supermarket_key).to eql(nil)
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
describe 'when overriding sample configuration file' do
|
|
53
|
+
let(:config_file_path) { 'spec/fixtures/sample_configuration.yml' }
|
|
54
|
+
|
|
55
|
+
describe 'with ENV variables' do
|
|
56
|
+
it 'should use CAPSULE_SOURCE_GITHUB_ACCESS_TOKEN instead of config file' do
|
|
57
|
+
allow(ENV).to receive(:each).and_yield('CAPSULE_SOURCE_GITHUB_ACCESS_TOKEN', 'override_test_token')
|
|
58
|
+
|
|
59
|
+
config = CapsuleCD::Configuration.new(config_file: config_file_path, source: :github, package_type: :node)
|
|
60
|
+
|
|
61
|
+
expect(config.source_github_access_token).to eql('override_test_token')
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
it 'should use CAPSULE_ENGINE_VERSION_BUMP_TYPE instead of default and return symbol' do
|
|
65
|
+
allow(ENV).to receive(:each).and_yield('CAPSULE_ENGINE_VERSION_BUMP_TYPE', 'patch')
|
|
66
|
+
|
|
67
|
+
config = CapsuleCD::Configuration.new(config_file: config_file_path, source: :github, package_type: :node)
|
|
68
|
+
|
|
69
|
+
expect(config.engine_version_bump_type).to eql(:patch)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
end
|
|
75
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe CapsuleCD::Engine do
|
|
4
|
+
|
|
5
|
+
describe '::new' do
|
|
6
|
+
describe 'without a source specified' do
|
|
7
|
+
it 'should throw an error' do
|
|
8
|
+
expect{CapsuleCD::Engine.new({})}.to raise_error(CapsuleCD::Error::SourceUnspecifiedError)
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
describe '::bump_version' do
|
|
14
|
+
subject{
|
|
15
|
+
CapsuleCD::Engine.new({:source => :github})
|
|
16
|
+
}
|
|
17
|
+
it 'should default to bumping patch segement' do
|
|
18
|
+
version = SemVer.parse('1.0.2')
|
|
19
|
+
new_version = subject.send(:bump_version, version)
|
|
20
|
+
expect(new_version.to_s).to eql('1.0.3')
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
describe 'when engine_version_bump_type is :minor' do
|
|
24
|
+
subject{
|
|
25
|
+
CapsuleCD::Engine.new({
|
|
26
|
+
:source => :github,
|
|
27
|
+
:engine_version_bump_type => :minor
|
|
28
|
+
})
|
|
29
|
+
}
|
|
30
|
+
it 'should correctly bump minor and clear patch segement' do
|
|
31
|
+
version = SemVer.parse('1.0.2')
|
|
32
|
+
new_version = subject.send(:bump_version, version)
|
|
33
|
+
expect(new_version.to_s).to eql('1.1.0')
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
describe 'when engine_version_bump_type is :major' do
|
|
38
|
+
subject{
|
|
39
|
+
CapsuleCD::Engine.new({
|
|
40
|
+
:source => :github,
|
|
41
|
+
:engine_version_bump_type => :major
|
|
42
|
+
})
|
|
43
|
+
}
|
|
44
|
+
it 'should correctly bump major and clear minor and patch segements' do
|
|
45
|
+
version = SemVer.parse('1.0.2')
|
|
46
|
+
new_version = subject.send(:bump_version, version)
|
|
47
|
+
expect(new_version.to_s).to eql('2.0.0')
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'capsulecd/base/source/github'
|
|
3
|
+
|
|
4
|
+
describe CapsuleCD::Source::Github do
|
|
5
|
+
describe '#source_configure' do
|
|
6
|
+
|
|
7
|
+
describe 'when no authentication token is present' do
|
|
8
|
+
let(:test_engine) { Class.new { include CapsuleCD::Source::Github } }
|
|
9
|
+
let(:config) { CapsuleCD::Configuration.new({}) }
|
|
10
|
+
it 'should raise an error' do
|
|
11
|
+
engine = test_engine.new
|
|
12
|
+
engine.instance_variable_set(:@config, config)
|
|
13
|
+
expect { engine.source_configure }.to raise_error(CapsuleCD::Error::SourceAuthenticationFailed)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
describe 'when authentication token is present' do
|
|
18
|
+
let(:test_engine) { Class.new { include CapsuleCD::Source::Github } }
|
|
19
|
+
let(:config) { CapsuleCD::Configuration.new({:config_file => 'spec/fixtures/sample_configuration.yml'}) }
|
|
20
|
+
|
|
21
|
+
it 'should successfully create an source_client' do
|
|
22
|
+
allow(Dir).to receive(:mktmpdir).and_return('/tmp')
|
|
23
|
+
engine = test_engine.new
|
|
24
|
+
engine.instance_variable_set(:@config, config)
|
|
25
|
+
engine.source_configure
|
|
26
|
+
expect(engine.source_client).to be_a_kind_of Octokit::Client
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
describe '#source_process_push_payload' do
|
|
32
|
+
let(:test_engine) { Class.new { include CapsuleCD::Source::Github } }
|
|
33
|
+
let(:payload) do
|
|
34
|
+
{
|
|
35
|
+
'head' => {
|
|
36
|
+
'sha' => '0a5948802a2bba02e019fd13bf3db3c5329faae6',
|
|
37
|
+
'ref' => 'master',
|
|
38
|
+
'repo' => {
|
|
39
|
+
'clone_url' => 'https://github.com/AnalogJ/npm_analogj_test.git',
|
|
40
|
+
'name' => 'npm_analog_test'
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
end
|
|
45
|
+
let(:config) { CapsuleCD::Configuration.new({:config_file => 'spec/fixtures/sample_configuration.yml'}) }
|
|
46
|
+
it 'should clone git repo' do
|
|
47
|
+
engine = test_engine.new
|
|
48
|
+
engine.instance_variable_set(:@config, config)
|
|
49
|
+
engine.instance_variable_set(:@source_git_parent_path, '/tmp')
|
|
50
|
+
allow(CapsuleCD::GitUtils).to receive(:clone).and_return(engine.source_git_parent_path + payload['head']['repo']['name'])
|
|
51
|
+
allow(CapsuleCD::GitUtils).to receive(:checkout).and_return(true)
|
|
52
|
+
|
|
53
|
+
engine.source_process_push_payload(payload)
|
|
54
|
+
|
|
55
|
+
expect(engine.source_git_local_path).to eql(engine.source_git_parent_path + payload['head']['repo']['name'])
|
|
56
|
+
expect(engine.source_git_local_branch).to eql(payload['head']['repo']['branch'])
|
|
57
|
+
expect(engine.source_git_head_info).to be_a(Hash)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
describe 'with an invalid payload' do
|
|
61
|
+
it 'should raise an error' do
|
|
62
|
+
engine = test_engine.new
|
|
63
|
+
engine.instance_variable_set(:@config, config)
|
|
64
|
+
engine.instance_variable_set(:@source_git_parent_path, '/tmp')
|
|
65
|
+
expect { engine.source_process_push_payload('head' => {}) }.to raise_error(CapsuleCD::Error::SourcePayloadFormatError)
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
describe '#source_process_pull_request_payload' do
|
|
71
|
+
let(:test_engine) { Class.new { include CapsuleCD::Source::Github } }
|
|
72
|
+
let(:source_client_double) { instance_double(Octokit::Client) }
|
|
73
|
+
let(:config) { CapsuleCD::Configuration.new({:config_file => 'spec/fixtures/sample_configuration.yml'}) }
|
|
74
|
+
|
|
75
|
+
describe 'with a closed pull request payload' do
|
|
76
|
+
let(:payload) do
|
|
77
|
+
{
|
|
78
|
+
'state' => 'closed'
|
|
79
|
+
}
|
|
80
|
+
end
|
|
81
|
+
it 'should raise an error' do
|
|
82
|
+
engine = test_engine.new
|
|
83
|
+
engine.instance_variable_set(:@config, config)
|
|
84
|
+
expect { engine.source_process_pull_request_payload(payload) }.to raise_error(CapsuleCD::Error::SourcePayloadUnsupported)
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
describe 'when the default branch is not the same as the pull request base branch' do
|
|
89
|
+
let(:config) { CapsuleCD::Configuration.new({:config_file => 'spec/fixtures/sample_configuration.yml'}) }
|
|
90
|
+
let(:payload) do
|
|
91
|
+
{
|
|
92
|
+
'state' => 'open',
|
|
93
|
+
'base' => {
|
|
94
|
+
'repo' => {
|
|
95
|
+
'default_branch' => 'master'
|
|
96
|
+
},
|
|
97
|
+
'ref' => 'development'
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
end
|
|
101
|
+
it 'should raise an error' do
|
|
102
|
+
engine = test_engine.new
|
|
103
|
+
engine.instance_variable_set(:@config, config)
|
|
104
|
+
expect { engine.source_process_pull_request_payload(payload) }.to raise_error(CapsuleCD::Error::SourcePayloadUnsupported)
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
describe 'when the user who opened the PR is not a collaborator' do
|
|
109
|
+
let(:payload) do
|
|
110
|
+
{
|
|
111
|
+
'state' => 'open',
|
|
112
|
+
'number' => 8,
|
|
113
|
+
'base' => {
|
|
114
|
+
'repo' => {
|
|
115
|
+
'full_name' => 'AnalogJ/npm_analogj_test',
|
|
116
|
+
'default_branch' => 'master',
|
|
117
|
+
'clone_url' => 'https://github.com/AnalogJ/npm_analogj_test.git',
|
|
118
|
+
'name' => 'npm_analog_test'
|
|
119
|
+
},
|
|
120
|
+
'sha' => '0a5948802a2bba02e019fd13bf3db3c5329faae6',
|
|
121
|
+
'ref' => 'master'
|
|
122
|
+
},
|
|
123
|
+
'user' => {
|
|
124
|
+
'login' => 'AnalogJ'
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
it 'should raise an error', :skip => true do
|
|
130
|
+
engine = test_engine.new
|
|
131
|
+
engine.instance_variable_set(:@source_client, source_client_double)
|
|
132
|
+
engine.instance_variable_set(:@source_git_parent_path, '/tmp')
|
|
133
|
+
|
|
134
|
+
allow(source_client_double).to receive(:collaborator?).and_return(false)
|
|
135
|
+
allow(source_client_double).to receive(:add_comment).and_return(false)
|
|
136
|
+
|
|
137
|
+
expect { engine.source_process_pull_request_payload(payload) }.to raise_error(CapsuleCD::Error::SourceUnauthorizedUser)
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
describe 'when using a valid payload' do
|
|
142
|
+
let(:payload) do
|
|
143
|
+
{
|
|
144
|
+
'state' => 'open',
|
|
145
|
+
'number' => 8,
|
|
146
|
+
'base' => {
|
|
147
|
+
'sha' => '0a5948802a2bba02e019fd13bf3db3c5329faae6',
|
|
148
|
+
'ref' => 'master',
|
|
149
|
+
'repo' => {
|
|
150
|
+
'full_name' => 'AnalogJ/npm_analogj_test',
|
|
151
|
+
'clone_url' => 'https://github.com/AnalogJ/npm_analogj_test.git',
|
|
152
|
+
'name' => 'npm_analog_test',
|
|
153
|
+
'default_branch' => 'master'
|
|
154
|
+
}
|
|
155
|
+
},
|
|
156
|
+
'head' => {
|
|
157
|
+
'sha' => '0a5948802a2bba02e019fd13bf3db3c5329faae6',
|
|
158
|
+
'ref' => 'feature',
|
|
159
|
+
'repo' => {
|
|
160
|
+
'full_name' => 'AnalogJ/npm_analogj_test',
|
|
161
|
+
'clone_url' => 'https://github.com/AnalogJ/npm_analogj_test.git',
|
|
162
|
+
'name' => 'npm_analog_test'
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
'user' => {
|
|
166
|
+
'login' => 'AnalogJ'
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
it 'should clone merged repo' do
|
|
172
|
+
engine = test_engine.new
|
|
173
|
+
engine.instance_variable_set(:@config, config)
|
|
174
|
+
engine.instance_variable_set(:@source_client, source_client_double)
|
|
175
|
+
engine.instance_variable_set(:@source_git_parent_path, '/tmp')
|
|
176
|
+
|
|
177
|
+
allow(source_client_double).to receive(:collaborator?).and_return(true)
|
|
178
|
+
allow(source_client_double).to receive(:add_comment).and_return(false)
|
|
179
|
+
allow(source_client_double).to receive(:create_status).and_return(false)
|
|
180
|
+
allow(CapsuleCD::GitUtils).to receive(:clone).and_return(engine.source_git_parent_path + payload['head']['repo']['name'])
|
|
181
|
+
allow(CapsuleCD::GitUtils).to receive(:fetch).and_return(true)
|
|
182
|
+
allow(CapsuleCD::GitUtils).to receive(:checkout).and_return(true)
|
|
183
|
+
|
|
184
|
+
engine.source_process_pull_request_payload(payload)
|
|
185
|
+
|
|
186
|
+
expect(engine.source_git_local_branch).to eql('pr_8')
|
|
187
|
+
expect(engine.source_git_local_path).to eql(engine.source_git_parent_path + payload['head']['repo']['name'])
|
|
188
|
+
expect(engine.source_git_head_info).to be_a(Hash)
|
|
189
|
+
expect(engine.source_git_base_info).to be_a(Hash)
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
describe '#source_release' do
|
|
195
|
+
let(:test_engine) { Class.new { include CapsuleCD::Source::Github } }
|
|
196
|
+
let(:source_client_double) { instance_double(Octokit::Client) }
|
|
197
|
+
let(:git_commit_double) { instance_double(Git::Object::Commit) }
|
|
198
|
+
|
|
199
|
+
describe 'when release state is valid' do
|
|
200
|
+
let(:payload) do
|
|
201
|
+
{
|
|
202
|
+
'state' => 'open',
|
|
203
|
+
'number' => 8,
|
|
204
|
+
'base' => {
|
|
205
|
+
'sha' => '0a5948802a2bba02e019fd13bf3db3c5329faae6',
|
|
206
|
+
'repo' => {
|
|
207
|
+
'full_name' => 'AnalogJ/npm_analogj_test',
|
|
208
|
+
'clone_url' => 'https://github.com/AnalogJ/npm_analogj_test.git',
|
|
209
|
+
'name' => 'npm_analog_test',
|
|
210
|
+
'default_branch' => 'master'
|
|
211
|
+
},
|
|
212
|
+
'ref' => 'master'
|
|
213
|
+
},
|
|
214
|
+
'head' => {
|
|
215
|
+
'sha' => '0a5948802a2bba02e019fd13bf3db3c5329faae6',
|
|
216
|
+
'repo' => {
|
|
217
|
+
'full_name' => 'AnalogJ/npm_analogj_test',
|
|
218
|
+
'clone_url' => 'https://github.com/AnalogJ/npm_analogj_test.git',
|
|
219
|
+
'name' => 'npm_analog_test'
|
|
220
|
+
},
|
|
221
|
+
'ref' => 'feature'
|
|
222
|
+
},
|
|
223
|
+
'user' => {
|
|
224
|
+
'login' => 'AnalogJ'
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
it 'should successfully push changes to github' do
|
|
230
|
+
engine = test_engine.new
|
|
231
|
+
engine.instance_variable_set(:@source_client, source_client_double)
|
|
232
|
+
engine.instance_variable_set(:@source_release_commit, git_commit_double)
|
|
233
|
+
engine.instance_variable_set(:@source_git_local_path, '')
|
|
234
|
+
engine.instance_variable_set(:@source_git_local_branch, '')
|
|
235
|
+
engine.instance_variable_set(:@source_git_base_info, payload['base'])
|
|
236
|
+
engine.instance_variable_set(:@source_git_head_info, payload['head'])
|
|
237
|
+
engine.instance_variable_set(:@source_release_artifacts, [])
|
|
238
|
+
engine.instance_variable_set(:@source_git_parent_path, test_directory)
|
|
239
|
+
|
|
240
|
+
allow(source_client_double).to receive(:create_release).and_return(true)
|
|
241
|
+
allow(source_client_double).to receive(:upload_asset).and_return(false)
|
|
242
|
+
allow(source_client_double).to receive(:create_status).and_return(false)
|
|
243
|
+
allow(git_commit_double).to receive(:sha).and_return('0a5948802a2bba02e019fd13bf3db3c5329faae6')
|
|
244
|
+
allow(git_commit_double).to receive(:name).and_return('test')
|
|
245
|
+
allow(CapsuleCD::GitUtils).to receive(:push).and_return(true)
|
|
246
|
+
allow(CapsuleCD::GitUtils).to receive(:generate_changelog).and_return('')
|
|
247
|
+
allow(FileUtils).to receive(:remove_entry_secure).and_return(true)
|
|
248
|
+
|
|
249
|
+
engine.source_release
|
|
250
|
+
end
|
|
251
|
+
end
|
|
252
|
+
end
|
|
253
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe CapsuleCD::TransformEngine do
|
|
4
|
+
before(:each) do
|
|
5
|
+
CapsuleCD.send(:remove_const, 'EngineExtension')
|
|
6
|
+
load 'lib/capsulecd/base/transform_engine.rb'
|
|
7
|
+
end
|
|
8
|
+
describe '::new' do
|
|
9
|
+
describe 'with a global configuration file' do
|
|
10
|
+
|
|
11
|
+
describe 'with an empty engine' do
|
|
12
|
+
before(:each) do
|
|
13
|
+
stub_const 'EmptyEngine', Class.new
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
let(:config_file_path) { 'spec/fixtures/sample_global_configuration.yml' }
|
|
17
|
+
subject { CapsuleCD::TransformEngine.new() }
|
|
18
|
+
|
|
19
|
+
it 'should raise an error if we specify that its a repo configuration' do
|
|
20
|
+
expect{
|
|
21
|
+
subject.transform(nil, config_file_path)
|
|
22
|
+
}.to raise_error(CapsuleCD::Error::EngineTransformUnavailableStep)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it 'should register the EngineExtension methods after transform' do
|
|
26
|
+
engine = EmptyEngine.new
|
|
27
|
+
expect(engine.methods - Object.methods).to be_empty
|
|
28
|
+
subject.transform(engine, config_file_path, :global)
|
|
29
|
+
expect((engine.methods - Object.methods).sort).to eql([:post_build_step, :post_source_configure, :pre_source_configure, :source_configure])
|
|
30
|
+
expect(engine.source_configure).to eql('override source_configure')
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
describe 'with an base engine' do
|
|
35
|
+
before(:each) do
|
|
36
|
+
stub_const 'BaseEngine', CapsuleCD::Engine
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
let(:config_file_path) { 'spec/fixtures/sample_global_configuration.yml' }
|
|
40
|
+
subject { CapsuleCD::TransformEngine.new() }
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
it 'should register the EngineExtension methods after transform, and override any existing methods' do
|
|
44
|
+
engine = BaseEngine.new(source: :github)
|
|
45
|
+
engine.instance_variable_set(:@source_git_local_path, test_directory)
|
|
46
|
+
subject.transform(engine, config_file_path, :global)
|
|
47
|
+
expect(engine.source_configure).to eql('override source_configure')
|
|
48
|
+
expect(engine.post_build_step).to eql('override post_build_step'+test_directory)
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe 'CapsuleCD::Chef::ChefEngine', :chef do
|
|
4
|
+
describe '#build_step' do
|
|
5
|
+
describe 'when building an empty package' do
|
|
6
|
+
let(:engine) do
|
|
7
|
+
require 'capsulecd/chef/chef_engine'
|
|
8
|
+
CapsuleCD::Chef::ChefEngine.new(source: :github,
|
|
9
|
+
package_type: :chef)
|
|
10
|
+
end
|
|
11
|
+
it 'should raise an error' do
|
|
12
|
+
engine.instance_variable_set(:@source_git_local_path, test_directory )
|
|
13
|
+
|
|
14
|
+
expect { engine.build_step }.to raise_error(CapsuleCD::Error::BuildPackageInvalid)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
describe 'when building a simple package ' do
|
|
19
|
+
let(:engine) do
|
|
20
|
+
require 'capsulecd/chef/chef_engine'
|
|
21
|
+
CapsuleCD::Chef::ChefEngine.new(source: :github,
|
|
22
|
+
package_type: :chef)
|
|
23
|
+
end
|
|
24
|
+
it 'should create a Rakefile, Berksfile, .gitignore file, file and tests folder' do
|
|
25
|
+
FileUtils.copy_entry('spec/fixtures/chef/cookbook_analogj_test', test_directory)
|
|
26
|
+
engine.instance_variable_set(:@source_git_local_path, test_directory )
|
|
27
|
+
|
|
28
|
+
VCR.use_cassette('chef_build_step',:tag => :chef) do
|
|
29
|
+
engine.build_step
|
|
30
|
+
end
|
|
31
|
+
File.exist?(test_directory+'/Rakefile')
|
|
32
|
+
File.exist?(test_directory+'/Berksfile')
|
|
33
|
+
File.exist?(test_directory+'/.gitignore')
|
|
34
|
+
File.exist?(test_directory+'/Gemfile')
|
|
35
|
+
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
describe '#test_step' do
|
|
41
|
+
let(:engine) do
|
|
42
|
+
require 'capsulecd/chef/chef_engine'
|
|
43
|
+
CapsuleCD::Chef::ChefEngine.new(source: :github,
|
|
44
|
+
package_type: :chef)
|
|
45
|
+
end
|
|
46
|
+
let(:config_double) { CapsuleCD::Configuration.new }
|
|
47
|
+
describe 'when testing chef package' do
|
|
48
|
+
it 'should run install dependencies' do
|
|
49
|
+
FileUtils.copy_entry('spec/fixtures/chef/cookbook_analogj_test', test_directory)
|
|
50
|
+
allow(Open3).to receive(:popen3).and_return(false)
|
|
51
|
+
allow(config_double).to receive(:engine_cmd_test).and_call_original
|
|
52
|
+
allow(config_double).to receive(:engine_disable_test).and_call_original
|
|
53
|
+
engine.instance_variable_set(:@source_git_local_path, test_directory)
|
|
54
|
+
engine.instance_variable_set(:@config, config_double)
|
|
55
|
+
|
|
56
|
+
engine.test_step
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
describe 'integration tests' do
|
|
62
|
+
let(:engine) do
|
|
63
|
+
require 'capsulecd/chef/chef_engine'
|
|
64
|
+
CapsuleCD::Chef::ChefEngine.new(source: :github,
|
|
65
|
+
runner: :default,
|
|
66
|
+
package_type: :chef,
|
|
67
|
+
config_file: 'spec/fixtures/sample_chef_configuration.yml'
|
|
68
|
+
# config_file: 'spec/fixtures/live_chef_configuration.yml'
|
|
69
|
+
)
|
|
70
|
+
end
|
|
71
|
+
let(:git_commit_double) { instance_double(Git::Object::Commit) }
|
|
72
|
+
describe 'when testing chef package' do
|
|
73
|
+
it 'should complete successfully' do
|
|
74
|
+
FileUtils.copy_entry('spec/fixtures/chef/cookbook_analogj_test', test_directory)
|
|
75
|
+
|
|
76
|
+
VCR.use_cassette('integration_chef',:tag => :chef) do
|
|
77
|
+
#set defaults for stubbed classes
|
|
78
|
+
source_git_local_path = test_directory
|
|
79
|
+
allow(File).to receive(:exist?).and_call_original
|
|
80
|
+
allow(File).to receive(:open).and_call_original
|
|
81
|
+
allow(Open3).to receive(:popen3).and_call_original
|
|
82
|
+
|
|
83
|
+
#stub methods in source_process_pull_request_payload
|
|
84
|
+
allow(CapsuleCD::GitUtils).to receive(:clone).and_return(source_git_local_path)
|
|
85
|
+
allow(CapsuleCD::GitUtils).to receive(:fetch).and_return(true)
|
|
86
|
+
allow(CapsuleCD::GitUtils).to receive(:checkout).and_return(true)
|
|
87
|
+
|
|
88
|
+
#stub methods in build_step
|
|
89
|
+
allow(CapsuleCD::GitUtils).to receive(:create_gitignore).with(source_git_local_path, ['ChefCookbook']).and_return(true)
|
|
90
|
+
|
|
91
|
+
#stub methods in package_step
|
|
92
|
+
allow(CapsuleCD::GitUtils).to receive(:commit).and_return(true)
|
|
93
|
+
allow(CapsuleCD::GitUtils).to receive(:tag).with(source_git_local_path,'v0.1.11').and_return(git_commit_double)
|
|
94
|
+
allow(git_commit_double).to receive(:sha).and_return('0a5948802a2bba02e019fd13bf3db3c5329faae6')
|
|
95
|
+
allow(git_commit_double).to receive(:name).and_return('0.1.11')
|
|
96
|
+
|
|
97
|
+
#stub methods in release_step
|
|
98
|
+
allow(Open3).to receive(:popen3).with("knife cookbook site share cookbook_analogj_test Other -c #{File.expand_path('~/knife.rb')}").and_return(true)
|
|
99
|
+
allow(File).to receive(:open).with(File.expand_path('~/knife.rb'), 'w+').and_return(true)
|
|
100
|
+
allow(File).to receive(:open).with(File.expand_path('~/client.pem'), 'w+').and_return(true)
|
|
101
|
+
|
|
102
|
+
#stub methods in source_release
|
|
103
|
+
allow(CapsuleCD::GitUtils).to receive(:push).and_return(true)
|
|
104
|
+
allow(CapsuleCD::GitUtils).to receive(:generate_changelog).and_return('')
|
|
105
|
+
|
|
106
|
+
engine.start
|
|
107
|
+
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'rspec/support/spec/in_sub_process'
|
|
3
|
+
require 'capsulecd/cli'
|
|
4
|
+
require 'capsulecd/base/engine'
|
|
5
|
+
|
|
6
|
+
describe CapsuleCD::Cli do
|
|
7
|
+
describe '#start' do
|
|
8
|
+
describe 'with default_engine' do
|
|
9
|
+
let(:engine_double) { instance_double(CapsuleCD::Engine, start: true) }
|
|
10
|
+
it 'should call the default start command with the proper options' do
|
|
11
|
+
expect(CapsuleCD::Engine).to receive(:new).with(
|
|
12
|
+
runner: :default, source: :default, package_type: :default, dry_run: false).and_return engine_double
|
|
13
|
+
|
|
14
|
+
CapsuleCD::Cli.start %w(start)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
describe 'with node_engine', :node do
|
|
19
|
+
require 'capsulecd/node/node_engine'
|
|
20
|
+
let(:engine_double) { instance_double(CapsuleCD::Node::NodeEngine, start: true) }
|
|
21
|
+
it 'should call the node start command with the proper options' do
|
|
22
|
+
expect(CapsuleCD::Node::NodeEngine).to receive(:new).with(
|
|
23
|
+
runner: :default, source: :default, package_type: :node, dry_run: false).and_return engine_double
|
|
24
|
+
|
|
25
|
+
CapsuleCD::Cli.start %w(start --package_type node)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
describe 'with chef_engine', :chef do
|
|
30
|
+
let(:engine_double) do
|
|
31
|
+
require 'capsulecd/chef/chef_engine'
|
|
32
|
+
instance_double(CapsuleCD::Chef::ChefEngine, start: true)
|
|
33
|
+
end
|
|
34
|
+
it 'should call the chef start command with the proper options' do
|
|
35
|
+
require 'capsulecd/chef/chef_engine'
|
|
36
|
+
expect(CapsuleCD::Chef::ChefEngine).to receive(:new).with(
|
|
37
|
+
runner: :default, source: :default, package_type: :chef, dry_run: false).and_return engine_double
|
|
38
|
+
|
|
39
|
+
CapsuleCD::Cli.start %w(start --package_type chef)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
describe 'with python_engine', :python do
|
|
44
|
+
let(:engine_double) do
|
|
45
|
+
require 'capsulecd/python/python_engine'
|
|
46
|
+
instance_double(CapsuleCD::Python::PythonEngine, start: true)
|
|
47
|
+
end
|
|
48
|
+
it 'should call the python start command with the proper options' do
|
|
49
|
+
require 'capsulecd/python/python_engine'
|
|
50
|
+
expect(CapsuleCD::Python::PythonEngine).to receive(:new).with(
|
|
51
|
+
runner: :default, source: :default, package_type: :python, dry_run: false).and_return engine_double
|
|
52
|
+
|
|
53
|
+
CapsuleCD::Cli.start %w(start --package_type python)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|