pact_broker-client 1.35.0 → 1.36.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -19,29 +19,49 @@ module PactBroker
19
19
  class PublicationTask < ::Rake::TaskLib
20
20
 
21
21
  attr_accessor :pattern, :pact_broker_base_url, :consumer_version, :tag, :write_method, :tag_with_git_branch, :pact_broker_basic_auth, :pact_broker_token
22
+ attr_reader :auto_detect_version_properties, :branch, :build_url
22
23
  alias_method :tags=, :tag=
23
24
  alias_method :tags, :tag
24
25
 
25
26
  def initialize name = nil, &block
26
27
  @name = name
28
+ @auto_detect_version_properties = nil
29
+ @version_required = false
27
30
  @pattern = 'spec/pacts/*.json'
28
31
  @pact_broker_base_url = 'http://pact-broker'
29
32
  rake_task &block
30
33
  end
31
34
 
35
+ def auto_detect_version_properties= auto_detect_version_properties
36
+ @version_required = version_required || auto_detect_version_properties
37
+ @auto_detect_version_properties = auto_detect_version_properties
38
+ end
39
+
40
+ def branch= branch
41
+ @version_required = version_required || !!branch
42
+ @branch = branch
43
+ end
44
+
45
+ def build_url= build_url
46
+ @version_required = version_required || !!build_url
47
+ @build_url = build_url
48
+ end
49
+
32
50
  private
33
51
 
52
+ attr_reader :version_required
53
+
34
54
  def rake_task &block
35
55
  namespace :pact do
36
56
  desc "Publish pacts to pact broker"
37
57
  task task_name do
38
58
  block.call(self)
39
59
  require 'pact_broker/client/publish_pacts'
40
- pact_broker_client_options = {}
41
- .merge( pact_broker_basic_auth ? { basic_auth: pact_broker_basic_auth } : {} )
42
- .merge( write_method ? { write: write_method } : {} )
43
- .merge( pact_broker_token ? { token: pact_broker_token } : {} )
44
- success = PactBroker::Client::PublishPacts.new(pact_broker_base_url, FileList[pattern], consumer_version, all_tags, pact_broker_client_options).call
60
+ pact_broker_client_options = { write: write_method, token: pact_broker_token }
61
+ pact_broker_client_options[:basic_auth] = pact_broker_basic_auth if pact_broker_basic_auth && pact_broker_basic_auth.any?
62
+ pact_broker_client_options.compact!
63
+ consumer_version_params = { number: consumer_version, branch: the_branch, build_url: build_url, tags: all_tags, version_required: version_required }.compact
64
+ success = PactBroker::Client::PublishPacts.new(pact_broker_base_url, FileList[pattern], consumer_version_params, pact_broker_client_options).call
45
65
  raise "One or more pacts failed to be published" unless success
46
66
  end
47
67
  end
@@ -53,9 +73,18 @@ module PactBroker
53
73
 
54
74
  def all_tags
55
75
  t = [*tags]
56
- t << PactBroker::Client::Git.branch if tag_with_git_branch
76
+ t << PactBroker::Client::Git.branch(raise_error: true) if tag_with_git_branch
57
77
  t.compact.uniq
58
78
  end
79
+
80
+ def the_branch
81
+ if branch.nil? && auto_detect_version_properties != false
82
+ PactBroker::Client::Git.branch(raise_error: auto_detect_version_properties == true)
83
+ else
84
+ branch
85
+ end
86
+ end
87
+
59
88
  end
60
89
  end
61
90
  end
@@ -1,5 +1,5 @@
1
1
  module PactBroker
2
2
  module Client
3
- VERSION = '1.35.0'
3
+ VERSION = '1.36.0'
4
4
  end
5
5
  end
@@ -1 +1,7 @@
1
- bundle exec bin/pact-broker publish spec/pacts/pact_broker_client-pact_broker.json --consumer-app-version 1.2.3 --broker-base-url http://localhost:9292 --tag-with-git-branch --broker-username localhost --broker-password localhost
1
+ bundle exec bin/pact-broker publish spec/pacts/pact_broker_client-pact_broker.json \
2
+ --consumer-app-version 1.2.7 \
3
+ --broker-base-url http://localhost:9292 \
4
+ --broker-username localhost --broker-password localhost \
5
+ --auto-detect-branch \
6
+ --build-url http://mybuild
7
+
@@ -35,7 +35,7 @@ module PactBroker
35
35
  end
36
36
 
37
37
  it "invokes the CanIDeploy service" do
38
- expect(CanIDeploy).to receive(:call).with('http://pact-broker', version_selectors, {to_tag: nil, limit: 1000}, {output: 'table', retry_while_unknown: 1, retry_interval: 2}, {verbose: 'verbose'})
38
+ expect(CanIDeploy).to receive(:call).with('http://pact-broker', version_selectors, {to_tag: nil, to_environment: nil, limit: 1000}, {output: 'table', retry_while_unknown: 1, retry_interval: 2}, {verbose: 'verbose'})
39
39
  invoke_can_i_deploy
40
40
  end
41
41
 
@@ -53,7 +53,18 @@ module PactBroker
53
53
  end
54
54
 
55
55
  it "passes the value as the matrix options" do
56
- expect(CanIDeploy).to receive(:call).with(anything, anything, {to_tag: 'prod', limit: 1000}, anything, anything)
56
+ expect(CanIDeploy).to receive(:call).with(anything, anything, {to_tag: 'prod', to_environment: nil, limit: 1000}, anything, anything)
57
+ invoke_can_i_deploy
58
+ end
59
+ end
60
+
61
+ context "with --to-environment" do
62
+ before do
63
+ subject.options.to_environment = 'prod'
64
+ end
65
+
66
+ it "passes the value as the matrix options" do
67
+ expect(CanIDeploy).to receive(:call).with(anything, anything, {to_tag: nil, to_environment: 'prod', limit: 1000}, anything, anything)
57
68
  invoke_can_i_deploy
58
69
  end
59
70
  end
@@ -27,9 +27,8 @@ module PactBroker::Client::CLI
27
27
  expect(PactBroker::Client::PublishPacts).to receive(:call).with(
28
28
  "http://pact-broker",
29
29
  ["spec/support/cli_test_pacts/foo.json"],
30
- "1.2.3",
31
- [],
32
- {verbose: nil}
30
+ { number: "1.2.3", tags: [], version_required: false },
31
+ { verbose: nil }
33
32
  )
34
33
  invoke_broker
35
34
  end
@@ -43,7 +42,6 @@ module PactBroker::Client::CLI
43
42
  anything,
44
43
  ["spec/support/cli_test_pacts/bar.json", "spec/support/cli_test_pacts/foo.json"],
45
44
  anything,
46
- anything,
47
45
  anything
48
46
  )
49
47
  invoke_broker
@@ -58,7 +56,6 @@ module PactBroker::Client::CLI
58
56
  anything,
59
57
  ["spec/support/cli_test_pacts/bar.json", "spec/support/cli_test_pacts/foo.json"],
60
58
  anything,
61
- anything,
62
59
  anything
63
60
  )
64
61
  invoke_broker
@@ -73,7 +70,6 @@ module PactBroker::Client::CLI
73
70
  anything,
74
71
  ["spec/support/cli_test_pacts/bar.json", "spec/support/cli_test_pacts/foo.json"],
75
72
  anything,
76
- anything,
77
73
  anything
78
74
  )
79
75
  invoke_broker
@@ -89,8 +85,7 @@ module PactBroker::Client::CLI
89
85
  expect(PactBroker::Client::PublishPacts).to receive(:call).with(
90
86
  anything,
91
87
  anything,
92
- anything,
93
- ['foo'],
88
+ hash_including(tags: ['foo']),
94
89
  anything
95
90
  )
96
91
  invoke_broker
@@ -100,7 +95,7 @@ module PactBroker::Client::CLI
100
95
  context "with tag-with-git-branch" do
101
96
  before do
102
97
  subject.options = OpenStruct.new(
103
- minimum_valid_options.merge(tag_with_git_branch: true)
98
+ minimum_valid_options.merge(tag_with_git_branch: true, tag: ['foo'])
104
99
  )
105
100
  end
106
101
 
@@ -112,9 +107,111 @@ module PactBroker::Client::CLI
112
107
  it "adds it to the list of tags when publishing" do
113
108
  expect(PactBroker::Client::PublishPacts).to receive(:call).with(
114
109
  anything,
110
+ anything,
111
+ hash_including(tags: ['foo', 'bar']),
112
+ anything
113
+ )
114
+ invoke_broker
115
+ end
116
+ end
117
+
118
+ context "with a branch specified" do
119
+ before do
120
+ subject.options = OpenStruct.new(
121
+ minimum_valid_options.merge(branch: "main")
122
+ )
123
+ end
124
+
125
+ it "passes in the branch option" do
126
+ expect(PactBroker::Client::PublishPacts).to receive(:call).with(
127
+ anything,
128
+ anything,
129
+ hash_including(branch: "main", version_required: true),
130
+ anything
131
+ )
132
+ invoke_broker
133
+ end
134
+ end
135
+
136
+ context "with --auto-detect-version-properties on by default" do
137
+ before do
138
+ subject.options = OpenStruct.new(
139
+ minimum_valid_options.merge(auto_detect_version_properties: true)
140
+ )
141
+ allow(subject).to receive(:explict_auto_detect_version_properties).and_return(false)
142
+ end
143
+
144
+ it "determines the git branch name" do
145
+ expect(PactBroker::Client::Git).to receive(:branch).with(raise_error: false)
146
+ invoke_broker
147
+ end
148
+
149
+ it "passes in the auto detected branch option with version_required: false" do
150
+ expect(PactBroker::Client::PublishPacts).to receive(:call).with(
151
+ anything,
152
+ anything,
153
+ hash_including(branch: "bar", version_required: false),
154
+ anything
155
+ )
156
+ invoke_broker
157
+ end
158
+ end
159
+
160
+
161
+ context "with --auto-detect-version-properties specified explicitly" do
162
+ before do
163
+ subject.options = OpenStruct.new(
164
+ minimum_valid_options.merge(auto_detect_version_properties: true)
165
+ )
166
+ allow(subject).to receive(:explict_auto_detect_version_properties).and_return(true)
167
+ end
168
+
169
+ it "determines the git branch name" do
170
+ expect(PactBroker::Client::Git).to receive(:branch).with(raise_error: true)
171
+ invoke_broker
172
+ end
173
+
174
+ it "passes in the auto detected branch option with version_required: true" do
175
+ expect(PactBroker::Client::PublishPacts).to receive(:call).with(
115
176
  anything,
116
177
  anything,
117
- ['bar'],
178
+ hash_including(branch: "bar", version_required: true),
179
+ anything
180
+ )
181
+ invoke_broker
182
+ end
183
+
184
+ context "with the branch specified as well" do
185
+ before do
186
+ subject.options = OpenStruct.new(
187
+ minimum_valid_options.merge(branch: "specified-branch", auto_detect_version_properties: true)
188
+ )
189
+ end
190
+
191
+ it "uses the specified branch" do
192
+ expect(PactBroker::Client::PublishPacts).to receive(:call).with(
193
+ anything,
194
+ anything,
195
+ hash_including(branch: "specified-branch", version_required: true),
196
+ anything
197
+ )
198
+ invoke_broker
199
+ end
200
+ end
201
+ end
202
+
203
+ context "with the build_url specified" do
204
+ before do
205
+ subject.options = OpenStruct.new(
206
+ minimum_valid_options.merge(build_url: "http://ci")
207
+ )
208
+ end
209
+
210
+ it "passes in the branch option" do
211
+ expect(PactBroker::Client::PublishPacts).to receive(:call).with(
212
+ anything,
213
+ anything,
214
+ hash_including(build_url: "http://ci"),
118
215
  anything
119
216
  )
120
217
  invoke_broker
@@ -133,8 +230,7 @@ module PactBroker::Client::CLI
133
230
  anything,
134
231
  anything,
135
232
  anything,
136
- anything,
137
- hash_including({basic_auth: {username: 'foo', password: 'bar'}})
233
+ hash_including(basic_auth: { username: 'foo', password: 'bar' })
138
234
  )
139
235
  invoke_broker
140
236
  end
@@ -9,9 +9,20 @@ module PactBroker
9
9
  Git::BRANCH_ENV_VAR_NAMES.each do | env_var_name|
10
10
  allow(ENV).to receive(:[]).with(env_var_name).and_return(nil)
11
11
  end
12
+ allow(Git).to receive(:execute_git_command).and_return(" origin/HEAD \n origin/foo")
12
13
  end
13
14
 
14
- subject { Git.branch }
15
+ let(:raise_exception) { true }
16
+
17
+ subject { Git.branch(raise_error: raise_exception) }
18
+
19
+ shared_examples_for "when raise_error is false" do
20
+ context "when raise_error is false" do
21
+ let(:raise_exception) { false }
22
+
23
+ it { is_expected.to be nil }
24
+ end
25
+ end
15
26
 
16
27
  context "when there is a known environment variable for the branch" do
17
28
  before do
@@ -24,8 +35,28 @@ module PactBroker
24
35
  end
25
36
  end
26
37
 
38
+ context "when there is one environment variable ending with _BRANCH" do
39
+ before do
40
+ allow(ENV).to receive(:keys).and_return(%w{FOO_BRANCH BAR_BRANCH BLAH})
41
+ allow(ENV).to receive(:[]).with("FOO_BRANCH").and_return("")
42
+ allow(ENV).to receive(:[]).with("BAR_BRANCH").and_return("meep")
43
+ end
44
+
45
+ it "returns the value of that environment variable" do
46
+ expect(subject).to eq "meep"
47
+ end
48
+ end
49
+
50
+ context "when there is more than one environment variable ending with _BRANCH" do
51
+ it "attempts to execute a git command to determine the value" do
52
+ expect(Git).to receive(:execute_git_command)
53
+ expect(subject).to_not be_empty
54
+ end
55
+ end
56
+
27
57
  context "when there is no known environment variable for the branch", skip_ci: true do
28
58
  it "attempts to execute a git command to determine the value" do
59
+ expect(Git).to receive(:execute_git_command)
29
60
  expect(subject).to_not be_empty
30
61
  end
31
62
  end
@@ -35,7 +66,7 @@ module PactBroker
35
66
  allow(Git).to receive(:execute_git_command).and_return(" origin/HEAD \n origin/foo")
36
67
  end
37
68
 
38
- it "raises an error" do
69
+ it "returns the branch" do
39
70
  expect(subject).to eq "foo"
40
71
  end
41
72
  end
@@ -48,6 +79,8 @@ module PactBroker
48
79
  it "raises an error" do
49
80
  expect { subject }.to raise_error PactBroker::Client::Error, /returned multiple branches: foo, bar/
50
81
  end
82
+
83
+ include_examples "when raise_error is false"
51
84
  end
52
85
 
53
86
 
@@ -59,6 +92,8 @@ module PactBroker
59
92
  it "raises an error" do
60
93
  expect { subject }.to raise_error PactBroker::Client::Error, /didn't return anything/
61
94
  end
95
+
96
+ include_examples "when raise_error is false"
62
97
  end
63
98
 
64
99
  context "when there is an error executing the git command" do
@@ -69,6 +104,8 @@ module PactBroker
69
104
  it "raises an error" do
70
105
  expect { subject }.to raise_error PactBroker::Client::Error, /some error/
71
106
  end
107
+
108
+ include_examples "when raise_error is false"
72
109
  end
73
110
  end
74
111
  end
@@ -23,6 +23,7 @@ module PactBroker
23
23
  File.open("spec/pacts/consumer-provider.json", "w") { |file| file << pact_hash.to_json }
24
24
  File.open("spec/pacts/consumer-provider-2.json", "w") { |file| file << pact_hash.to_json }
25
25
  File.open("spec/pacts/foo-bar.json", "w") { |file| file << pact_hash_2.to_json }
26
+ allow_any_instance_of(PublishPacts).to receive(:create_index_entry_point).and_return(index_entry_point)
26
27
  end
27
28
 
28
29
  after do
@@ -34,11 +35,23 @@ module PactBroker
34
35
  let(:pact_file_paths) { ['spec/pacts/consumer-provider.json']}
35
36
  let(:consumer_version) { "1.2.3" }
36
37
  let(:tags) { nil }
37
- let(:pact_hash) { {consumer: {name: 'Consumer'}, provider: {name: 'Provider'}, interactions: [] } }
38
- let(:pact_hash_2) { {consumer: {name: 'Foo'}, provider: {name: 'Bar'}, interactions: [] } }
38
+ let(:branch) { nil }
39
+ let(:build_url) { nil }
40
+ let(:version_required) { false }
41
+ let(:pact_hash) { { consumer: { name: 'Consumer'}, provider: { name: 'Provider' }, interactions: [] } }
42
+ let(:pact_hash_2) { {consumer: { name: 'Foo' }, provider: { name: 'Bar' }, interactions: [] } }
39
43
  let(:pacts_client) { instance_double("PactBroker::ClientSupport::Pacts")}
40
44
  let(:pact_versions_client) { instance_double("PactBroker::Client::Versions", tag: false) }
41
45
  let(:pact_broker_base_url) { 'http://some-host'}
46
+ let(:consumer_version_params) do
47
+ {
48
+ number: consumer_version,
49
+ branch: branch,
50
+ tags: tags,
51
+ build_url: build_url,
52
+ version_required: version_required
53
+ }
54
+ end
42
55
  let(:pact_broker_client_options) do
43
56
  {
44
57
  basic_auth: {
@@ -47,8 +60,11 @@ module PactBroker
47
60
  }
48
61
  }
49
62
  end
63
+ let(:index_entry_point) { instance_double("PactBroker::Client::Hal::EntryPoint", :get! => index_resource )}
64
+ let(:index_resource) { instance_double("PactBroker::Client::Hal::Entity", can?: can_create_version ) }
65
+ let(:can_create_version) { false }
50
66
 
51
- subject { PublishPacts.new(pact_broker_base_url, pact_file_paths, consumer_version, tags, pact_broker_client_options) }
67
+ subject { PublishPacts.new(pact_broker_base_url, pact_file_paths, consumer_version_params, pact_broker_client_options) }
52
68
 
53
69
  describe "call" do
54
70
  it "creates a PactBroker Client" do
@@ -184,7 +200,6 @@ module PactBroker
184
200
  end
185
201
 
186
202
  context "when an error occurs tagging the pact" do
187
-
188
203
  before do
189
204
  allow(pact_versions_client).to receive(:tag).and_raise("an error")
190
205
  allow(Retry).to receive(:sleep)
@@ -203,7 +218,6 @@ module PactBroker
203
218
  end
204
219
 
205
220
  context "when an error occurs every time while publishing a pact" do
206
-
207
221
  before do
208
222
  allow(Retry).to receive(:sleep)
209
223
  allow(pacts_client).to receive(:publish).and_raise("an error")
@@ -221,7 +235,6 @@ module PactBroker
221
235
  end
222
236
 
223
237
  context "when an error occurs less than the maximum number of retries" do
224
-
225
238
  before do
226
239
  allow(Retry).to receive(:sleep)
227
240
  tries = 0
@@ -245,6 +258,86 @@ module PactBroker
245
258
  expect(subject.call).to eq true
246
259
  end
247
260
  end
261
+
262
+ context "when the broker does not support creation of a version with a branch but a branch is specified" do
263
+ let(:branch) { "main" }
264
+
265
+ context "when version_required is true" do
266
+ let(:version_required) { true }
267
+
268
+ it "raises an error" do
269
+ expect { subject.call }.to raise_error PactBroker::Client::Error
270
+ end
271
+ end
272
+ end
273
+
274
+ context "when the broker supports creation of a version with a branch" do
275
+ before do
276
+ allow(version_link).to receive(:expand).and_return(version_link)
277
+ allow(version_resource).to receive(:assert_success!).and_return(version_resource)
278
+ allow(version_resource).to receive_message_chain(:response, :status).and_return(version_creation_response_status)
279
+ end
280
+ let(:can_create_version) { true }
281
+ let(:version_link) { instance_double("PactBroker::Client::Hal::Link", put: version_resource) }
282
+ let(:version_resource) { instance_double("PactBroker::Client::Hal::Entity") }
283
+ let(:version_creation_response_status) { 201 }
284
+
285
+ before do
286
+ allow(index_resource).to receive(:_link).and_return(version_link)
287
+ end
288
+
289
+ context "when there is a branch, build_url or tags specified" do
290
+ let(:tags) { ["dev"] }
291
+ let(:branch) { ["main"] }
292
+ let(:build_url) { "build_url" }
293
+
294
+ it "creates a version with the branch, build_url and tags" do
295
+ expect(index_resource).to receive(:_link)
296
+ expect(version_link).to receive(:expand).with(pacticipant: "Consumer", version: "1.2.3")
297
+ expect(version_link).to receive(:put).with(branch: branch, buildUrl: build_url)
298
+ subject.call
299
+ end
300
+
301
+ context "when there is a branch but no tags" do
302
+ let(:tags) { [] }
303
+
304
+ it "does not set the tags, as this would overwrite the existing ones - not sure about this implementation" do
305
+ expect(version_link).to receive(:put).with(branch: branch, buildUrl: build_url)
306
+ subject.call
307
+ end
308
+ end
309
+
310
+ context "when the version response status is 201" do
311
+ it "puts a message indicating the version was created" do
312
+ expect($stdout).to receive(:puts).with(/Created/)
313
+ subject.call
314
+ end
315
+ end
316
+
317
+ context "when the version response status is 200" do
318
+ let(:version_creation_response_status) { 200 }
319
+
320
+ it "puts a message indicating the version was replaced" do
321
+ expect($stdout).to receive(:puts).with(/Replaced/)
322
+ subject.call
323
+ end
324
+ end
325
+ end
326
+
327
+ context "when there is no branch, tags or build_url specified" do
328
+ before do
329
+ allow(Retry).to receive(:while_error) { |&block| block.call }
330
+ end
331
+ let(:tags) { [] }
332
+ let(:branch) { nil }
333
+ let(:build_url) { nil }
334
+
335
+ it "does not create a version resource" do
336
+ expect(index_resource).to_not receive(:_link)
337
+ subject.call
338
+ end
339
+ end
340
+ end
248
341
  end
249
342
  end
250
343
  end