pact_broker-client 1.43.0 → 1.44.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 (39) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test.yml +21 -0
  3. data/CHANGELOG.md +13 -0
  4. data/doc/pacts/markdown/Pact Broker Client - Pact Broker.md +0 -281
  5. data/lib/pact_broker/client/cli/broker.rb +3 -55
  6. data/lib/pact_broker/client/cli/deployment_commands.rb +74 -0
  7. data/lib/pact_broker/client/cli/pacticipant_commands.rb +9 -0
  8. data/lib/pact_broker/client/deployments.rb +4 -0
  9. data/lib/pact_broker/client/deployments/record_deployment.rb +38 -0
  10. data/lib/pact_broker/client/deployments/record_release.rb +99 -0
  11. data/lib/pact_broker/client/deployments/record_undeployment.rb +120 -0
  12. data/lib/pact_broker/client/describe_text_formatter.rb +23 -0
  13. data/lib/pact_broker/client/environments.rb +6 -3
  14. data/lib/pact_broker/client/environments/describe_environment.rb +3 -13
  15. data/lib/pact_broker/client/hal/entity.rb +5 -2
  16. data/lib/pact_broker/client/hal/http_client.rb +3 -2
  17. data/lib/pact_broker/client/pacticipants.rb +3 -3
  18. data/lib/pact_broker/client/pacticipants/create.rb +1 -1
  19. data/lib/pact_broker/client/pacticipants/describe.rb +33 -0
  20. data/lib/pact_broker/client/version.rb +1 -1
  21. data/lib/pact_broker/client/versions.rb +4 -1
  22. data/lib/pact_broker/client/versions/describe.rb +3 -1
  23. data/lib/pact_broker/client/versions/formatter.rb +3 -1
  24. data/lib/pact_broker/client/versions/json_formatter.rb +5 -3
  25. data/lib/pact_broker/client/versions/text_formatter.rb +3 -1
  26. data/script/record-deployments-and-releases.sh +10 -0
  27. data/spec/fixtures/approvals/describe_pacticipant.approved.txt +2 -0
  28. data/spec/integration/describe_environment_spec.rb +31 -0
  29. data/spec/lib/pact_broker/client/deployments/record_deployment_spec.rb +204 -0
  30. data/spec/pacts/pact_broker_client-pact_broker.json +0 -288
  31. data/spec/service_providers/publish_pacts_spec.rb +3 -1
  32. data/spec/service_providers/record_deployment_spec.rb +7 -29
  33. data/spec/service_providers/record_release_spec.rb +135 -0
  34. data/spec/spec_helper.rb +13 -2
  35. data/tasks/pact.rake +19 -1
  36. metadata +18 -6
  37. data/lib/pact_broker/client/versions/record_deployment.rb +0 -85
  38. data/lib/pact_broker/client/versions/record_undeployment.rb +0 -102
  39. 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,4 @@
1
+ require 'pact_broker/client/deployments/record_deployment'
2
+ require 'pact_broker/client/deployments/record_release'
3
+ require 'pact_broker/client/deployments/record_undeployment'
4
+
@@ -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
- Dir.glob(File.join(__FILE__.gsub(".rb", "/**/*.rb"))).sort.each do | path |
2
- require path
3
- end
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/generate_display_name'
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
- YAML.dump(displayify_keys(existing_environment_resource.response.body.except("_links"))).gsub("---\n", "")
22
- end
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 assert_success!(messages = {})
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
- raise ErrorResponseReturned.new(message, self)
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