pact_broker-client 1.35.0 → 1.36.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.
@@ -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