pact_broker-client 1.40.0 → 1.41.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 (33) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/CHANGELOG.md +7 -0
  4. data/Gemfile +4 -0
  5. data/doc/pacts/markdown/Pact Broker Client - Pact Broker.md +2 -181
  6. data/lib/pact_broker/client/can_i_deploy.rb +20 -3
  7. data/lib/pact_broker/client/cli/broker.rb +13 -5
  8. data/lib/pact_broker/client/cli/record_deployment_long_desc.txt +0 -55
  9. data/lib/pact_broker/client/cli/version_selector_options_parser.rb +4 -0
  10. data/lib/pact_broker/client/colorize_notices.rb +31 -0
  11. data/lib/pact_broker/client/matrix.rb +4 -0
  12. data/lib/pact_broker/client/matrix/abbreviate_version_number.rb +15 -0
  13. data/lib/pact_broker/client/matrix/resource.rb +26 -1
  14. data/lib/pact_broker/client/matrix/text_formatter.rb +11 -8
  15. data/lib/pact_broker/client/publish_pacts.rb +6 -2
  16. data/lib/pact_broker/client/version.rb +1 -1
  17. data/lib/pact_broker/client/versions/record_deployment.rb +4 -4
  18. data/pact-broker-client.gemspec +1 -0
  19. data/script/approve-all.sh +6 -0
  20. data/script/publish-pact.sh +12 -9
  21. data/spec/fixtures/approvals/can_i_deploy_ignore.approved.txt +13 -0
  22. data/spec/lib/pact_broker/client/can_i_deploy_spec.rb +47 -5
  23. data/spec/lib/pact_broker/client/cli/broker_can_i_deploy_spec.rb +3 -3
  24. data/spec/lib/pact_broker/client/cli/version_selector_options_parser_spec.rb +21 -0
  25. data/spec/lib/pact_broker/client/versions/record_deployment_spec.rb +2 -2
  26. data/spec/pacts/pact_broker_client-pact_broker.json +2 -182
  27. data/spec/service_providers/pact_broker_client_matrix_ignore_spec.rb +98 -0
  28. data/spec/service_providers/publish_pacts_spec.rb +2 -1
  29. data/spec/service_providers/record_deployment_spec.rb +5 -6
  30. data/spec/spec_helper.rb +2 -1
  31. data/spec/support/approvals.rb +26 -0
  32. data/spec/support/shared_context.rb +6 -2
  33. metadata +32 -3
@@ -0,0 +1,31 @@
1
+ require 'term/ansicolor'
2
+
3
+ module PactBroker
4
+ module Client
5
+ class ColorizeNotices
6
+ def self.call(notices)
7
+ notices.collect do | notice |
8
+ colorized_message(notice)
9
+ end
10
+ end
11
+
12
+ def self.colorized_message(notice)
13
+ color = color_for_type(notice.type)
14
+ if color
15
+ ::Term::ANSIColor.color(color, notice.text || '')
16
+ else
17
+ notice.text
18
+ end
19
+ end
20
+
21
+ def self.color_for_type(type)
22
+ case type
23
+ when "warning", "prompt" then "yellow"
24
+ when "error", "danger" then :red
25
+ when "success" then :green
26
+ else nil
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -60,6 +60,9 @@ module PactBroker
60
60
  elsif selectors.size == 1 && !options[:to_environment]
61
61
  opts[:latest] = 'true'
62
62
  end
63
+ if options[:ignore_selectors] && options[:ignore_selectors].any?
64
+ opts[:ignore] = convert_selector_hashes_to_params(options[:ignore_selectors])
65
+ end
63
66
  opts
64
67
  end
65
68
 
@@ -69,6 +72,7 @@ module PactBroker
69
72
  hash[:version] = selector[:version] if selector[:version]
70
73
  hash[:latest] = 'true' if selector[:latest]
71
74
  hash[:tag] = selector[:tag] if selector[:tag]
75
+ hash[:branch] = selector[:branch] if selector[:branch]
72
76
  end
73
77
  end
74
78
  end
@@ -0,0 +1,15 @@
1
+ module PactBroker
2
+ module Client
3
+ class Matrix
4
+ class AbbreviateVersionNumber
5
+ def self.call version_number
6
+ if version_number
7
+ version_number.gsub(/[A-Za-z0-9]{40}/) do | val |
8
+ val[0...7] + "..."
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -2,9 +2,22 @@ require 'pact_broker/client/base_client'
2
2
 
3
3
  module PactBroker
4
4
  module Client
5
+ class Notice < Hash
6
+ def initialize(hash)
7
+ self.merge!(hash)
8
+ end
9
+
10
+ def text
11
+ self[:text]
12
+ end
13
+
14
+ def type
15
+ self[:type]
16
+ end
17
+ end
5
18
  class Matrix < BaseClient
6
- class Resource < Hash
7
19
 
20
+ class Resource < Hash
8
21
  def initialize hash
9
22
  self.merge!(hash)
10
23
  end
@@ -21,6 +34,10 @@ module PactBroker
21
34
  !!(self[:summary] && Integer === self[:summary][:unknown] )
22
35
  end
23
36
 
37
+ def supports_ignore?
38
+ !!(self[:summary] && Integer === self[:summary][:ignored] )
39
+ end
40
+
24
41
  def unknown_count
25
42
  supports_unknown_count? ? self[:summary][:unknown] : nil
26
43
  end
@@ -32,6 +49,14 @@ module PactBroker
32
49
  def deployable?
33
50
  self[:summary][:deployable]
34
51
  end
52
+
53
+ def notices
54
+ if self[:notices].is_a?(Array)
55
+ self[:notices].collect { | notice_hash | Notice.new(notice_hash) }
56
+ else
57
+ nil
58
+ end
59
+ end
35
60
  end
36
61
  end
37
62
  end
@@ -1,6 +1,7 @@
1
1
  require 'table_print'
2
2
  require 'dig_rb'
3
3
  require 'pact_broker/client/hash_refinements'
4
+ require 'pact_broker/client/matrix/abbreviate_version_number'
4
5
 
5
6
  module PactBroker
6
7
  module Client
@@ -8,18 +9,19 @@ module PactBroker
8
9
  class TextFormatter
9
10
  using PactBroker::Client::HashRefinements
10
11
 
11
- Line = Struct.new(:consumer, :consumer_version, :provider, :provider_version, :success, :ref)
12
+ Line = Struct.new(:consumer, :consumer_version, :provider, :provider_version, :success, :ref, :ignored)
12
13
 
13
- OPTIONS = [
14
+ TP_OPTIONS = [
14
15
  { consumer: {} },
15
16
  { consumer_version: {display_name: 'C.VERSION'} },
16
17
  { provider: {} },
17
18
  { provider_version: {display_name: 'P.VERSION'} },
18
19
  { success: {display_name: 'SUCCESS?'} },
19
- { ref: { display_name: 'RESULT#' }}
20
+ { ref: { display_name: 'RESULT#' } }
20
21
  ]
21
22
 
22
23
  def self.call(matrix)
24
+ tp_options = TP_OPTIONS.dup
23
25
  matrix_rows = matrix[:matrix]
24
26
  return "" if matrix_rows.size == 0
25
27
  verification_result_number = 0
@@ -30,15 +32,16 @@ module PactBroker
30
32
  end
31
33
  Line.new(
32
34
  lookup(line, "???", :consumer, :name),
33
- lookup(line, "???", :consumer, :version, :number),
35
+ AbbreviateVersionNumber.call(lookup(line, "???", :consumer, :version, :number)),
34
36
  lookup(line, "???", :provider, :name) ,
35
- lookup(line, "???", :provider, :version, :number),
36
- (lookup(line, "???", :verificationResult, :success)).to_s,
37
- has_verification_result_url ? verification_result_number : ""
37
+ AbbreviateVersionNumber.call(lookup(line, "???", :provider, :version, :number)),
38
+ (lookup(line, "???", :verificationResult, :success)).to_s + ( line[:ignored] ? " [ignored]" : ""),
39
+ has_verification_result_url ? verification_result_number : "",
40
+ lookup(line, nil, :ignored)
38
41
  )
39
42
  end
40
43
 
41
- printer = TablePrint::Printer.new(data, OPTIONS)
44
+ printer = TablePrint::Printer.new(data, tp_options)
42
45
  printer.table_print + verification_result_urls_text(matrix)
43
46
  end
44
47
 
@@ -2,6 +2,7 @@ require 'term/ansicolor'
2
2
  require 'pact_broker/client/hal_client_methods'
3
3
  require 'base64'
4
4
  require 'pact_broker/client/publish_pacts_the_old_way'
5
+ require 'pact_broker/client/colorize_notices'
5
6
 
6
7
  module PactBroker
7
8
  module Client
@@ -71,7 +72,9 @@ module PactBroker
71
72
  def text_message
72
73
  response_entities.flat_map do | response_entity |
73
74
  if response_entity.success?
74
- if response_entity.logs
75
+ if response_entity.notices
76
+ PactBroker::Client::ColorizeNotices.call(response_entity.notices.collect{ |n| OpenStruct.new(n) } )
77
+ elsif response_entity.logs
75
78
  response_entity.logs.collect do | log |
76
79
  colorized_message(log)
77
80
  end
@@ -112,7 +115,8 @@ module PactBroker
112
115
  specification: "pact",
113
116
  contentType: "application/json",
114
117
  content: Base64.strict_encode64(pact_hash.to_json),
115
- writeMode: write_mode
118
+ writeMode: write_mode,
119
+ onConflict: write_mode
116
120
  }
117
121
  end
118
122
  end
@@ -1,5 +1,5 @@
1
1
  module PactBroker
2
2
  module Client
3
- VERSION = '1.40.0'
3
+ VERSION = '1.41.0'
4
4
  end
5
5
  end
@@ -75,14 +75,14 @@ module PactBroker
75
75
  end
76
76
 
77
77
  def record_deployment_request_body
78
- { replacedPreviousDeployedVersion: target }
78
+ { target: target }
79
79
  end
80
80
 
81
81
  def result_message
82
82
  if output == "text"
83
- message = "Recorded deployment of #{pacticipant_name} version #{version_number} to #{environment_name} in #{pact_broker_name}."
84
- suffix = target ? " Marked previous deployed version as undeployed." : ""
85
- message + suffix
83
+ message = "Recorded deployment of #{pacticipant_name} version #{version_number} to #{environment_name}"
84
+ message = "#{message} (target #{target})" if target
85
+ "#{message} in #{pact_broker_name}."
86
86
  elsif output == "json"
87
87
  deployed_version_resource.response.raw_body
88
88
  else
@@ -33,4 +33,5 @@ Gem::Specification.new do |gem|
33
33
  gem.add_development_dependency 'conventional-changelog', '~>1.3'
34
34
  gem.add_development_dependency 'pact', '~> 1.16'
35
35
  gem.add_development_dependency 'pact-support', '~> 1.16'
36
+ gem.add_development_dependency 'approvals', '>=0.0.24', '<1.0.0'
36
37
  end
@@ -0,0 +1,6 @@
1
+ #!/bin/sh
2
+
3
+ for file in $(find spec/fixtures/approvals -ipath "*.received.*"); do
4
+ approved_path=$(echo "$file" | sed 's/received/approved/')
5
+ mv "$file" "$approved_path"
6
+ done;
@@ -1,3 +1,6 @@
1
+ export PACT_BROKER_BASE_URL="http://localhost:9292"
2
+ export PACT_BROKER_TOKEN="localhost"
3
+
1
4
  # bundle exec bin/pact-broker create-or-update-webhook http://localhost:9393 \
2
5
  # --uuid d40f38c3-aaa3-47f5-9161-95c07bc16b14 \
3
6
  # --request POST \
@@ -5,18 +8,18 @@
5
8
  # --contract-published
6
9
 
7
10
  bundle exec bin/pact-broker create-or-update-webhook http://localhost:9393 \
8
- --uuid d40f38c3-aaa3-47f5-9161-95c07bc16555 \
9
- --provider Bar \
11
+ --uuid d40f38c3-aaa3-47f5-9161-95csfadfsd7 \
12
+ --description "This is quite a long description for a webhook that I hope will be truncated" \
10
13
  --request POST \
11
14
  --contract-published
12
15
 
13
- bundle exec bin/pact-broker publish spec/pacts/pact_broker_client-pact_broker.json spec/pacts/foo-bar.json \
14
- --consumer-app-version 1.2.12 \
15
- --broker-base-url http://localhost:9292 \
16
- --broker-username localhost --broker-password localhost \
17
- --auto-detect-version-properties \
18
- --build-url http://mybuild \
19
- --branch master --tag foo5
16
+ # bundle exec bin/pact-broker publish spec/pacts/pact_broker_client-pact_broker.json spec/fixtures/foo-bar.json \
17
+ # --consumer-app-version 1.2.12 \
18
+ # --broker-base-url http://localhost:9292 \
19
+ # --broker-username localhost --broker-password localhost \
20
+ # --auto-detect-version-properties \
21
+ # --build-url http://mybuild \
22
+ # --branch master --tag foo5
20
23
 
21
24
  # bundle exec bin/pact-broker create-or-update-webhook http://localhost:9393 \
22
25
  # --uuid d40f38c3-aaa3-47f5-9161-95c07bc16555 \
@@ -0,0 +1,13 @@
1
+ Computer says yes \o/ 
2
+
3
+ CONSUMER | C.VERSION | PROVIDER | P.VERSION | SUCCESS? | RESULT#
4
+ ---------|-----------|----------|-----------|-----------------|--------
5
+ Foo | 1.2.3 | Bar | 4.5.6 | true | 1
6
+ Foo | 3.4.5 | Bar | 4.5.6 | false [ignored] | 2
7
+
8
+ VERIFICATION RESULTS
9
+ --------------------
10
+ 1. http://result (success)
11
+ 2. http://result (failure)
12
+
13
+ some notice
@@ -6,22 +6,27 @@ module PactBroker
6
6
  describe CanIDeploy do
7
7
  let(:pact_broker_base_url) { 'http://example.org' }
8
8
  let(:version_selectors) { [{ pacticipant: "Foo", version: "1" }] }
9
- let(:matrix_options) { {} }
9
+ let(:matrix_options) { { } }
10
10
  let(:pact_broker_client_options) { { foo: 'bar' } }
11
11
  let(:matrix_client) { instance_double('PactBroker::Client::Matrix') }
12
12
  let(:matrix) do
13
13
  instance_double('Matrix::Resource',
14
- deployable?: true,
14
+ deployable?: deployable,
15
15
  reason: 'some reason',
16
16
  any_unknown?: any_unknown,
17
17
  supports_unknown_count?: supports_unknown_count,
18
- unknown_count: unknown_count)
18
+ supports_ignore?: supports_ignore,
19
+ unknown_count: unknown_count,
20
+ notices: notices)
19
21
  end
20
22
  let(:unknown_count) { 0 }
21
23
  let(:any_unknown) { unknown_count > 0 }
22
24
  let(:supports_unknown_count) { true }
23
25
  let(:retry_while_unknown) { 0 }
24
26
  let(:options) { { output: 'text', retry_while_unknown: retry_while_unknown, retry_interval: 5 } }
27
+ let(:notices) { nil }
28
+ let(:supports_ignore) { true }
29
+ let(:deployable) { true }
25
30
 
26
31
 
27
32
  before do
@@ -55,10 +60,19 @@ module PactBroker
55
60
  it "returns a success reason" do
56
61
  expect(subject.message).to include "some reason"
57
62
  end
63
+
64
+ context "when there are notices" do
65
+ let(:notices) { [Notice.new(text: "some notice", type: "info")] }
66
+
67
+ it "returns the notices instead of the reason" do
68
+ expect(subject.message).to_not include "some reason"
69
+ expect(subject.message).to include "some notice"
70
+ end
71
+ end
58
72
  end
59
73
 
60
74
  context "when the versions are not deployable" do
61
- let(:matrix) { instance_double('Matrix::Resource', deployable?: false, reason: 'some reason', any_unknown?: false) }
75
+ let(:matrix) { instance_double('Matrix::Resource', deployable?: false, reason: 'some reason', any_unknown?: false, notices: notices) }
62
76
 
63
77
  it "returns a failure response" do
64
78
  expect(subject.success).to be false
@@ -71,6 +85,15 @@ module PactBroker
71
85
  it "returns a failure reason" do
72
86
  expect(subject.message).to include "some reason"
73
87
  end
88
+
89
+ context "when there are notices" do
90
+ let(:notices) { [Notice.new(text: "some notice", type: "info")] }
91
+
92
+ it "returns the notices instead of the reason" do
93
+ expect(subject.message).to_not include "some reason"
94
+ expect(subject.message).to include "some notice"
95
+ end
96
+ end
74
97
  end
75
98
 
76
99
  context "when retry_while_unknown is greater than 0" do
@@ -115,6 +138,25 @@ module PactBroker
115
138
  end
116
139
  end
117
140
 
141
+ context "when there are ignore selectors but the matrix does not support ignoring" do
142
+ let(:matrix_options) { { ignore_selectors: [{ pacticipant_name: "Foo" }]} }
143
+ let(:supports_ignore) { false }
144
+
145
+ context "when deployable" do
146
+ it "returns a warning" do
147
+ expect(subject.message).to include "does not support"
148
+ end
149
+ end
150
+
151
+ context "when not deployable" do
152
+ let(:deployable) { false }
153
+
154
+ it "returns a warning" do
155
+ expect(subject.message).to include "does not support"
156
+ end
157
+ end
158
+ end
159
+
118
160
  context "when a PactBroker::Client::Error is raised" do
119
161
  before do
120
162
  allow(matrix_client).to receive(:get).and_raise(PactBroker::Client::Error.new('error text'))
@@ -125,7 +167,7 @@ module PactBroker
125
167
  end
126
168
 
127
169
  it "returns a failure message" do
128
- expect(subject.message).to eq "error text"
170
+ expect(subject.message).to include "error text"
129
171
  end
130
172
  end
131
173
 
@@ -37,7 +37,7 @@ module PactBroker
37
37
  end
38
38
 
39
39
  it "invokes the CanIDeploy service" do
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'})
40
+ expect(CanIDeploy).to receive(:call).with('http://pact-broker', version_selectors, {to_tag: nil, to_environment: nil, limit: 1000, ignore_selectors: []}, {output: 'table', retry_while_unknown: 1, retry_interval: 2}, {verbose: 'verbose'})
41
41
  invoke_can_i_deploy
42
42
  end
43
43
 
@@ -55,7 +55,7 @@ module PactBroker
55
55
  end
56
56
 
57
57
  it "passes the value as the matrix options" do
58
- expect(CanIDeploy).to receive(:call).with(anything, anything, {to_tag: 'prod', to_environment: nil, limit: 1000}, anything, anything)
58
+ expect(CanIDeploy).to receive(:call).with(anything, anything, {to_tag: 'prod', to_environment: nil, limit: 1000, ignore_selectors: []}, anything, anything)
59
59
  invoke_can_i_deploy
60
60
  end
61
61
  end
@@ -66,7 +66,7 @@ module PactBroker
66
66
  end
67
67
 
68
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)
69
+ expect(CanIDeploy).to receive(:call).with(anything, anything, {to_tag: nil, to_environment: 'prod', limit: 1000, ignore_selectors: []}, anything, anything)
70
70
  invoke_can_i_deploy
71
71
  end
72
72
  end
@@ -48,6 +48,27 @@ module PactBroker
48
48
  ],[
49
49
  ["--pacticipant", "Foo=Bar", "--version", "1.2.3"],
50
50
  [{ pacticipant: "Foo=Bar", version: "1.2.3" } ]
51
+ ],[
52
+ ["--ignore", "Foo", "--version", "1.2.3"],
53
+ [{ pacticipant: "Foo", version: "1.2.3", ignore: true }]
54
+ ],[
55
+ ["--ignore", "Foo", "--ignore", "Bar", "--version", "1.2.3"],
56
+ [{ pacticipant: "Foo", ignore: true }, { pacticipant: "Bar", version: "1.2.3", ignore: true }]
57
+ ],[
58
+ ["--ignore", "Foo", "--pacticipant", "Bar", "--version", "1.2.3"],
59
+ [{ pacticipant: "Foo", ignore: true }, { pacticipant: "Bar", version: "1.2.3" }]
60
+ ],[
61
+ ["--pacticipant", "Foo", "--version", "1", "--version", "2"],
62
+ [{ pacticipant: "Foo", version: "2" }]
63
+ ],[
64
+ ["--pacticipant", "Foo", "--version", "2", "--latest"],
65
+ [{ pacticipant: "Foo", version: "2", latest: true }]
66
+ ],[
67
+ ["--pacticipant", "Foo", "--version", "2", "--latest", "--latest"],
68
+ [{ pacticipant: "Foo", version: "2", latest: true }]
69
+ ],[
70
+ ["--version", "2"],
71
+ [{ pacticipant: nil, version: "2" }]
51
72
  ]
52
73
  ]
53
74