pact_broker-client 1.43.0 → 1.44.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/test.yml +21 -0
- data/CHANGELOG.md +13 -0
- data/doc/pacts/markdown/Pact Broker Client - Pact Broker.md +0 -281
- data/lib/pact_broker/client/cli/broker.rb +3 -55
- data/lib/pact_broker/client/cli/deployment_commands.rb +74 -0
- data/lib/pact_broker/client/cli/pacticipant_commands.rb +9 -0
- data/lib/pact_broker/client/deployments.rb +4 -0
- data/lib/pact_broker/client/deployments/record_deployment.rb +38 -0
- data/lib/pact_broker/client/deployments/record_release.rb +99 -0
- data/lib/pact_broker/client/deployments/record_undeployment.rb +120 -0
- data/lib/pact_broker/client/describe_text_formatter.rb +23 -0
- data/lib/pact_broker/client/environments.rb +6 -3
- data/lib/pact_broker/client/environments/describe_environment.rb +3 -13
- data/lib/pact_broker/client/hal/entity.rb +5 -2
- data/lib/pact_broker/client/hal/http_client.rb +3 -2
- data/lib/pact_broker/client/pacticipants.rb +3 -3
- data/lib/pact_broker/client/pacticipants/create.rb +1 -1
- data/lib/pact_broker/client/pacticipants/describe.rb +33 -0
- data/lib/pact_broker/client/version.rb +1 -1
- data/lib/pact_broker/client/versions.rb +4 -1
- data/lib/pact_broker/client/versions/describe.rb +3 -1
- data/lib/pact_broker/client/versions/formatter.rb +3 -1
- data/lib/pact_broker/client/versions/json_formatter.rb +5 -3
- data/lib/pact_broker/client/versions/text_formatter.rb +3 -1
- data/script/record-deployments-and-releases.sh +10 -0
- data/spec/fixtures/approvals/describe_pacticipant.approved.txt +2 -0
- data/spec/integration/describe_environment_spec.rb +31 -0
- data/spec/lib/pact_broker/client/deployments/record_deployment_spec.rb +204 -0
- data/spec/pacts/pact_broker_client-pact_broker.json +0 -288
- data/spec/service_providers/publish_pacts_spec.rb +3 -1
- data/spec/service_providers/record_deployment_spec.rb +7 -29
- data/spec/service_providers/record_release_spec.rb +135 -0
- data/spec/spec_helper.rb +13 -2
- data/tasks/pact.rake +19 -1
- metadata +18 -6
- data/lib/pact_broker/client/versions/record_deployment.rb +0 -85
- data/lib/pact_broker/client/versions/record_undeployment.rb +0 -102
- data/spec/lib/pact_broker/client/versions/record_deployment_spec.rb +0 -75
@@ -0,0 +1,74 @@
|
|
1
|
+
module PactBroker
|
2
|
+
module Client
|
3
|
+
module CLI
|
4
|
+
module DeploymentCommands
|
5
|
+
HELP_URL = "https://docs.pact.io/pact_broker/recording_deployments_and_releases/"
|
6
|
+
|
7
|
+
def self.included(thor)
|
8
|
+
thor.class_eval do
|
9
|
+
desc "record-deployment", "Record deployment of a pacticipant version to an environment. See #{HELP_URL} for more information."
|
10
|
+
method_option :pacticipant, required: true, aliases: "-a", desc: "The name of the pacticipant that was deployed."
|
11
|
+
method_option :version, required: true, aliases: "-e", desc: "The pacticipant version number that was deployed."
|
12
|
+
method_option :environment, required: true, desc: "The name of the environment that the pacticipant version was deployed to."
|
13
|
+
method_option :target, default: nil, required: false, desc: "Optional. The target of the deployment - a logical identifer required to differentiate deployments when there are multiple instances of the same application in an environment."
|
14
|
+
output_option_json_or_text
|
15
|
+
shared_authentication_options
|
16
|
+
|
17
|
+
def record_deployment
|
18
|
+
params = {
|
19
|
+
pacticipant_name: options.pacticipant,
|
20
|
+
version_number: options.version,
|
21
|
+
environment_name: options.environment,
|
22
|
+
target: options.target
|
23
|
+
}
|
24
|
+
execute_deployment_command(params, "RecordDeployment")
|
25
|
+
end
|
26
|
+
|
27
|
+
desc "record-undeployment", "Record undeployment of a pacticipant version from an environment."
|
28
|
+
long_desc "Note that use of this command is not required if you are deploying over a previous version, as record-deployment will handle that scenario for you. This command is only required if you are permanently removing an application instance from an environment."
|
29
|
+
method_option :pacticipant, required: true, aliases: "-a", desc: "The name of the pacticipant that was undeployed."
|
30
|
+
method_option :environment, required: true, desc: "The name of the environment that the pacticipant version was undeployed from."
|
31
|
+
method_option :target, default: nil, required: false, desc: "Optional. The target that the application is being undeployed from - a logical identifer required to differentiate deployments when there are multiple instances of the same application in an environment."
|
32
|
+
output_option_json_or_text
|
33
|
+
shared_authentication_options
|
34
|
+
|
35
|
+
def record_undeployment
|
36
|
+
params = {
|
37
|
+
pacticipant_name: options.pacticipant,
|
38
|
+
environment_name: options.environment,
|
39
|
+
target: options.target
|
40
|
+
}
|
41
|
+
execute_deployment_command(params, "RecordUndeployment")
|
42
|
+
end
|
43
|
+
|
44
|
+
desc "record-release", "Record release of a pacticipant version to an environment. See See #{HELP_URL} for more information."
|
45
|
+
method_option :pacticipant, required: true, aliases: "-a", desc: "The name of the pacticipant that was released."
|
46
|
+
method_option :version, required: true, aliases: "-e", desc: "The pacticipant version number that was released."
|
47
|
+
method_option :environment, required: true, desc: "The name of the environment that the pacticipant version was released to."
|
48
|
+
output_option_json_or_text
|
49
|
+
shared_authentication_options
|
50
|
+
|
51
|
+
def record_release
|
52
|
+
params = {
|
53
|
+
pacticipant_name: options.pacticipant,
|
54
|
+
version_number: options.version,
|
55
|
+
environment_name: options.environment
|
56
|
+
}
|
57
|
+
execute_deployment_command(params, "RecordRelease")
|
58
|
+
end
|
59
|
+
|
60
|
+
no_commands do
|
61
|
+
def execute_deployment_command(params, command_class_name)
|
62
|
+
require 'pact_broker/client/deployments'
|
63
|
+
command_options = { verbose: options.verbose, output: options.output }
|
64
|
+
result = PactBroker::Client::Deployments.const_get(command_class_name).call(params, command_options, pact_broker_client_options)
|
65
|
+
$stdout.puts result.message
|
66
|
+
exit(1) unless result.success
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -27,6 +27,15 @@ module PactBroker
|
|
27
27
|
execute_pacticipant_command(params_from_options(PACTICIPANT_PARAM_NAMES), 'List')
|
28
28
|
end
|
29
29
|
|
30
|
+
desc 'describe-pacticipant', "Describe a pacticipant"
|
31
|
+
method_option :name, type: :string, required: true, desc: "Pacticipant name"
|
32
|
+
output_option_json_or_text
|
33
|
+
shared_authentication_options
|
34
|
+
verbose_option
|
35
|
+
def describe_pacticipant
|
36
|
+
execute_pacticipant_command({ name: options.name }, 'Describe')
|
37
|
+
end
|
38
|
+
|
30
39
|
no_commands do
|
31
40
|
def execute_pacticipant_command(params, command_class_name)
|
32
41
|
require 'pact_broker/client/pacticipants'
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'pact_broker/client/deployments/record_release'
|
2
|
+
|
3
|
+
module PactBroker
|
4
|
+
module Client
|
5
|
+
module Deployments
|
6
|
+
class RecordDeployment < PactBroker::Client::Deployments::RecordRelease
|
7
|
+
def initialize(params, options, pact_broker_client_options)
|
8
|
+
super
|
9
|
+
@target = params.fetch(:target)
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
attr_reader :target
|
15
|
+
|
16
|
+
def action
|
17
|
+
"deployment"
|
18
|
+
end
|
19
|
+
|
20
|
+
def action_relation_name
|
21
|
+
"pb:record-deployment"
|
22
|
+
end
|
23
|
+
|
24
|
+
def record_action_request_body
|
25
|
+
{ target: target }.compact
|
26
|
+
end
|
27
|
+
|
28
|
+
def result_text_message
|
29
|
+
if target
|
30
|
+
"#{super} (target #{target})"
|
31
|
+
else
|
32
|
+
super
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'pact_broker/client/base_command'
|
2
|
+
|
3
|
+
module PactBroker
|
4
|
+
module Client
|
5
|
+
module Deployments
|
6
|
+
class RecordRelease < PactBroker::Client::BaseCommand
|
7
|
+
def initialize(params, options, pact_broker_client_options)
|
8
|
+
super
|
9
|
+
@pacticipant_name = params.fetch(:pacticipant_name)
|
10
|
+
@version_number = params.fetch(:version_number)
|
11
|
+
@environment_name = params.fetch(:environment_name)
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
attr_reader :pacticipant_name, :version_number, :environment_name
|
17
|
+
attr_reader :deployed_version_resource
|
18
|
+
|
19
|
+
def do_call
|
20
|
+
record_action
|
21
|
+
PactBroker::Client::CommandResult.new(true, result_message)
|
22
|
+
end
|
23
|
+
|
24
|
+
def action
|
25
|
+
"release"
|
26
|
+
end
|
27
|
+
|
28
|
+
def action_relation_name
|
29
|
+
"pb:record-release"
|
30
|
+
end
|
31
|
+
|
32
|
+
def not_supported_message
|
33
|
+
"This version of the Pact Broker does not support recording #{action}s. Please upgrade to version 2.80.0 or later."
|
34
|
+
end
|
35
|
+
|
36
|
+
def environment_exists?
|
37
|
+
index_resource
|
38
|
+
._link!("pb:environments")
|
39
|
+
.get!
|
40
|
+
._links("pb:environments")
|
41
|
+
.find(environment_name)
|
42
|
+
end
|
43
|
+
|
44
|
+
def record_action
|
45
|
+
@deployed_version_resource =
|
46
|
+
get_record_action_relation
|
47
|
+
.post(record_action_request_body)
|
48
|
+
.assert_success!
|
49
|
+
end
|
50
|
+
|
51
|
+
def record_action_links
|
52
|
+
get_pacticipant_version._links(action_relation_name) or raise PactBroker::Client::Error.new(not_supported_message)
|
53
|
+
end
|
54
|
+
|
55
|
+
def get_record_action_relation
|
56
|
+
record_action_links.find(environment_name) or record_action_links.find!(environment_name, environment_relation_not_found_error_message)
|
57
|
+
end
|
58
|
+
|
59
|
+
def environment_relation_not_found_error_message
|
60
|
+
if environment_exists?
|
61
|
+
"Environment '#{environment_name}' is not an available option for recording a deployment of #{pacticipant_name}."
|
62
|
+
else
|
63
|
+
"No environment found with name '#{environment_name}'."
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def get_pacticipant_version
|
68
|
+
index_resource
|
69
|
+
._link!("pb:pacticipant-version")
|
70
|
+
.expand(pacticipant: pacticipant_name, version: version_number)
|
71
|
+
.get
|
72
|
+
.assert_success!(404 => "#{pacticipant_name} version #{version_number} not found")
|
73
|
+
end
|
74
|
+
|
75
|
+
def record_action_request_body
|
76
|
+
{}
|
77
|
+
end
|
78
|
+
|
79
|
+
def result_message
|
80
|
+
if json_output?
|
81
|
+
deployed_version_resource.response.raw_body
|
82
|
+
else
|
83
|
+
green("#{result_text_message} in #{pact_broker_name}.")
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def result_text_message
|
88
|
+
"Recorded #{action} of #{pacticipant_name} version #{version_number} to #{environment_name} environment"
|
89
|
+
end
|
90
|
+
|
91
|
+
def check_if_command_supported
|
92
|
+
unless index_resource.can?("pb:environments")
|
93
|
+
raise PactBroker::Client::Error.new(not_supported_message)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
require 'pact_broker/client/base_command'
|
2
|
+
|
3
|
+
module PactBroker
|
4
|
+
module Client
|
5
|
+
module Deployments
|
6
|
+
class RecordUndeployment < PactBroker::Client::BaseCommand
|
7
|
+
|
8
|
+
|
9
|
+
|
10
|
+
def initialize(params, pact_broker_base_url, pact_broker_client_options)
|
11
|
+
super
|
12
|
+
@pacticipant_name = params.fetch(:pacticipant_name)
|
13
|
+
@environment_name = params.fetch(:environment_name)
|
14
|
+
@target = params.fetch(:target)
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def do_call
|
20
|
+
if undeployed_versions_resources.empty?
|
21
|
+
check_pacticipant_exists!
|
22
|
+
PactBroker::Client::CommandResult.new(false, deployed_version_not_found_error_message)
|
23
|
+
else
|
24
|
+
PactBroker::Client::CommandResult.new(undeployed_versions_resources.all?(:success?), result_message)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
attr_reader :pacticipant_name, :version_number, :environment_name, :target, :output
|
29
|
+
attr_reader :deployed_version_resource, :undeployment_entities
|
30
|
+
|
31
|
+
def currently_deployed_versions_link
|
32
|
+
environment_resource._link("pb:currently-deployed-versions") or raise PactBroker::Client::Error.new(not_supported_message)
|
33
|
+
end
|
34
|
+
|
35
|
+
def currently_deployed_versions_resource
|
36
|
+
@deployed_version_links ||= currently_deployed_versions_link.get!(pacticipant: pacticipant_name, target: target)
|
37
|
+
end
|
38
|
+
|
39
|
+
def undeployed_versions_resources
|
40
|
+
@undeployed_versions_resources ||= currently_deployed_versions_resource.embedded_entities("deployedVersions").collect do | entity |
|
41
|
+
entity._link!("self").patch(currentlyDeployed: false)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def action
|
46
|
+
"undeployment"
|
47
|
+
end
|
48
|
+
|
49
|
+
def environment_resource
|
50
|
+
index_resource
|
51
|
+
._link!("pb:environments")
|
52
|
+
.get!
|
53
|
+
._links("pb:environments")
|
54
|
+
.find!(environment_name, "No environment found with name '#{environment_name}'")
|
55
|
+
.get!
|
56
|
+
end
|
57
|
+
|
58
|
+
def check_pacticipant_exists!
|
59
|
+
if index_resource._link!("pb:pacticipant").expand(pacticipant: pacticipant_name).get.does_not_exist?
|
60
|
+
raise PactBroker::Client::Error.new("No pacticipant with name '#{pacticipant_name}' found")
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def result_message
|
65
|
+
if json_output?
|
66
|
+
undeployed_versions_resources.collect{ | resource | resource.response.body }.to_a.to_json
|
67
|
+
else
|
68
|
+
undeployed_versions_resources.collect do | undeployed_versions_resource |
|
69
|
+
if undeployed_versions_resource.success?
|
70
|
+
green("#{success_result_text_message(undeployed_versions_resource)} in #{pact_broker_name}.")
|
71
|
+
else
|
72
|
+
red(undeployed_versions_resource.error_message)
|
73
|
+
end
|
74
|
+
end.join("\n")
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def success_result_text_message(undeployed_versions_resource)
|
79
|
+
version_number = undeployed_versions_resource.embedded_entity{ | embedded_entity| embedded_entity['version'] }.number
|
80
|
+
message = "Recorded #{action} of #{pacticipant_name} version #{version_number} from #{environment_name} environment"
|
81
|
+
if target
|
82
|
+
message + " (target #{target})"
|
83
|
+
else
|
84
|
+
message
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def deployed_version_not_found_error_message
|
89
|
+
target_bit = target ? " with target '#{target}'" : ""
|
90
|
+
message = "#{pacticipant_name} is not currently deployed to #{environment_name}#{target_bit}. Cannot record undeployment."
|
91
|
+
|
92
|
+
if json_output?
|
93
|
+
{ error: message }.to_json
|
94
|
+
else
|
95
|
+
red(message)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
|
100
|
+
def deployed_version_not_found_message
|
101
|
+
if (env_names = deployed_version_links.names).any?
|
102
|
+
"#{pacticipant_name} version #{version_number} is not currently deployed to #{environment_name}. It is currently deployed to: #{env_names.join(", ")}"
|
103
|
+
else
|
104
|
+
"#{pacticipant_name} version #{version_number} is not currently deployed to any environment."
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def not_supported_message
|
109
|
+
"This version of the Pact Broker does not support recording undeployments. Please upgrade to version 2.80.0 or later."
|
110
|
+
end
|
111
|
+
|
112
|
+
def check_if_command_supported
|
113
|
+
unless index_resource.can?("pb:environments")
|
114
|
+
raise PactBroker::Client::Error.new(not_supported_message)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'pact_broker/client/generate_display_name'
|
3
|
+
|
4
|
+
module PactBroker
|
5
|
+
module Client
|
6
|
+
class DescribeTextFormatter
|
7
|
+
extend GenerateDisplayName
|
8
|
+
|
9
|
+
def self.call(properties)
|
10
|
+
YAML.dump(displayify_keys(properties)).gsub("---\n", "")
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.displayify_keys(thing)
|
14
|
+
case thing
|
15
|
+
when Hash then thing.each_with_object({}) { | (key, value), new_hash | new_hash[generate_display_name(key)] = displayify_keys(value) }
|
16
|
+
when Array then thing.collect{ | value | displayify_keys(value) }
|
17
|
+
else
|
18
|
+
thing
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -1,3 +1,6 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
require 'pact_broker/client/environments/create_environment'
|
2
|
+
require 'pact_broker/client/environments/delete_environment'
|
3
|
+
require 'pact_broker/client/environments/describe_environment'
|
4
|
+
require 'pact_broker/client/environments/list_environments'
|
5
|
+
require 'pact_broker/client/environments/update_environment'
|
6
|
+
|
@@ -1,12 +1,10 @@
|
|
1
1
|
require 'pact_broker/client/environments/environment_command'
|
2
|
-
require 'pact_broker/client/
|
3
|
-
require 'yaml'
|
2
|
+
require 'pact_broker/client/describe_text_formatter'
|
4
3
|
|
5
4
|
module PactBroker
|
6
5
|
module Client
|
7
6
|
module Environments
|
8
7
|
class DescribeEnvironment < PactBroker::Client::Environments::EnvironmentCommand
|
9
|
-
include PactBroker::Client::GenerateDisplayName
|
10
8
|
private
|
11
9
|
|
12
10
|
def do_call
|
@@ -18,16 +16,8 @@ module PactBroker
|
|
18
16
|
if json_output?
|
19
17
|
existing_environment_resource.response.raw_body
|
20
18
|
else
|
21
|
-
|
22
|
-
|
23
|
-
end
|
24
|
-
|
25
|
-
def displayify_keys(thing)
|
26
|
-
case thing
|
27
|
-
when Hash then thing.each_with_object({}) { | (key, value), new_hash | new_hash[generate_display_name(key)] = displayify_keys(value) }
|
28
|
-
when Array then thing.collect{ | value | displayify_keys(value) }
|
29
|
-
else
|
30
|
-
thing
|
19
|
+
properties = existing_environment_resource.response.body.except("_links", "_embedded")
|
20
|
+
PactBroker::Client::DescribeTextFormatter.call(properties)
|
31
21
|
end
|
32
22
|
end
|
33
23
|
end
|
@@ -165,14 +165,17 @@ module PactBroker
|
|
165
165
|
false
|
166
166
|
end
|
167
167
|
|
168
|
-
def
|
168
|
+
def error_message(messages = {})
|
169
169
|
default_message = "Error making request to #{@href} status=#{response ? response.status: nil} #{response ? response.raw_body : ''}".strip
|
170
170
|
message = if response && messages[response.status]
|
171
171
|
(messages[response.status] || "") + " (#{default_message})"
|
172
172
|
else
|
173
173
|
default_message
|
174
174
|
end
|
175
|
-
|
175
|
+
end
|
176
|
+
|
177
|
+
def assert_success!(messages = {})
|
178
|
+
raise ErrorResponseReturned.new(error_message(messages), self)
|
176
179
|
end
|
177
180
|
end
|
178
181
|
end
|