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.
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