pact_broker-client 1.32.0 → 1.37.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.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/release_gem.yml +1 -0
  3. data/.github/workflows/test.yml +23 -0
  4. data/CHANGELOG.md +48 -0
  5. data/README.md +15 -3
  6. data/Rakefile +2 -0
  7. data/doc/pacts/markdown/Pact Broker Client - Pact Broker.md +331 -8
  8. data/lib/pact_broker/client.rb +1 -1
  9. data/lib/pact_broker/client/backports.rb +13 -0
  10. data/lib/pact_broker/client/cli/broker.rb +73 -28
  11. data/lib/pact_broker/client/cli/can_i_deploy_long_desc.txt +18 -9
  12. data/lib/pact_broker/client/cli/custom_thor.rb +9 -12
  13. data/lib/pact_broker/client/git.rb +43 -22
  14. data/lib/pact_broker/client/hal/entity.rb +27 -3
  15. data/lib/pact_broker/client/hal/http_client.rb +4 -0
  16. data/lib/pact_broker/client/hal/links.rb +39 -0
  17. data/lib/pact_broker/client/hal_client_methods.rb +11 -0
  18. data/lib/pact_broker/client/hash_refinements.rb +19 -0
  19. data/lib/pact_broker/client/matrix.rb +2 -1
  20. data/lib/pact_broker/client/matrix/text_formatter.rb +46 -11
  21. data/lib/pact_broker/client/publish_pacts.rb +93 -14
  22. data/lib/pact_broker/client/tasks/publication_task.rb +37 -6
  23. data/lib/pact_broker/client/version.rb +1 -1
  24. data/lib/pact_broker/client/versions/record_deployment.rb +109 -0
  25. data/pact-broker-client.gemspec +2 -0
  26. data/script/publish-pact.sh +7 -1
  27. data/script/trigger-release.sh +1 -1
  28. data/spec/lib/pact_broker/client/cli/broker_can_i_deploy_spec.rb +13 -2
  29. data/spec/lib/pact_broker/client/cli/broker_publish_spec.rb +108 -12
  30. data/spec/lib/pact_broker/client/git_spec.rb +39 -2
  31. data/spec/lib/pact_broker/client/hal/entity_spec.rb +4 -3
  32. data/spec/lib/pact_broker/client/matrix/text_formatter_spec.rb +29 -4
  33. data/spec/lib/pact_broker/client/publish_pacts_spec.rb +119 -7
  34. data/spec/lib/pact_broker/client/tasks/publication_task_spec.rb +88 -10
  35. data/spec/lib/pact_broker/client/versions/describe_spec.rb +0 -1
  36. data/spec/lib/pact_broker/client/versions/record_deployment_spec.rb +82 -0
  37. data/spec/pacts/pact_broker_client-pact_broker.json +335 -8
  38. data/spec/service_providers/pact_broker_client_create_version_spec.rb +89 -0
  39. data/spec/service_providers/pact_broker_client_matrix_spec.rb +4 -0
  40. data/spec/service_providers/pact_broker_client_versions_spec.rb +1 -2
  41. data/spec/service_providers/record_deployment_spec.rb +219 -0
  42. data/spec/support/matrix.json +6 -1
  43. data/spec/support/matrix.txt +3 -3
  44. data/spec/support/matrix_error.txt +3 -3
  45. data/spec/support/matrix_with_results.txt +10 -0
  46. data/tasks/pact.rake +2 -0
  47. metadata +44 -4
  48. data/.travis.yml +0 -11
@@ -1,5 +1,5 @@
1
1
  module PactBroker
2
2
  module Client
3
- VERSION = '1.32.0'
3
+ VERSION = '1.37.0'
4
4
  end
5
5
  end
@@ -0,0 +1,109 @@
1
+ require 'pact_broker/client/hal_client_methods'
2
+ require 'pact_broker/client/error'
3
+ require 'pact_broker/client/command_result'
4
+
5
+ module PactBroker
6
+ module Client
7
+ class Versions
8
+ class RecordDeployment
9
+ include PactBroker::Client::HalClientMethods
10
+
11
+ NOT_SUPPORTED_MESSAGE = "This version of the Pact Broker does not support recording deployments. Please upgrade to version 2.80.0 or later."
12
+
13
+ def self.call(params, pact_broker_base_url, pact_broker_client_options)
14
+ new(params, pact_broker_base_url, pact_broker_client_options).call
15
+ end
16
+
17
+ def initialize(params, pact_broker_base_url, pact_broker_client_options)
18
+ @pact_broker_base_url = pact_broker_base_url
19
+ @pacticipant_name = params.fetch(:pacticipant_name)
20
+ @version_number = params.fetch(:version_number)
21
+ @environment_name = params.fetch(:environment_name)
22
+ @replaced_previous_deployed_version = params.fetch(:replaced_previous_deployed_version)
23
+ @output = params.fetch(:output)
24
+ @pact_broker_client_options = pact_broker_client_options
25
+ end
26
+
27
+ def call
28
+ check_if_command_supported
29
+ record_deployment
30
+
31
+ PactBroker::Client::CommandResult.new(true, result_message)
32
+ rescue PactBroker::Client::Error => e
33
+ PactBroker::Client::CommandResult.new(false, e.message)
34
+ end
35
+
36
+ private
37
+
38
+ attr_reader :pact_broker_base_url, :pact_broker_client_options
39
+ attr_reader :pacticipant_name, :version_number, :environment_name, :replaced_previous_deployed_version, :output
40
+ attr_reader :deployed_version_resource
41
+
42
+ def check_environment_exists
43
+ index_resource
44
+ ._link!("pb:environments")
45
+ .get!
46
+ ._links("pb:environments")
47
+ .find!(environment_name, "No environment found with name '#{environment_name}'")
48
+ end
49
+
50
+ def record_deployment
51
+ @deployed_version_resource =
52
+ get_record_deployment_relation
53
+ .post(record_deployment_request_body)
54
+ .assert_success!
55
+ end
56
+
57
+ def get_record_deployment_relation
58
+ record_deployment_links = get_pacticipant_version._links!("pb:record-deployment")
59
+ link_for_environment = record_deployment_links.find(environment_name)
60
+ if link_for_environment
61
+ link_for_environment
62
+ else
63
+ check_environment_exists
64
+ # Force the exception to be raised
65
+ record_deployment_links.find!(environment_name, "Environment '#{environment_name}' is not an available option for recording a deployment of #{pacticipant_name}.")
66
+ end
67
+ end
68
+
69
+ def get_pacticipant_version
70
+ index_resource
71
+ ._link!("pb:pacticipant-version")
72
+ .expand(pacticipant: pacticipant_name, version: version_number)
73
+ .get
74
+ .assert_success!(404 => "#{pacticipant_name} version #{version_number} not found")
75
+ end
76
+
77
+ def record_deployment_request_body
78
+ { replacedPreviousDeployedVersion: replaced_previous_deployed_version }
79
+ end
80
+
81
+ def result_message
82
+ if output == "text"
83
+ message = "Recorded deployment of #{pacticipant_name} version #{version_number} to #{environment_name} in #{pact_broker_name}."
84
+ suffix = replaced_previous_deployed_version ? " Marked previous deployed version as undeployed." : ""
85
+ message + suffix
86
+ elsif output == "json"
87
+ deployed_version_resource.response.raw_body
88
+ else
89
+ ""
90
+ end
91
+ end
92
+
93
+ def pact_broker_name
94
+ is_pactflow? ? "Pactflow" : "the Pact Broker"
95
+ end
96
+
97
+ def is_pactflow?
98
+ deployed_version_resource.response.headers.keys.any?{ | header_name | header_name.downcase.include?("pactflow") }
99
+ end
100
+
101
+ def check_if_command_supported
102
+ unless index_resource.can?("pb:environments")
103
+ raise PactBroker::Client::Error.new(NOT_SUPPORTED_MESSAGE)
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end
109
+ end
@@ -26,9 +26,11 @@ Gem::Specification.new do |gem|
26
26
  gem.add_runtime_dependency 'table_print', '~> 1.5'
27
27
  gem.add_runtime_dependency 'thor', '>= 0.20', '< 2.0'
28
28
  gem.add_runtime_dependency 'rake', '~> 13.0' #For FileList
29
+ gem.add_runtime_dependency 'dig_rb', '~> 1.0'
29
30
 
30
31
  gem.add_development_dependency 'fakefs', '~> 0.4'
31
32
  gem.add_development_dependency 'webmock', '~> 3.0'
32
33
  gem.add_development_dependency 'conventional-changelog', '~>1.3'
33
34
  gem.add_development_dependency 'pact', '~> 1.16'
35
+ gem.add_development_dependency 'pact-support', '1.15.0'
34
36
  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
+
@@ -19,7 +19,7 @@ output=$(curl -v -X POST https://api.github.com/repos/${repository_slug}/dispatc
19
19
  -H "Authorization: Bearer $GITHUB_ACCESS_TOKEN_FOR_PF_RELEASES" \
20
20
  -d "{\"event_type\": \"release-triggered\", \"client_payload\": {\"increment\": ${increment}}}" 2>&1)
21
21
 
22
- if ! echo "${output}" | grep "HTTP\/1.1 204" > /dev/null; then
22
+ if ! echo "${output}" | grep "HTTP\/.* 204" > /dev/null; then
23
23
  echo "$output" | sed "s/${GITHUB_ACCESS_TOKEN_FOR_PF_RELEASES}/********/g"
24
24
  echo "Failed to trigger release"
25
25
  exit 1
@@ -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
@@ -9,8 +9,9 @@ module PactBroker::Client
9
9
  end
10
10
 
11
11
  let(:provider_response) do
12
- double('response', body: provider_hash, success?: true)
12
+ double('response', body: provider_hash, success?: true, status: status)
13
13
  end
14
+ let(:status) { 200 }
14
15
 
15
16
  let(:provider_hash) do
16
17
  {
@@ -72,12 +73,12 @@ module PactBroker::Client
72
73
  subject(:entity) { ErrorEntity.new("http://pact", pact_hash, http_client) }
73
74
 
74
75
  it "raises an error" do
75
- expect { entity.assert_success! }.to raise_error ErrorResponseReturned, "Error retrieving http://pact status= "
76
+ expect { entity.assert_success! }.to raise_error ErrorResponseReturned, "Error retrieving http://pact status="
76
77
  end
77
78
  end
78
79
 
79
80
  context "when the response is not successful and there is a response" do
80
- let(:response) { double('response', code: 200, raw_body: "body") }
81
+ let(:response) { double('response', status: 200, raw_body: "body") }
81
82
 
82
83
  subject(:entity) { ErrorEntity.new("http://pact", pact_hash, http_client, response) }
83
84