pact_broker-client 1.36.0 → 1.37.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/release_gem.yml +1 -0
- data/CHANGELOG.md +11 -0
- data/Rakefile +2 -0
- data/doc/pacts/markdown/Pact Broker Client - Pact Broker.md +180 -0
- data/lib/pact_broker/client.rb +1 -1
- data/lib/pact_broker/client/backports.rb +13 -0
- data/lib/pact_broker/client/cli/broker.rb +42 -23
- data/lib/pact_broker/client/cli/custom_thor.rb +9 -12
- data/lib/pact_broker/client/git.rb +3 -0
- data/lib/pact_broker/client/hal/entity.rb +27 -3
- data/lib/pact_broker/client/hal/http_client.rb +4 -0
- data/lib/pact_broker/client/hal/links.rb +39 -0
- data/lib/pact_broker/client/hal_client_methods.rb +11 -0
- data/lib/pact_broker/client/hash_refinements.rb +19 -0
- data/lib/pact_broker/client/matrix/text_formatter.rb +2 -0
- data/lib/pact_broker/client/publish_pacts.rb +2 -1
- data/lib/pact_broker/client/tasks/publication_task.rb +2 -0
- data/lib/pact_broker/client/version.rb +1 -1
- data/lib/pact_broker/client/versions/record_deployment.rb +109 -0
- data/script/trigger-release.sh +1 -1
- data/spec/lib/pact_broker/client/hal/entity_spec.rb +4 -3
- data/spec/lib/pact_broker/client/versions/describe_spec.rb +0 -1
- data/spec/lib/pact_broker/client/versions/record_deployment_spec.rb +82 -0
- data/spec/pacts/pact_broker_client-pact_broker.json +181 -0
- data/spec/service_providers/record_deployment_spec.rb +219 -0
- metadata +10 -2
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'pact_broker/client/error'
|
2
|
+
require 'pact_broker/client/hash_refinements'
|
2
3
|
|
3
4
|
=begin
|
4
5
|
|
@@ -21,6 +22,8 @@ BITBUCKET_BRANCH BITBUCKET_COMMIT https://confluence.atlassian.com/bitbucket/var
|
|
21
22
|
module PactBroker
|
22
23
|
module Client
|
23
24
|
module Git
|
25
|
+
using PactBroker::Client::HashRefinements
|
26
|
+
|
24
27
|
COMMAND = 'git rev-parse --abbrev-ref HEAD'.freeze
|
25
28
|
BRANCH_ENV_VAR_NAMES = %w{BUILDKITE_BRANCH CIRCLE_BRANCH TRAVIS_BRANCH GIT_BRANCH GIT_LOCAL_BRANCH APPVEYOR_REPO_BRANCH CI_COMMIT_REF_NAME BITBUCKET_BRANCH}.freeze
|
26
29
|
COMMIT_ENV_VAR_NAMES = %w{BUILDKITE_COMMIT CIRCLE_SHA1 TRAVIS_COMMIT GIT_COMMIT APPVEYOR_REPO_COMMIT CI_COMMIT_ID BITBUCKET_COMMIT}
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'erb'
|
2
2
|
require 'delegate'
|
3
3
|
require 'pact_broker/client/hal/link'
|
4
|
+
require 'pact_broker/client/hal/links'
|
4
5
|
|
5
6
|
module PactBroker
|
6
7
|
module Client
|
@@ -51,10 +52,27 @@ module PactBroker
|
|
51
52
|
end
|
52
53
|
end
|
53
54
|
|
55
|
+
def _links(key)
|
56
|
+
if @links[key] && @links[key].is_a?(Array)
|
57
|
+
link_collection = @links[key].collect do | hash |
|
58
|
+
Link.new(hash, @client)
|
59
|
+
end
|
60
|
+
Links.new(@href, key, link_collection)
|
61
|
+
elsif @links[key].is_a?(Hash)
|
62
|
+
Links.new(@href, key, [Link.new(@links[key], @client)])
|
63
|
+
else
|
64
|
+
nil
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
54
68
|
def _link!(key)
|
55
69
|
_link(key) or raise RelationNotFoundError.new("Could not find relation '#{key}' in resource at #{@href}")
|
56
70
|
end
|
57
71
|
|
72
|
+
def _links!(key)
|
73
|
+
_links(key) or raise RelationNotFoundError.new("Could not find relation '#{key}' in resource at #{@href}")
|
74
|
+
end
|
75
|
+
|
58
76
|
def success?
|
59
77
|
true
|
60
78
|
end
|
@@ -85,7 +103,7 @@ module PactBroker
|
|
85
103
|
@data.key?(method_name) || @links.key?(method_name)
|
86
104
|
end
|
87
105
|
|
88
|
-
def assert_success!
|
106
|
+
def assert_success!(_ignored = nil)
|
89
107
|
self
|
90
108
|
end
|
91
109
|
end
|
@@ -107,8 +125,14 @@ module PactBroker
|
|
107
125
|
false
|
108
126
|
end
|
109
127
|
|
110
|
-
def assert_success!
|
111
|
-
|
128
|
+
def assert_success!(messages = {})
|
129
|
+
default_message = "Error retrieving #{@href} status=#{response ? response.status: nil} #{response ? response.raw_body : ''}".strip
|
130
|
+
message = if response && messages[response.status]
|
131
|
+
(messages[response.status] || "") + " (#{default_message})"
|
132
|
+
else
|
133
|
+
default_message
|
134
|
+
end
|
135
|
+
raise ErrorResponseReturned.new(message)
|
112
136
|
end
|
113
137
|
end
|
114
138
|
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'uri'
|
2
|
+
require 'delegate'
|
3
|
+
|
4
|
+
module PactBroker
|
5
|
+
module Client
|
6
|
+
module Hal
|
7
|
+
class Links
|
8
|
+
def initialize(href, key, links)
|
9
|
+
@href = href
|
10
|
+
@key = key
|
11
|
+
@links = links
|
12
|
+
end
|
13
|
+
|
14
|
+
def names
|
15
|
+
@names ||= links.collect(&:name).compact.uniq
|
16
|
+
end
|
17
|
+
|
18
|
+
def find!(name, not_found_message = nil)
|
19
|
+
link = find(name)
|
20
|
+
if link
|
21
|
+
link
|
22
|
+
else
|
23
|
+
message = not_found_message || "Could not find relation '#{key}' with name '#{name}' in resource at #{href}."
|
24
|
+
available_options = names.any? ? names.join(", ") : "<none found>"
|
25
|
+
raise RelationNotFoundError.new(message.chomp(".") + ". Available options: #{available_options}")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def find(name)
|
30
|
+
links.find{ | link | link.name == name }
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
attr_reader :links, :key, :href
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'pact_broker/client/hal'
|
2
|
+
require 'pact_broker/client/retry'
|
2
3
|
|
3
4
|
module PactBroker
|
4
5
|
module Client
|
@@ -10,6 +11,16 @@ module PactBroker
|
|
10
11
|
def create_http_client(pact_broker_client_options)
|
11
12
|
PactBroker::Client::Hal::HttpClient.new(pact_broker_client_options.merge(pact_broker_client_options[:basic_auth] || {}))
|
12
13
|
end
|
14
|
+
|
15
|
+
def index_entry_point
|
16
|
+
@index_entry_point ||= create_index_entry_point(pact_broker_base_url, pact_broker_client_options)
|
17
|
+
end
|
18
|
+
|
19
|
+
def index_resource
|
20
|
+
@index_resource ||= Retry.while_error do
|
21
|
+
index_entry_point.get!
|
22
|
+
end
|
23
|
+
end
|
13
24
|
end
|
14
25
|
end
|
15
26
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module PactBroker
|
2
|
+
module Client
|
3
|
+
module HashRefinements
|
4
|
+
refine Hash do
|
5
|
+
def compact
|
6
|
+
h = {}
|
7
|
+
each do |key, value|
|
8
|
+
h[key] = value unless value == nil
|
9
|
+
end
|
10
|
+
h
|
11
|
+
end unless Hash.method_defined? :compact
|
12
|
+
|
13
|
+
def compact!
|
14
|
+
reject! {|_key, value| value == nil}
|
15
|
+
end unless Hash.method_defined? :compact!
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -1,10 +1,12 @@
|
|
1
1
|
require 'table_print'
|
2
2
|
require 'dig_rb'
|
3
|
+
require 'pact_broker/client/hash_refinements'
|
3
4
|
|
4
5
|
module PactBroker
|
5
6
|
module Client
|
6
7
|
class Matrix
|
7
8
|
class TextFormatter
|
9
|
+
using PactBroker::Client::HashRefinements
|
8
10
|
|
9
11
|
Line = Struct.new(:consumer, :consumer_version, :provider, :provider_version, :success, :ref)
|
10
12
|
|
@@ -5,11 +5,12 @@ require 'pact_broker/client/pact_file'
|
|
5
5
|
require 'pact_broker/client/pact_hash'
|
6
6
|
require 'pact_broker/client/merge_pacts'
|
7
7
|
require 'pact_broker/client/hal_client_methods'
|
8
|
+
require 'pact_broker/client/hash_refinements'
|
8
9
|
|
9
10
|
module PactBroker
|
10
11
|
module Client
|
11
12
|
class PublishPacts
|
12
|
-
|
13
|
+
using PactBroker::Client::HashRefinements
|
13
14
|
include HalClientMethods
|
14
15
|
|
15
16
|
def self.call(pact_broker_base_url, pact_file_paths, consumer_version_params, pact_broker_client_options={})
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'rake/tasklib'
|
2
2
|
require 'pact_broker/client/git'
|
3
|
+
require 'pact_broker/client/hash_refinements'
|
3
4
|
|
4
5
|
=begin
|
5
6
|
require pact_broker/client/tasks
|
@@ -17,6 +18,7 @@ end
|
|
17
18
|
module PactBroker
|
18
19
|
module Client
|
19
20
|
class PublicationTask < ::Rake::TaskLib
|
21
|
+
using PactBroker::Client::HashRefinements
|
20
22
|
|
21
23
|
attr_accessor :pattern, :pact_broker_base_url, :consumer_version, :tag, :write_method, :tag_with_git_branch, :pact_broker_basic_auth, :pact_broker_token
|
22
24
|
attr_reader :auto_detect_version_properties, :branch, :build_url
|
@@ -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
|
data/script/trigger-release.sh
CHANGED
@@ -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
|
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
|
@@ -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',
|
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
|
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'pact_broker/client/versions/record_deployment'
|
2
|
+
|
3
|
+
module PactBroker
|
4
|
+
module Client
|
5
|
+
class Versions
|
6
|
+
describe RecordDeployment do
|
7
|
+
describe ".call" do
|
8
|
+
let(:broker_base_url) { "http://broker" }
|
9
|
+
let(:index_body_hash) do
|
10
|
+
{
|
11
|
+
_links: {}
|
12
|
+
}
|
13
|
+
end
|
14
|
+
let!(:index_request) do
|
15
|
+
stub_request(:get, broker_base_url).to_return(status: 200, body: index_body_hash.to_json, headers: { "Content-Type" => "application/hal+json" } )
|
16
|
+
end
|
17
|
+
|
18
|
+
let(:replaced_previous_deployed_version) { true }
|
19
|
+
|
20
|
+
let(:params) do
|
21
|
+
{
|
22
|
+
pacticipant_name: "Foo",
|
23
|
+
version_number: "1",
|
24
|
+
environment_name: "test",
|
25
|
+
replaced_previous_deployed_version: replaced_previous_deployed_version,
|
26
|
+
output: "text"
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
let(:pact_broker_client_options) { {} }
|
31
|
+
|
32
|
+
subject { RecordDeployment.call(params, broker_base_url, pact_broker_client_options) }
|
33
|
+
|
34
|
+
context "when the pb:environments relation does not exist" do
|
35
|
+
it "returns an error response" do
|
36
|
+
expect(subject.success).to be false
|
37
|
+
expect(subject.message).to include "does not support"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context "when the response headers contain Pactflow" do
|
42
|
+
before do
|
43
|
+
allow_any_instance_of(RecordDeployment).to receive(:check_if_command_supported)
|
44
|
+
allow_any_instance_of(RecordDeployment).to receive(:check_environment_exists)
|
45
|
+
allow_any_instance_of(RecordDeployment).to receive(:record_deployment)
|
46
|
+
allow_any_instance_of(RecordDeployment).to receive(:deployed_version_resource).and_return(deployed_version_resource)
|
47
|
+
end
|
48
|
+
|
49
|
+
let(:response_headers) { { "X-Pactflow-Sha" => "abc" } }
|
50
|
+
|
51
|
+
let(:deployed_version_resource) do
|
52
|
+
double('PactBroker::Client::Hal::Entity', response: double('response', headers: response_headers) )
|
53
|
+
end
|
54
|
+
|
55
|
+
it "indicates the API was Pactflow" do
|
56
|
+
expect(subject.message).to include "Recorded deployment of Foo version 1 to test in Pactflow"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context "when replaced_previous_deployed_version is false" do
|
61
|
+
before do
|
62
|
+
allow_any_instance_of(RecordDeployment).to receive(:check_if_command_supported)
|
63
|
+
allow_any_instance_of(RecordDeployment).to receive(:check_environment_exists)
|
64
|
+
allow_any_instance_of(RecordDeployment).to receive(:record_deployment)
|
65
|
+
allow_any_instance_of(RecordDeployment).to receive(:pact_broker_name).and_return("")
|
66
|
+
end
|
67
|
+
|
68
|
+
let(:replaced_previous_deployed_version) { false }
|
69
|
+
|
70
|
+
let(:deployed_version_resource) do
|
71
|
+
double('PactBroker::Client::Hal::Entity', response: double('response', headers: response_headers) )
|
72
|
+
end
|
73
|
+
|
74
|
+
it "does not include the message about marking the previous version as undeployed" do
|
75
|
+
expect(subject.message).to_not include "undeployed"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|