pact_broker-client 1.33.0 → 1.37.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) 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 +47 -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 +76 -33
  11. data/lib/pact_broker/client/cli/can_i_deploy_long_desc.txt +18 -9
  12. data/lib/pact_broker/client/cli/create_or_update_webhook_long_desc.txt +3 -1
  13. data/lib/pact_broker/client/cli/create_webhook_long_desc.txt +2 -0
  14. data/lib/pact_broker/client/cli/custom_thor.rb +11 -17
  15. data/lib/pact_broker/client/git.rb +43 -22
  16. data/lib/pact_broker/client/hal/entity.rb +27 -3
  17. data/lib/pact_broker/client/hal/http_client.rb +4 -0
  18. data/lib/pact_broker/client/hal/links.rb +39 -0
  19. data/lib/pact_broker/client/hal_client_methods.rb +11 -0
  20. data/lib/pact_broker/client/hash_refinements.rb +19 -0
  21. data/lib/pact_broker/client/matrix.rb +2 -1
  22. data/lib/pact_broker/client/matrix/text_formatter.rb +46 -11
  23. data/lib/pact_broker/client/publish_pacts.rb +93 -14
  24. data/lib/pact_broker/client/tasks/publication_task.rb +37 -6
  25. data/lib/pact_broker/client/version.rb +1 -1
  26. data/lib/pact_broker/client/versions/record_deployment.rb +109 -0
  27. data/pact-broker-client.gemspec +1 -0
  28. data/script/publish-pact.sh +7 -1
  29. data/script/trigger-release.sh +1 -1
  30. data/spec/lib/pact_broker/client/cli/broker_can_i_deploy_spec.rb +15 -2
  31. data/spec/lib/pact_broker/client/cli/broker_publish_spec.rb +108 -12
  32. data/spec/lib/pact_broker/client/cli/custom_thor_spec.rb +1 -7
  33. data/spec/lib/pact_broker/client/git_spec.rb +39 -2
  34. data/spec/lib/pact_broker/client/hal/entity_spec.rb +4 -3
  35. data/spec/lib/pact_broker/client/matrix/text_formatter_spec.rb +29 -4
  36. data/spec/lib/pact_broker/client/publish_pacts_spec.rb +119 -7
  37. data/spec/lib/pact_broker/client/tasks/publication_task_spec.rb +88 -10
  38. data/spec/lib/pact_broker/client/versions/describe_spec.rb +0 -1
  39. data/spec/lib/pact_broker/client/versions/record_deployment_spec.rb +82 -0
  40. data/spec/pacts/pact_broker_client-pact_broker.json +335 -8
  41. data/spec/service_providers/pact_broker_client_create_version_spec.rb +89 -0
  42. data/spec/service_providers/pact_broker_client_matrix_spec.rb +4 -0
  43. data/spec/service_providers/pact_broker_client_versions_spec.rb +1 -2
  44. data/spec/service_providers/record_deployment_spec.rb +219 -0
  45. data/spec/support/matrix.json +6 -1
  46. data/spec/support/matrix.txt +3 -3
  47. data/spec/support/matrix_error.txt +3 -3
  48. data/spec/support/matrix_with_results.txt +10 -0
  49. data/tasks/pact.rake +2 -0
  50. metadata +30 -4
  51. data/.travis.yml +0 -11
@@ -1,5 +1,5 @@
1
1
  module PactBroker
2
2
  module Client
3
- VERSION = '1.33.0'
3
+ VERSION = '1.37.1'
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,6 +26,7 @@ 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'
@@ -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
@@ -1,4 +1,6 @@
1
1
  require 'pact_broker/client/cli/broker'
2
+ require 'pact_broker/client/cli/version_selector_options_parser'
3
+ require 'pact_broker/client/can_i_deploy'
2
4
 
3
5
  module PactBroker
4
6
  module Client
@@ -35,7 +37,7 @@ module PactBroker
35
37
  end
36
38
 
37
39
  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'})
40
+ 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
41
  invoke_can_i_deploy
40
42
  end
41
43
 
@@ -53,7 +55,18 @@ module PactBroker
53
55
  end
54
56
 
55
57
  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)
58
+ expect(CanIDeploy).to receive(:call).with(anything, anything, {to_tag: 'prod', to_environment: nil, limit: 1000}, anything, anything)
59
+ invoke_can_i_deploy
60
+ end
61
+ end
62
+
63
+ context "with --to-environment" do
64
+ before do
65
+ subject.options.to_environment = 'prod'
66
+ end
67
+
68
+ it "passes the value as the matrix options" do
69
+ expect(CanIDeploy).to receive(:call).with(anything, anything, {to_tag: nil, to_environment: 'prod', limit: 1000}, anything, anything)
57
70
  invoke_can_i_deploy
58
71
  end
59
72
  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
+ { }
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
@@ -52,12 +52,9 @@ module PactBroker::Client::CLI
52
52
  ENV['PACT_BROKER_TOKEN'] = 'token'
53
53
  end
54
54
 
55
- it "populates the options from the environment variables" do
55
+ it "populates the base URL from the environment variables" do
56
56
  expect(Delegate).to receive(:call) do | options |
57
57
  expect(options.broker_base_url).to eq 'http://foo'
58
- expect(options.broker_username).to eq 'username'
59
- expect(options.broker_password).to eq 'password'
60
- expect(options.broker_token).to eq 'token'
61
58
  end
62
59
  TestThor.start(%w{test_using_env_vars})
63
60
  end
@@ -65,9 +62,6 @@ module PactBroker::Client::CLI
65
62
  it "does not override a value specifed on the command line" do
66
63
  expect(Delegate).to receive(:call) do | options |
67
64
  expect(options.broker_base_url).to eq 'http://bar'
68
- expect(options.broker_username).to eq 'username'
69
- expect(options.broker_password).to eq 'password'
70
- expect(options.broker_token).to eq 'token'
71
65
  end
72
66
  TestThor.start(%w{test_using_env_vars --broker-base-url http://bar})
73
67
  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