pact_broker-client 1.64.0 → 1.66.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '097964adbb5c79d708b5a0a8b74ddef396ad05b5909583dbf07b1857abcca5f1'
4
- data.tar.gz: 2f60b1fb9258157889dd6217db2e17ea338903469daec14eb5e3760d90b11cc1
3
+ metadata.gz: 4264ac61f86c48d574c045f51849e4e02d4ee0238b3561c19d8ae331991d4410
4
+ data.tar.gz: 78c60a7b425e70a095a1a70fe2ed369ed472f6192dfceb172448d15969ae1e0a
5
5
  SHA512:
6
- metadata.gz: 67d01a72a39969f0b9a5aba16119a033cf3961a41f4cdaa1f49a286ac5c3376a3d7b77c74da90159e87e29827c4fcfdab4328949a9c24c51ed8e51301417ca19
7
- data.tar.gz: 61e4a0ac04368ebdc4d5aea5f1bfeac3d39440cecdcab4df690f6ea3b86ae2fd277e49191d58189e97c6b1c0918d8336471402c63afc2d62778dfd455cc44efa
6
+ metadata.gz: a36a0807c6bc5d8e5132a1423d5e7ac6cb5a0da6cc99209f368621f19b8dbb86d66746092152ea3686c1988ac7b995c111a390ca65f8a9cefb30479c1cbb6c6e
7
+ data.tar.gz: 9aa5aa0598056bc73418c1f4d29c2f5556ffe33bece67b7686abda0c5ec135cbb888e02019b918b8867b8bd17dbb263e4576f0ceca25698df956091f2b9b3470
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.7
data/CHANGELOG.md CHANGED
@@ -1,3 +1,27 @@
1
+ <a name="v1.66.0"></a>
2
+ ### v1.66.0 (2022-12-01)
3
+
4
+ #### Features
5
+
6
+ * **can-i-deploy**
7
+ * support specifying --ignore using the environment variable PACT_BROKER_CAN_I_DEPLOY_IGNORE ([04a0894](/../../commit/04a0894))
8
+
9
+ * refactor can-i-deploy to use HAL Client instead of HTTParty ([d21efe6](/../../commit/d21efe6))
10
+
11
+ #### Bug Fixes
12
+
13
+ * found the missing computer arm when computer says no (#120) ([7b8ea24](/../../commit/7b8ea24))
14
+
15
+ * **publish-provider-contract**
16
+ * raise validation error when pact broker base URL is missing or blank ([2d719c3](/../../commit/2d719c3))
17
+
18
+ <a name="v1.65.0"></a>
19
+ ### v1.65.0 (2022-06-24)
20
+
21
+ #### Features
22
+
23
+ * add support for automatically detecting the git commit and branch for Azure DevOps ([889f83f](/../../commit/889f83f))
24
+
1
25
  <a name="v1.64.0"></a>
2
26
  ### v1.64.0 (2022-05-27)
3
27
 
data/README.md CHANGED
@@ -60,13 +60,17 @@ Options:
60
60
  # Repository branch of the consumer version
61
61
  [--auto-detect-version-properties], [--no-auto-detect-version-properties]
62
62
  # Automatically detect the repository branch from known CI
63
- environment variables or git CLI.
63
+ environment variables or git CLI. Supports Buildkite, Circle
64
+ CI, Travis CI, GitHub Actions, Jenkins, Hudson, AppVeyor,
65
+ GitLab, CodeShip, Bitbucket and Azure DevOps.
64
66
  -t, [--tag=TAG]
65
67
  # Tag name for consumer version. Can be specified multiple
66
68
  times.
67
69
  -g, [--tag-with-git-branch], [--no-tag-with-git-branch]
68
70
  # Tag consumer version with the name of the current git branch.
69
- Default: false
71
+ Supports Buildkite, Circle CI, Travis CI, GitHub Actions,
72
+ Jenkins, Hudson, AppVeyor, GitLab, CodeShip, Bitbucket and
73
+ Azure DevOps. Default: false
70
74
  [--build-url=BUILD_URL]
71
75
  # The build URL that created the pact
72
76
  [--merge], [--no-merge]
@@ -130,7 +134,7 @@ Options:
130
134
  # The display name of the environment
131
135
  [--production], [--no-production]
132
136
  # Whether or not this environment is a production environment.
133
- Default: false
137
+ This is currently informational only. Default: false
134
138
  [--contact-name=CONTACT_NAME]
135
139
  # The name of the team/person responsible for this environment
136
140
  [--contact-email-address=CONTACT_EMAIL_ADDRESS]
@@ -169,7 +173,7 @@ Options:
169
173
  # The display name of the environment
170
174
  [--production], [--no-production]
171
175
  # Whether or not this environment is a production environment.
172
- Default: false
176
+ This is currently informational only. Default: false
173
177
  [--contact-name=CONTACT_NAME]
174
178
  # The name of the team/person responsible for this environment
175
179
  [--contact-email-address=CONTACT_EMAIL_ADDRESS]
@@ -433,7 +437,10 @@ Options:
433
437
  [--ignore=IGNORE]
434
438
  # The pacticipant name to ignore. Use once for each pacticipant
435
439
  being ignored. A specific version can be ignored by also
436
- specifying a --version after the pacticipant name option.
440
+ specifying a --version after the pacticipant name option. The
441
+ environment variable PACT_BROKER_CAN_I_DEPLOY_IGNORE may also
442
+ be used to specify a pacticipant name to ignore, with commas to
443
+ separate multiple pacticipant names if necessary.
437
444
  -l, [--latest=[TAG]]
438
445
  # Use the latest pacticipant version. Optionally specify a TAG
439
446
  to use the latest version with the specified tag.
@@ -868,7 +875,7 @@ Options:
868
875
 
869
876
  Generate a UUID for use when calling create-or-update-webhook
870
877
 
871
- ### Provider contracts
878
+ ### Provider contracts (Pactflow only)
872
879
 
873
880
  #### publish-provider-contract
874
881
 
@@ -895,7 +902,7 @@ Options:
895
902
  # Whether or not the self verification passed successfully.
896
903
  [--verification-exit-code=N]
897
904
  # The exit code of the verification process. Can be used instead
898
- of --verificaiton-success|--no-verification-success for a
905
+ of --verification-success|--no-verification-success for a
899
906
  simpler build script.
900
907
  [--verification-results=VERIFICATION_RESULTS]
901
908
  # The path to the file containing the output from the
@@ -4,6 +4,7 @@ require 'pact_broker/client/retry'
4
4
  require 'pact_broker/client/matrix/formatter'
5
5
  require 'term/ansicolor'
6
6
  require 'pact_broker/client/colorize_notices'
7
+ require "pact_broker/client/matrix/query"
7
8
 
8
9
  module PactBroker
9
10
  module Client
@@ -18,12 +19,11 @@ module PactBroker
18
19
  end
19
20
  end
20
21
 
21
- def self.call(pact_broker_base_url, version_selectors, matrix_options, options, pact_broker_client_options={})
22
- new(pact_broker_base_url, version_selectors, matrix_options, options, pact_broker_client_options).call
22
+ def self.call(version_selectors, matrix_options, options, pact_broker_client_options={})
23
+ new(version_selectors, matrix_options, options, pact_broker_client_options).call
23
24
  end
24
25
 
25
- def initialize(pact_broker_base_url, version_selectors, matrix_options, options, pact_broker_client_options)
26
- @pact_broker_base_url = pact_broker_base_url
26
+ def initialize(version_selectors, matrix_options, options, pact_broker_client_options)
27
27
  @version_selectors = version_selectors
28
28
  @matrix_options = matrix_options
29
29
  @options = options
@@ -32,15 +32,13 @@ module PactBroker
32
32
 
33
33
  def call
34
34
  create_result(fetch_matrix_with_retries)
35
- rescue PactBroker::Client::Error => e
36
- Result.new(dry_run_or_false, for_dry_run(Term::ANSIColor.red(e.message)))
37
35
  rescue StandardError => e
38
36
  Result.new(dry_run_or_false, for_dry_run(Term::ANSIColor.red("Error retrieving matrix. #{e.class} - #{e.message}") + "\n#{e.backtrace.join("\n")}"))
39
37
  end
40
38
 
41
39
  private
42
40
 
43
- attr_reader :pact_broker_base_url, :version_selectors, :matrix_options, :options, :pact_broker_client_options
41
+ attr_reader :version_selectors, :matrix_options, :options, :pact_broker_client_options
44
42
 
45
43
  def create_result(matrix)
46
44
  if matrix.deployable?
@@ -79,7 +77,7 @@ module PactBroker
79
77
  if dry_run?
80
78
  "Computer says no ¯\\_(ツ)_/¯ (but you're ignoring this by enabling dry run)"
81
79
  else
82
- Term::ANSIColor.red("Computer says no ¯\_(ツ)_/¯")
80
+ Term::ANSIColor.red("Computer says no ¯\\_(ツ)_/¯")
83
81
  end
84
82
  end
85
83
  end
@@ -106,7 +104,7 @@ module PactBroker
106
104
  end
107
105
 
108
106
  def fetch_matrix
109
- Retry.while_error { pact_broker_client.matrix.get(version_selectors, matrix_options) }
107
+ Retry.while_error { PactBroker::Client::Matrix::Query.call({ selectors: version_selectors, matrix_options: matrix_options }, options, pact_broker_client_options) }
110
108
  end
111
109
 
112
110
  def fetch_matrix_with_retries
@@ -124,10 +122,6 @@ module PactBroker
124
122
  matrix
125
123
  end
126
124
 
127
- def pact_broker_client
128
- @pact_broker_client ||= PactBroker::Client::PactBrokerClient.new(base_url: pact_broker_base_url, client_options: pact_broker_client_options)
129
- end
130
-
131
125
  def retry_while_unknown?
132
126
  options[:retry_while_unknown] > 0
133
127
  end
@@ -9,7 +9,7 @@ module PactBroker
9
9
  def self.shared_environment_options(name_required: false)
10
10
  method_option :name, required: name_required, desc: "The uniquely identifying name of the environment as used in deployment code"
11
11
  method_option :display_name, desc: "The display name of the environment"
12
- method_option :production, type: :boolean, default: false, desc: "Whether or not this environment is a production environment. Default: false"
12
+ method_option :production, type: :boolean, default: false, desc: "Whether or not this environment is a production environment. This is currently informational only. Default: false"
13
13
  method_option :contact_name, required: false, desc: "The name of the team/person responsible for this environment"
14
14
  method_option :contact_email_address, required: false, desc: "The email address of the team/person responsible for this environment"
15
15
  output_option_json_or_text
@@ -2,15 +2,15 @@ module PactBroker
2
2
  module Client
3
3
  module CLI
4
4
  module MatrixCommands
5
-
6
5
  def self.included(thor)
7
6
  thor.class_eval do
7
+
8
8
  desc "can-i-deploy", ""
9
9
  long_desc File.read(File.join(__dir__, "can_i_deploy_long_desc.txt"))
10
10
 
11
11
  method_option :pacticipant, required: true, aliases: "-a", desc: "The pacticipant name. Use once for each pacticipant being checked."
12
12
  method_option :version, required: false, aliases: "-e", desc: "The pacticipant version. Must be entered after the --pacticipant that it relates to."
13
- method_option :ignore, required: false, desc: "The pacticipant name to ignore. Use once for each pacticipant being ignored. A specific version can be ignored by also specifying a --version after the pacticipant name option."
13
+ method_option :ignore, required: false, desc: "The pacticipant name to ignore. Use once for each pacticipant being ignored. A specific version can be ignored by also specifying a --version after the pacticipant name option. The environment variable PACT_BROKER_CAN_I_DEPLOY_IGNORE may also be used to specify a pacticipant name to ignore, with commas to separate multiple pacticipant names if necessary."
14
14
  method_option :latest, required: false, aliases: "-l", banner: "[TAG]", desc: "Use the latest pacticipant version. Optionally specify a TAG to use the latest version with the specified tag."
15
15
  method_option :to_environment, required: false, banner: "ENVIRONMENT", desc: "The environment into which the pacticipant(s) are to be deployed", default: nil
16
16
  method_option :branch, required: false, desc: "The branch of the version for which you want to check the verification results", default: nil
@@ -29,11 +29,11 @@ module PactBroker
29
29
 
30
30
  validate_credentials
31
31
  selectors = VersionSelectorOptionsParser.call(ARGV).select { |s| !s[:ignore] }
32
- ignore_selectors = VersionSelectorOptionsParser.call(ARGV).select { |s| s[:ignore] }
32
+ ignore_selectors = VersionSelectorOptionsParser.call(ARGV).select { |s| s[:ignore] } + ignore_selectors_from_environment_variable
33
33
  validate_can_i_deploy_selectors(selectors)
34
34
  dry_run = options.dry_run || ENV["PACT_BROKER_CAN_I_DEPLOY_DRY_RUN"] == "true"
35
35
  can_i_deploy_options = { output: options.output, retry_while_unknown: options.retry_while_unknown, retry_interval: options.retry_interval, dry_run: dry_run, verbose: options.verbose }
36
- result = CanIDeploy.call(options.broker_base_url, selectors, { to_tag: options.to, to_environment: options.to_environment, limit: options.limit, ignore_selectors: ignore_selectors }, can_i_deploy_options, pact_broker_client_options)
36
+ result = CanIDeploy.call(selectors, { to_tag: options.to, to_environment: options.to_environment, limit: options.limit, ignore_selectors: ignore_selectors }, can_i_deploy_options, pact_broker_client_options)
37
37
  $stdout.puts result.message
38
38
  $stdout.flush
39
39
  exit(can_i_deploy_exit_status) unless result.success
@@ -81,6 +81,10 @@ module PactBroker
81
81
  pacticipants_without_versions = selectors.select{ |s| s[:version].nil? && s[:latest].nil? && s[:tag].nil? && s[:branch].nil? }.collect{ |s| s[:pacticipant] }
82
82
  raise ::Thor::RequiredArgumentMissingError, "The version must be specified using `--version VERSION`, `--branch BRANCH` `--latest`, `--latest TAG`, or `--all TAG` for pacticipant #{pacticipants_without_versions.join(", ")}" if pacticipants_without_versions.any?
83
83
  end
84
+
85
+ def ignore_selectors_from_environment_variable
86
+ ENV.fetch("PACT_BROKER_CAN_I_DEPLOY_IGNORE", "").split(",").collect(&:strip).collect{ |i| { pacticipant: i } }
87
+ end
84
88
  end
85
89
  end
86
90
  end
@@ -14,9 +14,9 @@ module PactBroker
14
14
  desc 'publish PACT_DIRS_OR_FILES ...', "Publish pacts to a Pact Broker."
15
15
  method_option :consumer_app_version, required: true, aliases: "-a", desc: "The consumer application version"
16
16
  method_option :branch, aliases: "-h", desc: "Repository branch of the consumer version"
17
- method_option :auto_detect_version_properties, hidden: true, type: :boolean, default: false, desc: "Automatically detect the repository branch from known CI environment variables or git CLI."
17
+ method_option :auto_detect_version_properties, type: :boolean, default: false, desc: "Automatically detect the repository branch from known CI environment variables or git CLI. Supports Buildkite, Circle CI, Travis CI, GitHub Actions, Jenkins, Hudson, AppVeyor, GitLab, CodeShip, Bitbucket and Azure DevOps."
18
18
  method_option :tag, aliases: "-t", type: :array, banner: "TAG", desc: "Tag name for consumer version. Can be specified multiple times."
19
- method_option :tag_with_git_branch, aliases: "-g", type: :boolean, default: false, required: false, desc: "Tag consumer version with the name of the current git branch. Default: false"
19
+ method_option :tag_with_git_branch, aliases: "-g", type: :boolean, default: false, required: false, desc: "Tag consumer version with the name of the current git branch. Supports Buildkite, Circle CI, Travis CI, GitHub Actions, Jenkins, Hudson, AppVeyor, GitLab, CodeShip, Bitbucket and Azure DevOps. Default: false"
20
20
  method_option :build_url, desc: "The build URL that created the pact"
21
21
  method_option :merge, type: :boolean, default: false, require: false, desc: "If a pact already exists for this consumer version and provider, merge the contents. Useful when running Pact tests concurrently on different build nodes."
22
22
  output_option_json_or_text
@@ -38,10 +38,9 @@ module PactBroker
38
38
  run_webhook_commands webhook_url
39
39
  end
40
40
 
41
+ desc 'create-or-update-webhook URL', 'Creates or updates a webhook with a provided uuid and using the same switches as a curl request.'
41
42
  shared_options_for_webhook_commands
42
43
  method_option :uuid, type: :string, required: true, desc: "Specify the uuid for the webhook"
43
-
44
- desc 'create-or-update-webhook URL', 'Creates or updates a webhook with a provided uuid and using the same switches as a curl request.'
45
44
  long_desc File.read(File.join(File.dirname(__FILE__), 'create_or_update_webhook_long_desc.txt'))
46
45
  def create_or_update_webhook webhook_url
47
46
  run_webhook_commands webhook_url
@@ -13,7 +13,7 @@ CI_COMMIT_REF_NAME https://docs.gitlab.com/ee/ci/variables/predefined_variables.
13
13
  CI_BRANCH CI_COMMIT_ID https://documentation.codeship.com/pro/builds-and-configuration/environment-variables/
14
14
  bamboo.repository.git.branch https://confluence.atlassian.com/bamboo/bamboo-variables-289277087.html
15
15
  BITBUCKET_BRANCH BITBUCKET_COMMIT https://confluence.atlassian.com/bitbucket/variables-in-pipelines-794502608.html
16
-
16
+ BUILD_SOURCEBRANCHNAME BUILD_SOURCEVERSION Azure
17
17
  =end
18
18
 
19
19
  # Keep in sync with pact-provider-verifier/lib/pact/provider_verifier/git.rb
@@ -25,8 +25,8 @@ module PactBroker
25
25
  using PactBroker::Client::HashRefinements
26
26
 
27
27
  COMMAND = 'git rev-parse --abbrev-ref HEAD'.freeze
28
- BRANCH_ENV_VAR_NAMES = %w{GITHUB_HEAD_REF GITHUB_REF BUILDKITE_BRANCH CIRCLE_BRANCH TRAVIS_BRANCH GIT_BRANCH GIT_LOCAL_BRANCH APPVEYOR_REPO_BRANCH CI_COMMIT_REF_NAME BITBUCKET_BRANCH}.freeze
29
- COMMIT_ENV_VAR_NAMES = %w{GITHUB_SHA BUILDKITE_COMMIT CIRCLE_SHA1 TRAVIS_COMMIT GIT_COMMIT APPVEYOR_REPO_COMMIT CI_COMMIT_ID BITBUCKET_COMMIT}
28
+ BRANCH_ENV_VAR_NAMES = %w{GITHUB_HEAD_REF GITHUB_REF BUILDKITE_BRANCH CIRCLE_BRANCH TRAVIS_BRANCH GIT_BRANCH GIT_LOCAL_BRANCH APPVEYOR_REPO_BRANCH CI_COMMIT_REF_NAME BITBUCKET_BRANCH BUILD_SOURCEBRANCHNAME}.freeze
29
+ COMMIT_ENV_VAR_NAMES = %w{GITHUB_SHA BUILDKITE_COMMIT CIRCLE_SHA1 TRAVIS_COMMIT GIT_COMMIT APPVEYOR_REPO_COMMIT CI_COMMIT_ID BITBUCKET_COMMIT BUILD_SOURCEVERSION}
30
30
  BUILD_URL_ENV_VAR_NAMES = %w{BUILDKITE_BUILD_URL CIRCLE_BUILD_URL TRAVIS_BUILD_WEB_URL BUILD_URL }
31
31
 
32
32
  def self.commit
@@ -19,7 +19,7 @@ module PactBroker
19
19
  end
20
20
 
21
21
  def get href, params = {}, headers = {}
22
- query = params.collect{ |(key, value)| "#{CGI::escape(key.to_s)}=#{CGI::escape(value.to_s)}" }.join("&")
22
+ query = build_nested_query(params)
23
23
  uri = URI(href)
24
24
  uri.query = query
25
25
  perform_request(create_request(uri, 'Get', nil, headers), uri)
@@ -130,6 +130,29 @@ module PactBroker
130
130
  ENV['PACT_DISABLE_SSL_VERIFICATION'] == 'true' || ENV['PACT_BROKER_DISABLE_SSL_VERIFICATION'] == 'true'
131
131
  end
132
132
 
133
+ # From Rack lib/rack/utils.rb
134
+ def build_nested_query(value, prefix = nil)
135
+ case value
136
+ when Array
137
+ value.map { |v|
138
+ build_nested_query(v, "#{prefix}[]")
139
+ }.join("&")
140
+ when Hash
141
+ value.map { |k, v|
142
+ build_nested_query(v, prefix ? "#{prefix}[#{escape(k)}]" : escape(k))
143
+ }.delete_if(&:empty?).join('&')
144
+ when nil
145
+ prefix
146
+ else
147
+ raise ArgumentError, "value must be a Hash" if prefix.nil?
148
+ "#{prefix}=#{escape(value)}"
149
+ end
150
+ end
151
+
152
+ def escape(s)
153
+ URI.encode_www_form_component(s)
154
+ end
155
+
133
156
  class Response < SimpleDelegator
134
157
  def body
135
158
  bod = raw_body
@@ -0,0 +1,77 @@
1
+ require 'pact_broker/client/base_command'
2
+ require "pact_broker/client/matrix/resource"
3
+ require "pact_broker/client/matrix"
4
+
5
+ module PactBroker
6
+ module Client
7
+ class Matrix < BaseClient
8
+ class Query < PactBroker::Client::BaseCommand
9
+
10
+ def call
11
+ matrix_entity = create_entry_point("#{pact_broker_client_options[:pact_broker_base_url]}/matrix", pact_broker_client_options).get!(query_params)
12
+ Matrix::Resource.new(JSON.parse(matrix_entity.response.raw_body, symbolize_names: true))
13
+ end
14
+
15
+ private
16
+
17
+ attr_reader :action, :response_entity
18
+
19
+
20
+ def selectors
21
+ params[:selectors]
22
+ end
23
+
24
+ def matrix_options
25
+ @matrix_options ||= params[:matrix_options] ||{}
26
+ end
27
+
28
+ def query_params
29
+ latestby = selectors.size == 1 ? 'cvp' : 'cvpv'
30
+ query = {
31
+ q: convert_selector_hashes_to_params(selectors),
32
+ latestby: latestby
33
+ }.merge(query_options)
34
+ end
35
+
36
+ def query_options
37
+ opts = {}
38
+ if matrix_options.key?(:success)
39
+ opts[:success] = [*matrix_options[:success]]
40
+ end
41
+ opts[:limit] = matrix_options[:limit] if matrix_options[:limit]
42
+ opts[:environment] = matrix_options[:to_environment] if matrix_options[:to_environment]
43
+ if matrix_options[:to_tag]
44
+ opts[:latest] = 'true'
45
+ opts[:tag] = matrix_options[:to_tag]
46
+ elsif selectors.size == 1 && !matrix_options[:to_environment]
47
+ opts[:latest] = 'true'
48
+ end
49
+ if matrix_options[:ignore_selectors] && matrix_options[:ignore_selectors].any?
50
+ opts[:ignore] = convert_selector_hashes_to_params(matrix_options[:ignore_selectors])
51
+ end
52
+ opts
53
+ end
54
+
55
+ def convert_selector_hashes_to_params(selectors)
56
+ selectors.collect do |selector|
57
+ { pacticipant: selector[:pacticipant] }.tap do | hash |
58
+ hash[:version] = selector[:version] if selector[:version]
59
+ hash[:latest] = 'true' if selector[:latest]
60
+ hash[:tag] = selector[:tag] if selector[:tag]
61
+ hash[:branch] = selector[:branch] if selector[:branch]
62
+ end
63
+ end
64
+ end
65
+
66
+
67
+ def result_message
68
+ if json_output?
69
+ response_entity.response.raw_body
70
+ else
71
+ green("Pacticipant \"#{params[:name]}\" #{action} in #{pact_broker_name}")
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
@@ -5,6 +5,10 @@ module PactBroker
5
5
  def blank?
6
6
  true
7
7
  end
8
+
9
+ def not_blank?
10
+ false
11
+ end
8
12
  end
9
13
 
10
14
  refine String do
@@ -1,5 +1,5 @@
1
1
  module PactBroker
2
2
  module Client
3
- VERSION = '1.64.0'
3
+ VERSION = '1.66.0'
4
4
  end
5
5
  end
@@ -1,10 +1,12 @@
1
1
  require "pact_broker/client/hash_refinements"
2
+ require "pact_broker/client/string_refinements"
2
3
 
3
4
  module Pactflow
4
5
  module Client
5
6
  module CLI
6
7
  module ProviderContractCommands
7
8
  using PactBroker::Client::HashRefinements
9
+ using PactBroker::Client::StringRefinements
8
10
 
9
11
  def self.included(thor)
10
12
  thor.class_eval do
@@ -18,7 +20,7 @@ module Pactflow
18
20
  method_option :specification, default: "oas", desc: "The contract specification"
19
21
  method_option :content_type, desc: "The content type. eg. application/yml"
20
22
  method_option :verification_success, type: :boolean, desc: "Whether or not the self verification passed successfully."
21
- method_option :verification_exit_code, type: :numeric, desc: "The exit code of the verification process. Can be used instead of --verificaiton-success|--no-verification-success for a simpler build script."
23
+ method_option :verification_exit_code, type: :numeric, desc: "The exit code of the verification process. Can be used instead of --verification-success|--no-verification-success for a simpler build script."
22
24
  method_option :verification_results, desc: "The path to the file containing the output from the verification process"
23
25
  method_option :verification_results_content_type, desc: "The content type of the verification output eg. text/plain, application/yaml"
24
26
  method_option :verification_results_format, desc: "The format of the verification output eg. junit, text"
@@ -32,6 +34,7 @@ module Pactflow
32
34
  def publish_provider_contract(provider_contract_path)
33
35
  require "pactflow/client/provider_contracts/publish"
34
36
 
37
+ validate_pact_broker_url
35
38
  validate_publish_provider_contract_options(provider_contract_path)
36
39
  result = ::Pactflow::Client::ProviderContracts::Publish.call(
37
40
  publish_provider_contract_command_params(provider_contract_path),
@@ -47,6 +50,12 @@ module Pactflow
47
50
  { verbose: options.verbose, output: options.output }
48
51
  end
49
52
 
53
+ def validate_pact_broker_url
54
+ if pact_broker_client_options[:pact_broker_base_url].blank?
55
+ raise Thor::Error, "No value provided for required option --broker-base-url or environment variable PACT_BROKER_BASE_URL"
56
+ end
57
+ end
58
+
50
59
  def validate_publish_provider_contract_options(provider_contract_path)
51
60
  if !options.verification_success.nil? && options.verification_exit_code
52
61
  raise Thor::Error, "Cannot use both --verification-success|--no-verification-success and --verification-exit-code"
@@ -7,7 +7,7 @@ module PactBroker
7
7
  let(:pact_broker_base_url) { 'http://example.org' }
8
8
  let(:version_selectors) { [{ pacticipant: "Foo", version: "1" }] }
9
9
  let(:matrix_options) { { } }
10
- let(:pact_broker_client_options) { { foo: 'bar' } }
10
+ let(:pact_broker_client_options) { { pact_broker_base_url: pact_broker_base_url, foo: 'bar' } }
11
11
  let(:dry_run) { false }
12
12
  let(:matrix_client) { instance_double('PactBroker::Client::Matrix') }
13
13
  let(:matrix) do
@@ -31,15 +31,14 @@ module PactBroker
31
31
 
32
32
 
33
33
  before do
34
- allow_any_instance_of(PactBroker::Client::PactBrokerClient).to receive(:matrix).and_return(matrix_client)
35
- allow(matrix_client).to receive(:get).and_return(matrix)
34
+ allow(PactBroker::Client::Matrix::Query).to receive(:call).and_return(matrix)
36
35
  allow(Matrix::Formatter).to receive(:call).and_return('text matrix')
37
36
  end
38
37
 
39
- subject { CanIDeploy.call(pact_broker_base_url, version_selectors, matrix_options, options, pact_broker_client_options) }
38
+ subject { CanIDeploy.call(version_selectors, matrix_options, options, pact_broker_client_options) }
40
39
 
41
40
  it "retrieves the matrix from the pact broker" do
42
- expect(matrix_client).to receive(:get).with(version_selectors, matrix_options)
41
+ expect(PactBroker::Client::Matrix::Query).to receive(:call).with({ selectors: version_selectors, matrix_options: matrix_options }, options, pact_broker_client_options)
43
42
  subject
44
43
  end
45
44
 
@@ -193,7 +192,7 @@ module PactBroker
193
192
 
194
193
  context "when a PactBroker::Client::Error is raised" do
195
194
  before do
196
- allow(matrix_client).to receive(:get).and_raise(PactBroker::Client::Error.new('error text'))
195
+ allow(PactBroker::Client::Matrix::Query).to receive(:call).and_raise(PactBroker::Client::Error.new('error text'))
197
196
  end
198
197
 
199
198
  it "returns a failure response" do
@@ -222,7 +221,7 @@ module PactBroker
222
221
  before do
223
222
  allow(Retry).to receive(:while_error) { |&block| block.call }
224
223
  allow($stderr).to receive(:puts)
225
- allow(matrix_client).to receive(:get).and_raise(StandardError.new('error text'))
224
+ allow(PactBroker::Client::Matrix::Query).to receive(:call).and_raise(StandardError.new('error text'))
226
225
  end
227
226
 
228
227
  it "returns a failure response" do
@@ -38,7 +38,7 @@ module PactBroker
38
38
  end
39
39
 
40
40
  it "invokes the CanIDeploy service" do
41
- 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, dry_run: false, verbose: "verbose"}, { pact_broker_base_url: 'http://pact-broker', verbose: 'verbose' })
41
+ expect(CanIDeploy).to receive(:call).with(version_selectors, { to_tag: nil, to_environment: nil, limit: 1000, ignore_selectors: []}, {output: 'table', retry_while_unknown: 1, retry_interval: 2, dry_run: false, verbose: "verbose"}, { pact_broker_base_url: 'http://pact-broker', verbose: 'verbose' })
42
42
  invoke_can_i_deploy
43
43
  end
44
44
 
@@ -56,7 +56,7 @@ module PactBroker
56
56
  end
57
57
 
58
58
  it "passes the value as the matrix options" do
59
- expect(CanIDeploy).to receive(:call).with(anything, anything, {to_tag: 'prod', to_environment: nil, limit: 1000, ignore_selectors: []}, anything, anything)
59
+ expect(CanIDeploy).to receive(:call).with(anything, {to_tag: 'prod', to_environment: nil, limit: 1000, ignore_selectors: []}, anything, anything)
60
60
  invoke_can_i_deploy
61
61
  end
62
62
  end
@@ -67,7 +67,7 @@ module PactBroker
67
67
  end
68
68
 
69
69
  it "passes the value as the matrix options" do
70
- expect(CanIDeploy).to receive(:call).with(anything, anything, {to_tag: nil, to_environment: 'prod', limit: 1000, ignore_selectors: []}, anything, anything)
70
+ expect(CanIDeploy).to receive(:call).with(anything, {to_tag: nil, to_environment: 'prod', limit: 1000, ignore_selectors: []}, anything, anything)
71
71
  invoke_can_i_deploy
72
72
  end
73
73
  end
@@ -79,7 +79,7 @@ module PactBroker
79
79
  end
80
80
 
81
81
  it "invokes the CanIDeploy service with the basic auth credentials" do
82
- expect(CanIDeploy).to receive(:call).with(anything, anything, anything, anything, { pact_broker_base_url: 'http://pact-broker', basic_auth: {username: "foo", password: "bar"}, verbose: 'verbose'})
82
+ expect(CanIDeploy).to receive(:call).with(anything, anything, anything, { pact_broker_base_url: 'http://pact-broker', basic_auth: {username: "foo", password: "bar"}, verbose: 'verbose'})
83
83
  invoke_can_i_deploy
84
84
  end
85
85
  end
@@ -90,7 +90,7 @@ module PactBroker
90
90
  end
91
91
 
92
92
  it "invokes the CanIDeploy service with the basic auth credentials" do
93
- expect(CanIDeploy).to receive(:call).with(anything, anything, anything, anything, {pact_broker_base_url: 'http://pact-broker', token: "some token", verbose: 'verbose'})
93
+ expect(CanIDeploy).to receive(:call).with(anything, anything, anything, {pact_broker_base_url: 'http://pact-broker', token: "some token", verbose: 'verbose'})
94
94
  invoke_can_i_deploy
95
95
  end
96
96
  end
@@ -102,7 +102,19 @@ module PactBroker
102
102
  end
103
103
 
104
104
  it "invokes the CanIDeploy service with dry_run set to true" do
105
- expect(CanIDeploy).to receive(:call).with(anything, anything, anything, hash_including(dry_run: true), anything)
105
+ expect(CanIDeploy).to receive(:call).with(anything, anything, hash_including(dry_run: true), anything)
106
+ invoke_can_i_deploy
107
+ end
108
+ end
109
+
110
+ context "when PACT_BROKER_CAN_I_DEPLOY_IGNORE=Some Service" do
111
+ before do
112
+ allow(ENV).to receive(:fetch).and_call_original
113
+ allow(ENV).to receive(:fetch).with("PACT_BROKER_CAN_I_DEPLOY_IGNORE", "").and_return("Some Service, Some Other Service")
114
+ end
115
+
116
+ it "invokes the CanIDeploy service with ignore selectors" do
117
+ expect(CanIDeploy).to receive(:call).with(anything, hash_including(ignore_selectors: [ { pacticipant: "Some Service" }, { pacticipant: "Some Other Service" } ]), anything, anything)
106
118
  invoke_can_i_deploy
107
119
  end
108
120
  end
@@ -88,7 +88,7 @@ module PactBroker::Client
88
88
  )
89
89
  end
90
90
 
91
- subject { PactBroker::Client::CanIDeploy.call(broker_base_url, selectors, matrix_options, options, {})}
91
+ subject { PactBroker::Client::CanIDeploy.call(selectors, matrix_options, options, { pact_broker_base_url: broker_base_url })}
92
92
 
93
93
  it 'returns the CLI output' do
94
94
  Approvals.verify(subject.message, :name => "can_i_deploy_ignore", format: :txt)
@@ -1,5 +1,6 @@
1
1
  require_relative 'pact_helper'
2
2
  require 'pact_broker/client'
3
+ require "pact_broker/client/matrix/query"
3
4
 
4
5
  module PactBroker::Client
5
6
  describe Matrix, :pact => true do
@@ -10,6 +11,9 @@ module PactBroker::Client
10
11
  let(:matrix_response_body) { Pact.like(matrix) }
11
12
  let(:matrix) { JSON.parse(File.read('spec/support/matrix.json')) }
12
13
  let(:selectors) { [{ pacticipant: "Foo", version: "1.2.3" }, { pacticipant: "Bar", version: "4.5.6" }] }
14
+ let(:options) { {} }
15
+
16
+ subject { PactBroker::Client::Matrix::Query.call({ selectors: selectors, options: options }, {}, { pact_broker_base_url: pact_broker.mock_service_base_url }) }
13
17
 
14
18
  context "when results are found" do
15
19
  before do
@@ -29,7 +33,7 @@ module PactBroker::Client
29
33
  end
30
34
 
31
35
  it 'returns the pact matrix' do
32
- matrix = pact_broker_client.matrix.get(selectors)
36
+ matrix = subject
33
37
  expect(matrix[:matrix].size).to eq 1
34
38
  end
35
39
  end
@@ -54,7 +58,7 @@ module PactBroker::Client
54
58
  let(:selectors) { [{ pacticipant: "Foo Thing", version: "1.2.3" }, { pacticipant: "Bar", version: "4.5.6" }] }
55
59
 
56
60
  it 'incorrectly escapes the spaces but it still seems to work' do
57
- matrix = pact_broker_client.matrix.get(selectors)
61
+ matrix = subject
58
62
  expect(matrix[:matrix].size).to eq 1
59
63
  end
60
64
  end
@@ -79,7 +83,7 @@ module PactBroker::Client
79
83
  let(:selectors) { [{ pacticipant: "Foo", version: "1.2.3" }] }
80
84
 
81
85
  it 'returns the row with the lastest verification for version 1.2.3' do
82
- matrix = pact_broker_client.matrix.get(selectors)
86
+ matrix = subject
83
87
  expect(matrix[:matrix].size).to eq 1
84
88
  end
85
89
  end
@@ -108,7 +112,7 @@ module PactBroker::Client
108
112
  let(:selectors) { [{ pacticipant: "Foo", version: "1.2.3" }, { pacticipant: "Bar", version: "9.9.9" }] }
109
113
 
110
114
  it 'does not raise an error' do
111
- pact_broker_client.matrix.get(selectors)
115
+ subject
112
116
  end
113
117
  end
114
118
 
@@ -134,8 +138,8 @@ module PactBroker::Client
134
138
 
135
139
  it 'raises an error' do
136
140
  expect {
137
- pact_broker_client.matrix.get(selectors)
138
- }.to raise_error PactBroker::Client::Error, "an error message"
141
+ subject
142
+ }.to raise_error PactBroker::Client::Hal::ErrorResponseReturned, /an error message/
139
143
  end
140
144
  end
141
145
 
@@ -161,7 +165,7 @@ module PactBroker::Client
161
165
  let(:selectors) { [{ pacticipant: "Foo" }, { pacticipant: "Bar" }] }
162
166
 
163
167
  it "returns multiple rows" do
164
- matrix = pact_broker_client.matrix.get(selectors)
168
+ matrix = subject
165
169
  expect(matrix[:matrix].size).to eq 2
166
170
  end
167
171
  end
data/spec/spec_helper.rb CHANGED
@@ -1,6 +1,8 @@
1
1
  require 'webmock/rspec'
2
2
  require 'rspec/its'
3
3
 
4
+ ENV["PACT_BROKER_CAN_I_DEPLOY_IGNORE"] = nil
5
+
4
6
  WebMock.disable_net_connect!(allow_localhost: true)
5
7
 
6
8
  require "./spec/support/shared_context.rb"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pact_broker-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.64.0
4
+ version: 1.66.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Beth Skurrie
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-05-27 00:00:00.000000000 Z
11
+ date: 2022-12-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httparty
@@ -213,6 +213,7 @@ files:
213
213
  - ".github/workflows/trigger_pact_docs_update.yml"
214
214
  - ".gitignore"
215
215
  - ".rspec"
216
+ - ".ruby-version"
216
217
  - CHANGELOG.md
217
218
  - Dockerfile
218
219
  - Gemfile
@@ -286,6 +287,7 @@ files:
286
287
  - lib/pact_broker/client/matrix/abbreviate_version_number.rb
287
288
  - lib/pact_broker/client/matrix/formatter.rb
288
289
  - lib/pact_broker/client/matrix/json_formatter.rb
290
+ - lib/pact_broker/client/matrix/query.rb
289
291
  - lib/pact_broker/client/matrix/resource.rb
290
292
  - lib/pact_broker/client/matrix/text_formatter.rb
291
293
  - lib/pact_broker/client/merge_pacts.rb
@@ -438,7 +440,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
438
440
  - !ruby/object:Gem::Version
439
441
  version: '0'
440
442
  requirements: []
441
- rubygems_version: 3.3.14
443
+ rubygems_version: 3.3.26
442
444
  signing_key:
443
445
  specification_version: 4
444
446
  summary: See description