pact_broker-client 1.71.0 → 1.73.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/release_gem.yml +19 -4
  3. data/.github/workflows/test.yml +5 -5
  4. data/CHANGELOG.md +17 -0
  5. data/DEVELOPING.md +17 -0
  6. data/Gemfile +13 -1
  7. data/README.md +14 -2
  8. data/doc/pacts/markdown/Pact Broker Client - Pact Broker.md +1 -2
  9. data/lib/pact_broker/client/cli/custom_thor.rb +32 -2
  10. data/lib/pact_broker/client/cli/thor_unknown_options_monkey_patch.rb +38 -0
  11. data/lib/pact_broker/client/cli/webhook_commands.rb +1 -1
  12. data/lib/pact_broker/client/hal/http_client.rb +19 -0
  13. data/lib/pact_broker/client/version.rb +1 -1
  14. data/lib/pactflow/client/provider_contracts/publish.rb +3 -3
  15. data/pact-broker-client.gemspec +0 -8
  16. data/script/ci/record-release.sh +7 -0
  17. data/script/publish-pact.sh +1 -1
  18. data/script/update-cli-usage-in-readme.rb +7 -0
  19. data/spec/fixtures/certificates/ca_cert.pem +19 -0
  20. data/spec/fixtures/certificates/ca_cert.srl +1 -0
  21. data/spec/fixtures/certificates/ca_key.pem +28 -0
  22. data/spec/fixtures/certificates/client_cert.pem +17 -0
  23. data/spec/fixtures/certificates/key.pem +28 -0
  24. data/spec/fixtures/certificates/server.csr +15 -0
  25. data/spec/fixtures/certificates/unsigned_cert.pem +19 -0
  26. data/spec/fixtures/certificates/unsigned_key.pem +28 -0
  27. data/spec/integration/publish_provider_contract_spec.rb +0 -4
  28. data/spec/integration/unknown_options_spec.rb +39 -0
  29. data/spec/lib/pact_broker/client/cli/custom_thor_spec.rb +27 -0
  30. data/spec/lib/pact_broker/client/hal/http_client_spec.rb +76 -0
  31. data/spec/lib/pactflow/client/provider_contracts/publish_spec.rb +3 -4
  32. data/spec/pacts/pact_broker_client-pact_broker.json +1 -2
  33. data/spec/service_providers/pactflow_publish_provider_contract_spec.rb +0 -2
  34. data/spec/service_providers/publish_pacts_spec.rb +1 -2
  35. data/spec/support/ssl_server.rb +42 -0
  36. metadata +26 -101
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7cab4d53c9ef3be0be8a1bdd732c4e7eefddad4e2bd27591ca06500e5c63a81d
4
- data.tar.gz: 67e2015656535cf37325f9a45d7fca195c1a2fb64e157e6a1485447d76173551
3
+ metadata.gz: bfeaaf44e2dc8a19f90bd55795542da931dec46853371ea5a51955ccb1f3a39f
4
+ data.tar.gz: c9d00e81e65a20bc6f8a0b38c5c2af2c135e05266906f3b7bd45207a8f7e7b07
5
5
  SHA512:
6
- metadata.gz: d70c00647a761e2cf37028514027b4a36ae0159a65145949144cdc2e3026dfdcaef93d3ac8a827bf1ad43e55e0cf8e7dc40a5ad1117e4424fe70054b153334e9
7
- data.tar.gz: 88264d74be62413f138453b54a842eab64b975d3a5f433ffd370993f86afe4ebd2bb79f969f92c3b54b6ac51a641b729515224996d3c154d721e036cdc8d7448
6
+ metadata.gz: 521599522cf724dd5f0f28becbcc7faf2695c45e1050892ae0494573dc220d22427712548d4a1c5395d7caf9d59263405ff4b8158fdc2634ba8416292afc3447
7
+ data.tar.gz: 987e4569edfac0db3e0bc81483b67cee1d73803422e4dea145456dd61dd7afdad2ad632190cba28eb91501069fce9aa6a49b661cb6398be8a865a6dd681a81aa
@@ -10,10 +10,8 @@ jobs:
10
10
  test:
11
11
  runs-on: ubuntu-latest
12
12
  steps:
13
- - uses: actions/checkout@v3
13
+ - uses: actions/checkout@v4
14
14
  - uses: ruby/setup-ruby@v1
15
- with:
16
- ruby-version: '3.2'
17
15
  - run: |
18
16
  gem install bundler -v 2.4
19
17
  bundle install
@@ -28,7 +26,7 @@ jobs:
28
26
  version: ${{ steps.release.outputs.version }}
29
27
  increment: ${{ steps.release.outputs.increment }}
30
28
  steps:
31
- - uses: actions/checkout@v3
29
+ - uses: actions/checkout@v4
32
30
  with:
33
31
  fetch-depth: 0
34
32
  - uses: pact-foundation/release-gem@v0.0.14
@@ -38,6 +36,23 @@ jobs:
38
36
  GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
39
37
  INCREMENT: '${{ github.event.client_payload.increment }}'
40
38
 
39
+ record-release:
40
+ needs: release
41
+ runs-on: ubuntu-latest
42
+ steps:
43
+ - uses: actions/checkout@v4
44
+ - uses: ruby/setup-ruby@v1
45
+ - name: Bundle install
46
+ run: |
47
+ gem install bundler -v 2.4
48
+ bundle config set --local without development test
49
+ bundle install
50
+ - name: Record release
51
+ run: script/ci/record-release.sh
52
+ env:
53
+ PACT_BROKER_BASE_URL: https://pact-foundation.pactflow.io
54
+ PACT_BROKER_TOKEN: ${{ secrets.PACT_BROKER_TOKEN_PACT_FOUNDATION }}
55
+
41
56
  notify-gem-released:
42
57
  needs: release
43
58
  strategy:
@@ -11,7 +11,7 @@ jobs:
11
11
  ruby_version: ["2.7", "3.0", "3.1", "3.2"]
12
12
  os: ["ubuntu-latest","windows-latest","macos-latest"]
13
13
  steps:
14
- - uses: actions/checkout@v3
14
+ - uses: actions/checkout@v4
15
15
  - uses: ruby/setup-ruby@v1
16
16
  with:
17
17
  ruby-version: ${{ matrix.ruby_version }}
@@ -25,7 +25,7 @@ jobs:
25
25
  matrix:
26
26
  feature: [""]
27
27
  steps:
28
- - uses: actions/checkout@v3
28
+ - uses: actions/checkout@v4
29
29
  - uses: ruby/setup-ruby@v1
30
30
  with:
31
31
  ruby-version: "3.2"
@@ -47,11 +47,11 @@ jobs:
47
47
  steps:
48
48
  - run: |
49
49
  docker run --rm \
50
- -e PACT_BROKER_BASE_URL=https://pact-oss.pactflow.io \
50
+ -e PACT_BROKER_BASE_URL=https://pact-foundation.pactflow.io \
51
51
  -e PACT_BROKER_TOKEN \
52
52
  pactfoundation/pact-cli:latest \
53
53
  broker can-i-deploy \
54
54
  --pacticipant "Pact Broker Client" --version ${GITHUB_SHA} \
55
- --pacticipant "Pact Broker" --latest master
55
+ --pacticipant "Pact Broker" --branch master
56
56
  env:
57
- PACT_BROKER_TOKEN: ${{ secrets.PACTFLOW_PACT_OSS_TOKEN }}
57
+ PACT_BROKER_TOKEN: ${{ secrets.PACT_BROKER_TOKEN_PACT_FOUNDATION }}
data/CHANGELOG.md CHANGED
@@ -1,3 +1,20 @@
1
+ <a name="v1.73.0"></a>
2
+ ### v1.73.0 (2023-10-13)
3
+
4
+ #### Features
5
+
6
+ * print warnings and allow error to be raised when unknown option is used ([5412121](/../../commit/5412121))
7
+ * raise an error when an em dash is used instead of a normal dash ([0e8e773](/../../commit/0e8e773))
8
+ * support --help and -h flags ([a6458ab](/../../commit/a6458ab))
9
+ * handle x509 certs in HTTP Client (#142) ([c3aa8dc](/../../commit/c3aa8dc))
10
+
11
+ <a name="v1.72.0"></a>
12
+ ### v1.72.0 (2023-09-11)
13
+
14
+ #### Features
15
+
16
+ * enable publishing provider contracts using the 'all in one' endpoint ([398d58c](/../../commit/398d58c))
17
+
1
18
  <a name="v1.71.0"></a>
2
19
  ### v1.71.0 (2023-09-07)
3
20
 
data/DEVELOPING.md ADDED
@@ -0,0 +1,17 @@
1
+ # Developing
2
+
3
+ ## Testing pact_broker-client locally
4
+
5
+ 1. Make sure you have `ruby` available on the command line
6
+ 2. Install with `bundle install`
7
+ 3. Run tests with `bundle exec rake`
8
+ 4. Run individual test with `rspec <path to test>`
9
+ 5. Run one of the scripts in `./example/scripts`, see the readme for more detail, and scripts
10
+
11
+ ##  Available Rake tasks
12
+
13
+ 1. check `bundle exec rake --tasks`
14
+
15
+ ## Generating docs
16
+
17
+ If you change the CLI commands, run `bundle exec script/update-cli-usage-in-readme.rb` to update the `README.md` automatically.
data/Gemfile CHANGED
@@ -12,5 +12,17 @@ if ENV['X_PACT_DEVELOPMENT'] == 'true'
12
12
  end
13
13
 
14
14
  group :development do
15
+ gem 'fakefs', '~> 2.4'
16
+ gem 'webmock', '~> 3.0'
17
+ gem 'conventional-changelog', '~>1.3'
18
+ gem 'pact', '~> 1.16'
19
+ gem 'pact-support', '~> 1.16'
20
+ gem 'approvals', '0.0.26'
21
+ gem 'rspec-its', '~> 1.3'
15
22
  gem 'pry-byebug'
16
- end
23
+ end
24
+
25
+ group :test do
26
+ gem 'faraday', '~>2.0'
27
+ gem 'faraday-retry', '~>2.0'
28
+ end
data/README.md CHANGED
@@ -42,6 +42,14 @@ Basic auth parameters can be specified using the `$PACT_BROKER_USERNAME` and `$P
42
42
 
43
43
  Authentication using a bearer token can be specified using the environment variable `$PACT_BROKER_TOKEN` or the `-k` or `--broker-token` parameters. This bearer token authentication is used by [PactFlow](https://pactflow.io) and is not available in the [OSS Pact Broker](https://docs.pact.io/pact_broker/), which only supports basic auth.
44
44
 
45
+ ### Handling unknown options
46
+
47
+ By default, the underlying library used for the Pact Broker CLI (Thor) does not raise an error in every situation where there is an unknown option used.
48
+ This can allow invalid commands to be executed that do not perform as expected.
49
+
50
+ From version 1.73.0, warnings will be printed for unknown options, and if the environment variable `PACT_BROKER_ERROR_ON_UNKNOWN_OPTION=true` is set, an error will be raised when an unknown option is used.
51
+
52
+ In the next major version, an error will be raised by default.
45
53
 
46
54
  <!-- start-autogenerated-docs -->
47
55
 
@@ -680,7 +688,9 @@ Options:
680
688
  -H, [--header=one two three]
681
689
  # Webhook Header
682
690
  -d, [--data=DATA]
683
- # Webhook payload (file or string)
691
+ # Webhook payload. Provide a JSON string (remember to escape
692
+ characters appropriately for the shell) or a file path prefixed
693
+ with the @ symbol, as per the curl usage for this flag.
684
694
  -u, [--user=USER]
685
695
  # Webhook basic auth username and password eg. username:password
686
696
  [--consumer=CONSUMER]
@@ -743,7 +753,9 @@ Options:
743
753
  -H, [--header=one two three]
744
754
  # Webhook Header
745
755
  -d, [--data=DATA]
746
- # Webhook payload (file or string)
756
+ # Webhook payload. Provide a JSON string (remember to escape
757
+ characters appropriately for the shell) or a file path prefixed
758
+ with the @ symbol, as per the curl usage for this flag.
747
759
  -u, [--user=USER]
748
760
  # Webhook basic auth username and password eg. username:password
749
761
  [--consumer=CONSUMER]
@@ -2305,8 +2305,7 @@ Pact Broker will respond with:
2305
2305
  "name": "Foo"
2306
2306
  },
2307
2307
  "version": {
2308
- "number": "5556b8149bf8bac76bc30f50a8a2dd4c22c85f30",
2309
- "buildUrl": "http://build"
2308
+ "number": "5556b8149bf8bac76bc30f50a8a2dd4c22c85f30"
2310
2309
  }
2311
2310
  },
2312
2311
  "logs": [
@@ -1,30 +1,41 @@
1
1
  require 'thor'
2
+ require 'pact_broker/client/cli/thor_unknown_options_monkey_patch'
2
3
  require 'pact_broker/client/hash_refinements'
3
4
 
4
5
  module PactBroker
5
6
  module Client
6
7
  module CLI
7
8
  class AuthError < ::Thor::Error; end
8
-
9
9
  ##
10
10
  # Custom Thor task allows the following:
11
11
  #
12
12
  # `--option 1 --option 2` to be interpreted as `--option 1 2` (the standard Thor format for multiple value options)
13
13
  #
14
+
14
15
  class CustomThor < ::Thor
15
16
  using PactBroker::Client::HashRefinements
16
17
 
18
+ EM_DASH = "\u2014"
19
+
20
+ check_unknown_options!
21
+
17
22
  no_commands do
18
23
  def self.exit_on_failure?
19
24
  true
20
25
  end
21
26
 
27
+ # Provide a wrapper method that can be stubbed in tests
28
+ def self.exit_with_error_code
29
+ exit(1)
30
+ end
31
+
22
32
  def self.start given_args = ARGV, config = {}
33
+ check_for_mdash!(given_args)
23
34
  super(massage_args(given_args))
24
35
  end
25
36
 
26
37
  def self.massage_args argv
27
- add_broker_config_from_environment_variables(turn_muliple_tag_options_into_array(argv))
38
+ add_broker_config_from_environment_variables(turn_muliple_tag_options_into_array(handle_help(argv)))
28
39
  end
29
40
 
30
41
  def self.add_broker_config_from_environment_variables argv
@@ -42,6 +53,25 @@ module PactBroker
42
53
  end
43
54
  end
44
55
 
56
+ # Thor expects help to be invoked by typing `help <command>`, which is very odd.
57
+ # Add support for `command --help|-h` by massaging the arguments into the format that Thor expects.
58
+ def self.handle_help(argv)
59
+ if argv.last == "--help" || argv.last == "-h"
60
+ argv[0..-3] + ["help", argv[-2]].compact
61
+ else
62
+ argv
63
+ end
64
+ end
65
+
66
+ def self.check_for_mdash!(argv)
67
+ if (word_with_mdash = argv.find{ |arg | arg.include?(EM_DASH) })
68
+ # Can't use the `raise Thor::Error` approach here (which is designed to show the error without a backtrace)
69
+ # because the exception is not handled within the Thor code, and will show an ugly backtrace.
70
+ $stdout.puts "The argument '#{word_with_mdash}' contains an em dash (the long dash you get in Microsoft Word when you type two short dashes in a row). Please replace it with a normal dash and try again."
71
+ exit_with_error_code
72
+ end
73
+ end
74
+
45
75
  # other task names, help, and the help shortcuts
46
76
  def self.known_first_arguments
47
77
  @known_first_arguments ||= tasks.keys + ::Thor::HELP_MAPPINGS + ['help']
@@ -0,0 +1,38 @@
1
+ require "thor"
2
+ require "term/ansicolor"
3
+
4
+ # Monkey patch Thor so we can print out a warning when there are unknown options, rather than raising an error.
5
+ # If PACT_BROKER_ERROR_ON_UNKNOWN_OPTION=true, raise the error, as the user will have opted in to this behaviour.
6
+ # This is for backwards compatibility reasons, and in the next major version, the flag will be removed.
7
+
8
+ class Thor
9
+ class Options < Arguments
10
+
11
+ alias_method :original_check_unknown!, :check_unknown!
12
+
13
+ # Replace the original check_unknown! method with an implementation
14
+ # that will print a warning rather than raising an error
15
+ # unless PACT_BROKER_ERROR_ON_UNKNOWN_OPTION=true is set.
16
+ def check_unknown!
17
+ if raise_error_on_unknown_options?
18
+ original_check_unknown!
19
+ else
20
+ check_unknown_and_warn
21
+ end
22
+ end
23
+
24
+ def raise_error_on_unknown_options?
25
+ ENV["PACT_BROKER_ERROR_ON_UNKNOWN_OPTION"] == "true"
26
+ end
27
+
28
+ def check_unknown_and_warn
29
+ begin
30
+ original_check_unknown!
31
+ rescue UnknownArgumentError => e
32
+ $stderr.puts(::Term::ANSIColor.yellow(e.message))
33
+ $stderr.puts(::Term::ANSIColor.yellow("This is a warning rather than an error so as not to break backwards compatibility. To raise an error for unknown options set PACT_BROKER_ERROR_ON_UNKNOWN_OPTION=true"))
34
+ $stderr.puts("\n")
35
+ end
36
+ end
37
+ end
38
+ end
@@ -12,7 +12,7 @@ module PactBroker
12
12
  def self.shared_options_for_webhook_commands
13
13
  method_option :request, banner: "METHOD", aliases: "-X", desc: "Webhook HTTP method", required: true
14
14
  method_option :header, aliases: "-H", type: :array, desc: "Webhook Header"
15
- method_option :data, aliases: "-d", desc: "Webhook payload (file or string)"
15
+ method_option :data, aliases: "-d", desc: "Webhook payload. Provide a JSON string (remember to escape characters appropriately for the shell) or a file path prefixed with the @ symbol, as per the curl usage for this flag."
16
16
  method_option :user, aliases: "-u", desc: "Webhook basic auth username and password eg. username:password"
17
17
  method_option :consumer, desc: "Consumer name"
18
18
  method_option :consumer_label, desc: "Consumer label, mutually exclusive with consumer name"
@@ -71,6 +71,12 @@ module PactBroker
71
71
  # See https://github.com/pact-foundation/pact-ruby-standalone/issues/57
72
72
  http.ca_file = ENV['SSL_CERT_FILE'] if ENV['SSL_CERT_FILE'] && ENV['SSL_CERT_FILE'] != ''
73
73
  http.ca_path = ENV['SSL_CERT_DIR'] if ENV['SSL_CERT_DIR'] && ENV['SSL_CERT_DIR'] != ''
74
+
75
+ if x509_certificate?
76
+ http.cert = OpenSSL::X509::Certificate.new(x509_client_cert_file)
77
+ http.key = OpenSSL::PKey::RSA.new(x509_client_key_file)
78
+ end
79
+
74
80
  if disable_ssl_verification?
75
81
  if verbose?
76
82
  $stdout.puts("SSL verification is disabled")
@@ -127,6 +133,19 @@ module PactBroker
127
133
  verbose || ENV["VERBOSE"] == "true"
128
134
  end
129
135
 
136
+ def x509_certificate?
137
+ ENV['X509_CLIENT_CERT_FILE'] && ENV['X509_CLIENT_CERT_FILE'] != '' &&
138
+ ENV['X509_CLIENT_KEY_FILE'] && ENV['X509_CLIENT_KEY_FILE'] != ''
139
+ end
140
+
141
+ def x509_client_cert_file
142
+ File.read(ENV['X509_CLIENT_CERT_FILE'])
143
+ end
144
+
145
+ def x509_client_key_file
146
+ File.read(ENV['X509_CLIENT_KEY_FILE'])
147
+ end
148
+
130
149
  def disable_ssl_verification?
131
150
  ENV['PACT_DISABLE_SSL_VERIFICATION'] == 'true' || ENV['PACT_BROKER_DISABLE_SSL_VERIFICATION'] == 'true'
132
151
  end
@@ -1,5 +1,5 @@
1
1
  module PactBroker
2
2
  module Client
3
- VERSION = '1.71.0'
3
+ VERSION = '1.73.0'
4
4
  end
5
5
  end
@@ -26,7 +26,7 @@ module Pactflow
26
26
  attr_reader :provider_name, :provider_version_number, :branch_name, :tags, :build_url, :contract, :verification_results
27
27
 
28
28
  def do_call
29
- if enabled? && index_resource.assert_success!.can?(PUBLISH_RELATION)
29
+ if !disabled? && index_resource.assert_success!.can?(PUBLISH_RELATION)
30
30
  publish_provider_contracts
31
31
  PactBroker::Client::CommandResult.new(success?, message)
32
32
  else
@@ -34,8 +34,8 @@ module Pactflow
34
34
  end
35
35
  end
36
36
 
37
- def enabled?
38
- ENV.fetch("PACT_BROKER_FEATURES", "").include?("publish_provider_contracts_all_in_one")
37
+ def disabled?
38
+ ENV.fetch("PACTFLOW_FEATURES", "").include?("publish_provider_contracts_using_old_api")
39
39
  end
40
40
 
41
41
  def publish_provider_contracts
@@ -27,12 +27,4 @@ Gem::Specification.new do |gem|
27
27
  gem.add_runtime_dependency 'thor', '>= 0.20', '< 2.0'
28
28
  gem.add_runtime_dependency 'rake', '~> 13.0' #For FileList
29
29
  gem.add_runtime_dependency 'dig_rb', '~> 1.0'
30
-
31
- gem.add_development_dependency 'fakefs', '~> 2.4'
32
- gem.add_development_dependency 'webmock', '~> 3.0'
33
- gem.add_development_dependency 'conventional-changelog', '~>1.3'
34
- gem.add_development_dependency 'pact', '~> 1.16'
35
- gem.add_development_dependency 'pact-support', '~> 1.16'
36
- gem.add_development_dependency 'approvals', '0.0.26'
37
- gem.add_development_dependency 'rspec-its', '~> 1.3'
38
30
  end
@@ -0,0 +1,7 @@
1
+ #!/bin/sh
2
+
3
+ set -eu
4
+
5
+ bundle exec bin/pact-broker record-release \
6
+ --pacticipant "Pact Broker Client" --version $GITHUB_SHA \
7
+ --environment production
@@ -29,7 +29,7 @@ export PACT_BROKER_TOKEN=${PACT_BROKER_TOKEN:-"localhost"}
29
29
  # --contract-published
30
30
 
31
31
 
32
- bundle exec bin/pact-broker publish scripts/foo-bar.json \
32
+ bundle exec bin/pact-broker publish script/foo-bar.json \
33
33
  --consumer-app-version 1.2.26 \
34
34
  --auto-detect-version-properties \
35
35
  --build-url http://mybuild \
@@ -1,4 +1,11 @@
1
1
  #!/usr/bin/env ruby
2
+ require "bundler/inline"
3
+
4
+ gemfile do
5
+ source "https://rubygems.org"
6
+ gem "pact_broker-client", path: "."
7
+ end
8
+
2
9
  require "stringio"
3
10
  require "pact_broker/client/cli/broker"
4
11
  require "pactflow/client/cli/pactflow"
@@ -0,0 +1,19 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDATCCAemgAwIBAgIUWfQF2Mh+eFd3q+cSVgekpaMTh9MwDQYJKoZIhvcNAQEL
3
+ BQAwDzENMAsGA1UEAwwETXlDQTAgFw0yMzA5MTkxMTA2MjZaGA8yMTIzMDgyNjEx
4
+ MDYyNlowDzENMAsGA1UEAwwETXlDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
5
+ AQoCggEBAK9Qha2OdeFrSCUqiYRUBngNLn8PRGDaKPWmjd+3WOWJNM1RNgFfGpKY
6
+ nxYJp4J6eW7aeQ6o94Q+QOZp+Yxm6thrtvjRbcEafAore4EwC4tjXvoFoy+mKwzm
7
+ njlJw+ha3TsMAqD3GGDLF7uDnmliURRo8TOmJ++Mwss9Uhb5p9LArjWXa3sV8da+
8
+ gsxP2aTgBZfznUhNKDGUfezYa5UEbHQ869rA1PAqL3tOC2M5LTX08C2PlzzLOF5S
9
+ gBzicV1PPDkmkbxKmFV+D8LmkwWNsRhrzZ6TIxYoXIRhziS7JuYOGU7G0+6ZKpIP
10
+ mo7WXSoSrd7GL5PQJzlHKCsTckd4so0CAwEAAaNTMFEwHQYDVR0OBBYEFCeovNXs
11
+ r1mcbprFaLyll+LrBJmQMB8GA1UdIwQYMBaAFCeovNXsr1mcbprFaLyll+LrBJmQ
12
+ MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAHOsbZ0iDiKiRU8Q
13
+ hIAav056dboPjTK19Q736DUD6oCbTbvecfxMv/wu9LmYGW5jt/DWP6s+jDYhcPpj
14
+ c3U03pPKCnvsG5z60ZgmNSqzyVAVPW17UVdw/ZnkKK/SFxYgYQaF/1g6opS2Zana
15
+ 4aBGypqqGoD4KE+DAnRjuuCUpiz3zXwGd86auajY6soMlLNnVXteVa/whW6IZ84x
16
+ w4LISeMGUr+MXw9ye4WhcZYKZ4vwJdUYst2PA0pDuGwBDbGnrYloGm2BSpaHXUUo
17
+ XrwKFFkIxcK63IpAhoceTJpyfjI1BSmItfjEwToOUu6xDBsHLNiH6BKstSxk0DfX
18
+ 01PHz2I=
19
+ -----END CERTIFICATE-----
@@ -0,0 +1 @@
1
+ 494F82D5FE5055D2C9C64941C421085B59521071
@@ -0,0 +1,28 @@
1
+ -----BEGIN PRIVATE KEY-----
2
+ MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCvUIWtjnXha0gl
3
+ KomEVAZ4DS5/D0Rg2ij1po3ft1jliTTNUTYBXxqSmJ8WCaeCenlu2nkOqPeEPkDm
4
+ afmMZurYa7b40W3BGnwKK3uBMAuLY176BaMvpisM5p45ScPoWt07DAKg9xhgyxe7
5
+ g55pYlEUaPEzpifvjMLLPVIW+afSwK41l2t7FfHWvoLMT9mk4AWX851ITSgxlH3s
6
+ 2GuVBGx0POvawNTwKi97TgtjOS019PAtj5c8yzheUoAc4nFdTzw5JpG8SphVfg/C
7
+ 5pMFjbEYa82ekyMWKFyEYc4kuybmDhlOxtPumSqSD5qO1l0qEq3exi+T0Cc5Rygr
8
+ E3JHeLKNAgMBAAECggEAF2EHQqWB24V2rIYnVT9DUZUobdyiWMF0aYtEK4uuzjAQ
9
+ RjpzQkGQMJvWc0DnAW5wbTOzUHIrTTZkFJYYp6boiziUwPUPduCfnqznySBCxIbZ
10
+ mUFRNBSBHzT4mq6B8qV+D9bChFFkrdvHlsOu8gzLaouyxsQnWo8MlxU0B55UHrWc
11
+ nqIsPKVBeBtiF7c7eyZtpKmYgmWN8hnPzTZ2rtCL/BS3p2+/O+fFJKuul58Yo4t6
12
+ bmMCPN5C6HxNhB6ADHm3lPVU3ap5g3a/4UHqVJ8c2SGKfAx6C1PgbajxiA74qMLS
13
+ YOhMXzc3jSLmakqvSmVhQFJhFt7drbbGtx4oD3+XPQKBgQDj1k7O2A0yJRQPtvQJ
14
+ A1m+H5fmynMnH6XuQuO8WzqCsDsE786EAG6AzY562SMEQrQ0zgpFx0A9ZmECNaOZ
15
+ 28OnzcA5xGKQh5dD0ou9lvRHXEavu7fYCrAG+wlQTo1eRHUDOAN4pQPoZ9r3bz1M
16
+ tnGtG3rak4KemAsoX8aSy59ZswKBgQDE/C+eu012vzjyr2J1W0Gdms7fh5CWzMp8
17
+ hCHk+kmLCY4DHIaUv0tT3IXGKebRH+PZObE3zZ5Hx2QXPjFQWsyTkd9D2tRIWHaZ
18
+ ZpKPBLxYJJuBc3YWZM1qC2ZcRyvv1NgtNUFpB5xOGIUL3/QsfcOE25kC7Z21aN+e
19
+ uXSi3CkivwKBgGFHSZLLcKbuaehjx0Jp6dFhj+v8mLolqyVV7gKoOQ0/zZNICLcX
20
+ sBbSrXkKaQcSq/q31m8Aqg8NPXJCEL5KtPlawi5oCWWIXy+YIA4s+9PUNGIoFlDq
21
+ D0qLuOhPAdE0DXn4WpMScd6zKSzolBXC+DpfN09IGEc6x9jPO+vFgR49AoGABPiw
22
+ YvsrK1IMJ+PRQlD5SPb9PZr4RTYJ7jaPfG3sqTumf+Gaa+qgBg/MuIGaN7DsWTEh
23
+ jdz8n6cimYuSRwrjmt3VmqrNLL4+0ARMsptV/Yt++TdmxY3puUFsZevN6hGfGxT6
24
+ /6GXikkIIpKWYQETjCjWpcJFdqyc6C6aCPoxd5UCgYEA1B4AdDgxhZgXhz24sKM7
25
+ aX2aY4glBsEZ7dxaqpqvwmsSshvdfudjuFxo5jjMKV2C9JmwrCGML9O6MvSP03n8
26
+ B3R543JqKqWLTaSROHkcoil+LdIV9w7jrMBildOCHSDXwuM8Pl7YObIdKMq4pVwe
27
+ 87n9/ZihlrKGaZ8utMrrGmc=
28
+ -----END PRIVATE KEY-----
@@ -0,0 +1,17 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIICrDCCAZQCFElPgtX+UFXSycZJQcQhCFtZUhBxMA0GCSqGSIb3DQEBCwUAMA8x
3
+ DTALBgNVBAMMBE15Q0EwIBcNMjMwOTE5MTEwNzM1WhgPMjEyMzA4MjYxMTA3MzVa
4
+ MBQxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
5
+ AQoCggEBAJj6DF+bu0DhXmkBaC2+CkoqNlsO+LzW9bZnNCQk0Jw99fgCGTLifU3N
6
+ eyAhKgHs+V3G/9ULbMrxYMSQ/psrrXpS7FM9xtA0WZ0VAg7Oi4WEi+wueE0R1GmO
7
+ NMuCVT2JCYd5uDh8+mrWoVqb9L4xIsy0kaV0Nnl+NX1zDvHXUHzfo3T3roaxRbd6
8
+ N92qNPzrj8TviwbapT0bo4GKwTCOO1ewPFGCjsWEeLZ4p2UfbOzW/zjIBEUD8Kqg
9
+ FOht48y9J6XG3Tb61/7neT0xj6E7cn6hGSzuiIM/oZbtuUt72VDgbLbOrS02oHTz
10
+ YmC9tVL35Qvfgzrqw0DEv7zpm/3iG0sCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEA
11
+ nndLK/t6+dmoAwg4K7pdo8xqUEDnUx8K7sU2whZvLEUM+mO+jWOe3USHjR3aXYnU
12
+ OjNhN90/TAy5wlIK6U2C36nHyZJUeScxuiaVwErwayE+GgwYmw9R7HVofgcVfTve
13
+ IpjyrT7mDOCMYjkHgZv1dSHQTcc6uclaw7SgywEEjxjCNSJCN+WPjxCdcuno0td8
14
+ i7F6FL7FeOiP1mtQrTo42Tq+knerUc55CbTW4anbQfL+6TFEVCPJKduLHFieGB0k
15
+ BFilUR3JD2t8/f4fIilQ6FrMZpUzKcLbgW9cjts8mxq0zNV+z6lISgKbdxZFQp+2
16
+ fvyYdnoNLP0YeRI6j9x1pg==
17
+ -----END CERTIFICATE-----
@@ -0,0 +1,28 @@
1
+ -----BEGIN PRIVATE KEY-----
2
+ MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCY+gxfm7tA4V5p
3
+ AWgtvgpKKjZbDvi81vW2ZzQkJNCcPfX4Ahky4n1NzXsgISoB7Pldxv/VC2zK8WDE
4
+ kP6bK616UuxTPcbQNFmdFQIOzouFhIvsLnhNEdRpjjTLglU9iQmHebg4fPpq1qFa
5
+ m/S+MSLMtJGldDZ5fjV9cw7x11B836N0966GsUW3ejfdqjT864/E74sG2qU9G6OB
6
+ isEwjjtXsDxRgo7FhHi2eKdlH2zs1v84yARFA/CqoBTobePMvSelxt02+tf+53k9
7
+ MY+hO3J+oRks7oiDP6GW7blLe9lQ4Gy2zq0tNqB082JgvbVS9+UL34M66sNAxL+8
8
+ 6Zv94htLAgMBAAECggEAF2l9Z0yANgfH2S478XQ6Qut+8iSycMQ9SrM0yatQufjJ
9
+ ojFABgefwb6G733j3fOUnoOMN+DNv6l9c9f0/26J2ETEomC8ArVgWagTboyx0bdd
10
+ asIZ60GlTppS/ipuPUKx0KgSR6Lo+FzsyN9Bb7I5bzbba4UDqUhli1OGoACh8tpS
11
+ pyhD58C0nWBCYUjgkB2ilVoguQnnTvYC0VDbGOWK1P8bw0to810mkKTyv7ztifW2
12
+ lHUwTe8vbQk7jY52+crvtgVZWNaXEdma3ivDSDHUjK3WLmPw9MFgVSMVYFLDZUQN
13
+ Btd7PyBSkjeHOzoS5b9l4qnjn2vhObpjrT5PZT6TMQKBgQDI+xrzk351kyqezHuZ
14
+ Bqo5CqEN3BHvwKALh3DA3uxHVaLqOo/yALv86yHgue/9ksaxxDwufAnVvcg5eEEh
15
+ XIsZrfKBIaNV5umqJAkbCbx4hVCX9mE45THv3Nc7XhiHuZZpUHb1i7qcab1lly5Y
16
+ 7lFoCd5dCQJUoBf3/9Bw76OjRwKBgQDC2sba56V0dahFxTE3bOIRR2HIYWNfPv0a
17
+ 7ejiNSHVHGTLrEfnya5ZcerT0j6QNA2IQcKw5ovPKn2xgjGlfPWgtBAz55r+lfU2
18
+ +/6CRf8v6tu9FdPs7RDHxBuicOGQlQGSAH2+tfcY9ZCB8wcdGYB3v5ko0OFsFdZY
19
+ +fJOIt4h3QKBgByFJanzADsHC0FFmzR38afujjQ9Sn5PQ2bfbWyxNa5ZxKigbtTU
20
+ rdiSNViCij/dmDyZsECYcXzXVZZyLivhygt217bjYx5JilcOjgw8MXaY1Hr8B4ff
21
+ Xlq/Z/uQusJn36RKOtdVYMHZb3r/HSCZkQvGeruRD7eakEwtDRM5rmr5AoGAZFt9
22
+ s90/ED5RDq5DbQJ9ZNzY9fWC0tmETsxd97PZ2wMmvufamPz8+UB86+ALLQZCOf10
23
+ otv7AhYmarhdjZhQghZ7ieAtqhXeGBWtvbcDedCCoF6PqiVnURwmB4IQCwFTr7jl
24
+ CsZ5n7dKWEOtVEWALyzVW3pJv/t3TJhfPfMjaVkCgYAxmC4/jmBCLmQZ3eWbmZHx
25
+ X7N2qAI7Cu2JVi1Wut4WnBgFNynYH+kt67LZSQ9Jf9lHDnlBe5gOTvF5/8UeoTMv
26
+ MGI4R4WJ6ezWV12ugbmKAvzHB/SiJ9U0ph78ibejCxW3gomuDzY1T+xF56kCKXJ0
27
+ uPaEN0rPMT6wMEegJHaE8A==
28
+ -----END PRIVATE KEY-----
@@ -0,0 +1,15 @@
1
+ -----BEGIN CERTIFICATE REQUEST-----
2
+ MIICWTCCAUECAQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0B
3
+ AQEFAAOCAQ8AMIIBCgKCAQEAmPoMX5u7QOFeaQFoLb4KSio2Ww74vNb1tmc0JCTQ
4
+ nD31+AIZMuJ9Tc17ICEqAez5Xcb/1QtsyvFgxJD+myutelLsUz3G0DRZnRUCDs6L
5
+ hYSL7C54TRHUaY40y4JVPYkJh3m4OHz6atahWpv0vjEizLSRpXQ2eX41fXMO8ddQ
6
+ fN+jdPeuhrFFt3o33ao0/OuPxO+LBtqlPRujgYrBMI47V7A8UYKOxYR4tninZR9s
7
+ 7Nb/OMgERQPwqqAU6G3jzL0npcbdNvrX/ud5PTGPoTtyfqEZLO6Igz+hlu25S3vZ
8
+ UOBsts6tLTagdPNiYL21UvflC9+DOurDQMS/vOmb/eIbSwIDAQABoAAwDQYJKoZI
9
+ hvcNAQELBQADggEBAEz74PiDtYCL1XiZV4On0l5jRjBrKTVEAnjEtWgygy9V6U1d
10
+ BYE3AxwsdTUygl/cS2i3g8U2yZGQ1ZAh/qHq0sHB6TDePLmNSEiksP7KOJwXU9vO
11
+ /pCS9qbOYcWucLlQpnHxySpUlcxFWmrl33pMaNCzxxLN1q3eRbNmxoxACI/+vZsX
12
+ M6sm2fhhw6yZkU7D04BDgSwsddW8ApDqbtwbndyv/ZL13xjG9yow8noSF7uxGQnn
13
+ UnVFMGVGp3I6M/E3VFIwRvUYA1MJeqh9tLIEItlGmqkrQmxOnMvXKzJnQ9nK1KBq
14
+ 2gaBXdvbabkXKAHnV0tYbDmZXvTO+7Ci7wgapNU=
15
+ -----END CERTIFICATE REQUEST-----
@@ -0,0 +1,19 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDCzCCAfOgAwIBAgIUN2/oKOttkdOretzyqc+Zv8IqpT8wDQYJKoZIhvcNAQEL
3
+ BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MCAXDTIzMDkxOTExMjEzM1oYDzIxMjMw
4
+ ODI2MTEyMTMzWjAUMRIwEAYDVQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEB
5
+ AQUAA4IBDwAwggEKAoIBAQD30tqrKrHa0p1RsGlDc7lUUS/ZF2/7ZtNWe0gRuuum
6
+ 6l/X5H8F+Ay1cO8DirGx3s/LPpj7DwvjjKo2eE+wcO2v/R5S+uPL4Bm0o+bPGwZP
7
+ vw+XMMgBZUsNSMER6DUliP5bHQ/8TCXWpfP3rLJ9QitOAX/rD9bVrOs3g3I0uf2A
8
+ RZ0O40//5q9fiXRC3PAfPbX7XdyI9Mr3duwmAW+nK2Gbd98ut27PkO0Fze27Xtk2
9
+ EdIh3u5pajK/ub8rf5vyfk+c/6pcN9kMakPtlgIR/eqzTkfRWyIpMoFn/X8VumUQ
10
+ X4ylj1SfSs+K47GBjrqknEh1BYlblW8WKg5cUjx/r/b/AgMBAAGjUzBRMB0GA1Ud
11
+ DgQWBBQUEefafoC0qDhzThhEBMMwr/C5FTAfBgNVHSMEGDAWgBQUEefafoC0qDhz
12
+ ThhEBMMwr/C5FTAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQDn
13
+ dfkjZtgSdbsEPhUMfUlhZWXqxtLDQBoxM7xF+i5WC6w3yHpN/teA8SqA8CYiPb9d
14
+ 5rNfnmJLP4PeyfTu6Pc0EJpQsmK19i9z0FPrA7bqPIzgF4U4R1eQ5mvTzlNoGkp3
15
+ 1gnjDdwtTq0RFfuvHKm5EqECKX+hBEJKMiviEH/mGqQuoycpKifZ5WRTQonnWjGe
16
+ BVkhdn4Psp83EWdnD/yQbo1XEbYRtsaPM4Dozr6uKbeq9Zbu+xDO9Uw4mTE/WSfb
17
+ t4AXqOLDRafOP9w3twlFH2ZQxqpSaqXo8z1RkS9jtCm69JcDnsePKqkhesToMZAz
18
+ 2cylIQmuuNIRGLmCRsVK
19
+ -----END CERTIFICATE-----
@@ -0,0 +1,28 @@
1
+ -----BEGIN PRIVATE KEY-----
2
+ MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQD30tqrKrHa0p1R
3
+ sGlDc7lUUS/ZF2/7ZtNWe0gRuuum6l/X5H8F+Ay1cO8DirGx3s/LPpj7DwvjjKo2
4
+ eE+wcO2v/R5S+uPL4Bm0o+bPGwZPvw+XMMgBZUsNSMER6DUliP5bHQ/8TCXWpfP3
5
+ rLJ9QitOAX/rD9bVrOs3g3I0uf2ARZ0O40//5q9fiXRC3PAfPbX7XdyI9Mr3duwm
6
+ AW+nK2Gbd98ut27PkO0Fze27Xtk2EdIh3u5pajK/ub8rf5vyfk+c/6pcN9kMakPt
7
+ lgIR/eqzTkfRWyIpMoFn/X8VumUQX4ylj1SfSs+K47GBjrqknEh1BYlblW8WKg5c
8
+ Ujx/r/b/AgMBAAECggEAR4aYzBwndvOgqioTR3+H9tjzyWFlVZbo2iX8t/lN+D/e
9
+ 562wJ6Xe7SMqKMiH3sFjEdMATj2afdNkcRIqVc9SGqAgd2yoAHiukp9Xh2DSYoPP
10
+ WSCgKR72GWBtMODnLe0rFFr/+R51MU12a35xiYtmej4ekFZi+ArPXJdYh/VCQBnG
11
+ BGF+EnUJqCAOXLz9zG3FoYVBWu071vEnpBtfblbHYfY2/o5CSoORkxcput6XDHxO
12
+ 7pOXN7IRt7DJZ0goda3OwZQ9suKyTLcOxa8cA+DteVP6cvh4u2l+ZMxUIYK5B1eh
13
+ VAmJkIbcbAaz/SxyO9E2gWraz+pu6ArOGY/0krcBmQKBgQD9BlVtx7QTVzu+nLzF
14
+ 2++cB0LTsTD9T9rlMfIuQMBIOywmsivyvUDr9SjOPqICQUIRufHKqCgHs4TH7Ifs
15
+ 4AxyUEwQMG4xuYh3nU5eZlpUEjzUWbbe7o0NjhaJ4ZlUBvzHBcgptUlKTwvwamMs
16
+ pnzQxWlFXFuh+pxPPdSXZVmWJQKBgQD6vN0pO/xc3bAqHSCavX95NBjUhFvkAsoo
17
+ T8tfv2qoAN8RhI2/N8prix6tJk3AdhzdLmmMktv3MBDXd3cgLgmXQTYHIijWXPlF
18
+ /WXWmZXK0E9fiDjfXI9eB7E237fYGOaSobOhLOLoHcuL0kndps67QP2BhtXhYB88
19
+ 1We7LoJVUwKBgQCnF1qtH5d0ukPTEdC73Q0z/buM7tPKRMTqXHxxPQN9782tVDYf
20
+ nAlWiVTENqpoUM4fxKq/SSL+SvfhyvrMW/z8NLi2bDUpEzviufg58N+v60dOeFyC
21
+ hgiSLgYGUfweeGrPx6qymGxo7SCWSLtrjhqZB/UIAADnTAeTcOKGhECQHQKBgAlM
22
+ A29J+BuBZMzK87CJIjbeRaVrmvSjXdeMzd+o+01ratn9bjwO14SRTfvhlbRzLLLO
23
+ y78YmutZbuZuWY5p5pUjJ9uv2o/INr3vnV0NqM4yVx8Vr/YoOnCkHGAKf4iVs8bw
24
+ E/b/8RHmOOvgSjjbvIKY8E1jMH8Az2e0CfqYyOBdAoGAOlhTefyBGgAWFHqH/l4p
25
+ ThbWupIMsw1ZXlArwBnTfsUFuz0Yq7B+0tqrV8lhS3P4/0jI2yWnzhluDk62clwz
26
+ Xg187V85Ylagshsjv60mP5qBEF4N7Nf5fP2w6+GjMU+YiHEBsgGGt+2jPgKeCGQW
27
+ IlV3ym59oL+wGyN9OK3z+aw=
28
+ -----END PRIVATE KEY-----
@@ -1,10 +1,6 @@
1
1
  require "pactflow/client/cli/pactflow"
2
2
 
3
3
  RSpec.describe "publish-provider-contract" do
4
- before do
5
- allow(ENV).to receive(:fetch).and_call_original
6
- allow(ENV).to receive(:fetch).with("PACT_BROKER_FEATURES", "").and_return("publish_provider_contracts_all_in_one")
7
- end
8
4
  let(:index_body_hash) do
9
5
  {
10
6
  _links: {
@@ -0,0 +1,39 @@
1
+ require "open3"
2
+ require "pact_broker/client/cli/broker"
3
+
4
+ # This is not the ideal way to write a test, but I tried to write it with an in memory invocation,
5
+ # and I couldn't get the capture to work, and it became super complicated.
6
+
7
+ RSpec.describe "using unknown options", skip_windows: true do
8
+ let(:unknown_switches_text) { "Unknown switches" }
9
+ let(:warning_text) { "This is a warning"}
10
+ let(:command) { "bundle exec bin/pact-broker can-i-deploy --pacticipant Foo --foo --broker-base-url http://example.org" }
11
+
12
+ it "prints an 'unknown switches' warning to stderr and also includes the normal output of the command" do
13
+ stderr_lines = nil
14
+
15
+ Open3.popen3(command) do |stdin, stdout, stderr, thread|
16
+ stderr_lines = stderr.readlines
17
+ end
18
+
19
+ expect(stderr_lines.join("\n")).to include(unknown_switches_text)
20
+ expect(stderr_lines.join("\n")).to include(warning_text)
21
+
22
+ expect(stderr_lines.size).to be > 2
23
+ end
24
+
25
+
26
+ context "with PACT_BROKER_ERROR_ON_UNKNOWN_OPTION=true" do
27
+ it "prints an 'unknown switches' message to stderr and does NOT include the normal output of the command as it exits straight after" do
28
+ stderr_lines = nil
29
+
30
+ Open3.popen3({ "PACT_BROKER_ERROR_ON_UNKNOWN_OPTION" => "true" }, command) do |stdin, stdout, stderr, thread|
31
+ stderr_lines = stderr.readlines
32
+ end
33
+
34
+ expect(stderr_lines.first).to include(unknown_switches_text)
35
+ expect(stderr_lines.join("\n")).to_not include(warning_text)
36
+ expect(stderr_lines.size).to eq 1
37
+ end
38
+ end
39
+ end
@@ -7,6 +7,10 @@ module PactBroker::Client::CLI
7
7
  end
8
8
 
9
9
  class TestThor < CustomThor
10
+ def self.exit_on_failure?
11
+ false
12
+ end
13
+
10
14
  desc 'ARGUMENT', 'This is the description'
11
15
  def test_default(argument)
12
16
  Delegate.call(argument: argument)
@@ -96,6 +100,29 @@ module PactBroker::Client::CLI
96
100
  TestThor.start(%w{test_pact_broker_client_options})
97
101
  end
98
102
 
103
+ describe "when someone copy pastes from Word and uses an em dash instead of a normal dash" do
104
+ before do
105
+ allow(TestThor).to receive(:exit_with_error_code)
106
+ end
107
+
108
+ it "exits with an error message" do
109
+ expect($stdout).to receive(:puts).with(/contains an em dash/)
110
+ expect(TestThor).to receive(:exit_with_error_code)
111
+ TestThor.start(["test_default", "\u2014\u2014bar"])
112
+ end
113
+ end
114
+
115
+ describe ".handle_help" do
116
+ context "when the last argument is --help or -h" do
117
+ it "turns it into the form that Thor expects, which is a really odd one" do
118
+ expect(TestThor.handle_help(["foo", "--help"])).to eq ["help", "foo"]
119
+ expect(TestThor.handle_help(["foo", "-h"])).to eq ["help", "foo"]
120
+ expect(TestThor.handle_help(["-h"])).to eq ["help"]
121
+ expect(TestThor.handle_help(["--help"])).to eq ["help"]
122
+ end
123
+ end
124
+ end
125
+
99
126
  describe ".turn_muliple_tag_options_into_array" do
100
127
  it "turns '--tag foo --tag bar' into '--tag foo bar'" do
101
128
  input = %w{--ignore this --tag foo --tag bar --wiffle --that}
@@ -1,4 +1,6 @@
1
1
  require 'pact_broker/client/hal/http_client'
2
+ require "faraday"
3
+ require "faraday/retry"
2
4
 
3
5
  module PactBroker::Client
4
6
  module Hal
@@ -157,6 +159,80 @@ module PactBroker::Client
157
159
  end
158
160
  end
159
161
  end
162
+
163
+ describe "x509 certificate" do
164
+ FAKE_SERVER_URL = 'https://localhost:4444'
165
+ X509_CERT_FILE_PATH = './spec/fixtures/certificates/client_cert.pem'
166
+ X509_KEY_FILE_PATH = './spec/fixtures/certificates/key.pem'
167
+ UNSIGNED_X509_CERT_FILE_PATH = './spec/fixtures/certificates/unsigned_cert.pem'
168
+ UNSIGNED_X509_KEY_FILE_PATH = './spec/fixtures/certificates/unsigned_key.pem'
169
+
170
+ def wait_for_server_to_start
171
+ Faraday.new(
172
+ url: FAKE_SERVER_URL,
173
+ ssl: {
174
+ verify: false,
175
+ client_cert: OpenSSL::X509::Certificate.new(File.read(X509_CERT_FILE_PATH)),
176
+ client_key: OpenSSL::PKey::RSA.new(File.read(X509_KEY_FILE_PATH))
177
+ }
178
+ ) do |builder|
179
+ builder.request :retry, max: 20, interval: 0.5, exceptions: [StandardError]
180
+ builder.adapter :net_http
181
+ end.get
182
+ end
183
+
184
+ let(:do_get) { subject.get(FAKE_SERVER_URL) }
185
+
186
+ before(:all) do
187
+ @pipe = IO.popen("bundle exec ruby ./spec/support/ssl_server.rb")
188
+ ENV['SSL_CERT_FILE'] = "./spec/fixtures/certificates/ca_cert.pem"
189
+
190
+ wait_for_server_to_start()
191
+ end
192
+
193
+ context "with valid x509 client certificates" do
194
+ before do
195
+ ENV['X509_CLIENT_CERT_FILE'] = X509_CERT_FILE_PATH
196
+ ENV['X509_CLIENT_KEY_FILE'] = X509_KEY_FILE_PATH
197
+ end
198
+
199
+ it "succeeds" do
200
+ expect(do_get.status).to eq 200
201
+ end
202
+ end
203
+
204
+ context "when invalid x509 certificates are set" do
205
+ before do
206
+ ENV['X509_CLIENT_CERT_FILE'] = UNSIGNED_X509_CERT_FILE_PATH
207
+ ENV['X509_CLIENT_KEY_FILE'] = UNSIGNED_X509_KEY_FILE_PATH
208
+ end
209
+
210
+ it "fails raising SSL error" do
211
+ expect { do_get }
212
+ .to raise_error { |error|
213
+ expect([OpenSSL::SSL::SSLError, Errno::ECONNRESET]).to include(error.class)
214
+ }
215
+ end
216
+ end
217
+
218
+ context "when no x509 certificates are set" do
219
+ before do
220
+ ENV['X509_CLIENT_CERT_FILE'] = nil
221
+ ENV['X509_CLIENT_KEY_FILE'] = nil
222
+ end
223
+
224
+ it "fails raising SSL error" do
225
+ expect { do_get }
226
+ .to raise_error { |error|
227
+ expect([OpenSSL::SSL::SSLError, Errno::ECONNRESET]).to include(error.class)
228
+ }
229
+ end
230
+ end
231
+
232
+ after(:all) do
233
+ Process.kill "KILL", @pipe.pid
234
+ end
235
+ end
160
236
  end
161
237
  end
162
238
  end
@@ -7,8 +7,6 @@ module Pactflow
7
7
  before do
8
8
  allow_any_instance_of(PactBroker::Client::Hal::HttpClient).to receive(:sleep)
9
9
  allow_any_instance_of(PactBroker::Client::Hal::HttpClient).to receive(:default_max_tries).and_return(1)
10
- allow(ENV).to receive(:fetch).and_call_original
11
- allow(ENV).to receive(:fetch).with("PACT_BROKER_FEATURES", "").and_return("publish_provider_contracts_all_in_one")
12
10
  end
13
11
 
14
12
  let(:command_params) do
@@ -99,9 +97,10 @@ module Pactflow
99
97
  end
100
98
  end
101
99
 
102
- context "when the feature is not enabled" do
100
+ context "when the feature is disabled" do
103
101
  before do
104
- allow(ENV).to receive(:fetch).with("PACT_BROKER_FEATURES", "").and_return("")
102
+ allow(ENV).to receive(:fetch).and_call_original
103
+ allow(ENV).to receive(:fetch).with("PACTFLOW_FEATURES", "").and_return("publish_provider_contracts_using_old_api")
105
104
  end
106
105
 
107
106
  it "publishes the provider contracts the old way" do
@@ -1602,8 +1602,7 @@
1602
1602
  "name": "Foo"
1603
1603
  },
1604
1604
  "version": {
1605
- "number": "5556b8149bf8bac76bc30f50a8a2dd4c22c85f30",
1606
- "buildUrl": "http://build"
1605
+ "number": "5556b8149bf8bac76bc30f50a8a2dd4c22c85f30"
1607
1606
  }
1608
1607
  },
1609
1608
  "logs": [
@@ -6,8 +6,6 @@ RSpec.describe "publishing a provider contract to PactFlow", pact: true do
6
6
  before do
7
7
  allow_any_instance_of(PactBroker::Client::Hal::HttpClient).to receive(:sleep)
8
8
  allow_any_instance_of(PactBroker::Client::Hal::HttpClient).to receive(:default_max_tries).and_return(1)
9
- allow(ENV).to receive(:fetch).and_call_original
10
- allow(ENV).to receive(:fetch).with("PACT_BROKER_FEATURES", "").and_return("publish_provider_contracts_all_in_one")
11
9
  end
12
10
 
13
11
  include_context "pact broker"
@@ -88,8 +88,7 @@ RSpec.describe "publishing contracts", pact: true do
88
88
  name: pacticipant_name
89
89
  },
90
90
  version: {
91
- number: version_number,
92
- buildUrl: build_url
91
+ number: version_number
93
92
  }
94
93
  },
95
94
  logs: Pact.each_like(level: "info", message: "some message"),
@@ -0,0 +1,42 @@
1
+ if __FILE__ == $0
2
+
3
+ SSL_KEY = "spec/fixtures/certificates/key.pem"
4
+ SSL_CERT = "spec/fixtures/certificates/client_cert.pem"
5
+ SSL_CA_CERT = "spec/fixtures/certificates/ca_cert.pem"
6
+
7
+ trap(:INT) do
8
+ @server.shutdown
9
+ exit
10
+ end
11
+
12
+ def webrick_opts port
13
+ certificate = OpenSSL::X509::Certificate.new(File.read(SSL_CERT))
14
+ cert_name = certificate.subject.to_a.collect{|a| a[0..1] }
15
+ logger_stream = ENV["DEBUG"] ? $stderr : StringIO.new
16
+ {
17
+ Port: port,
18
+ Host: "0.0.0.0",
19
+ AccessLog: [],
20
+ Logger: WEBrick::Log.new(logger_stream,WEBrick::Log::INFO),
21
+ SSLVerifyClient: OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT | OpenSSL::SSL::VERIFY_PEER,
22
+ SSLCACertificateFile: SSL_CA_CERT,
23
+ SSLCertificate: certificate,
24
+ SSLPrivateKey: OpenSSL::PKey::RSA.new(File.read(SSL_KEY)),
25
+ SSLEnable: true,
26
+ SSLCertName: cert_name,
27
+ }
28
+ end
29
+
30
+ app = ->(_env) { puts "hello"; [200, {}, ["Hello world" + "\n"]] }
31
+
32
+ require "webrick"
33
+ require "webrick/https"
34
+ require "rack"
35
+ require "rack/handler/webrick"
36
+
37
+ opts = webrick_opts(4444)
38
+
39
+ Rack::Handler::WEBrick.run(app, **opts) do |server|
40
+ @server = server
41
+ end
42
+ end
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.71.0
4
+ version: 1.73.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: 2023-09-07 00:00:00.000000000 Z
11
+ date: 2023-10-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httparty
@@ -106,104 +106,6 @@ dependencies:
106
106
  - - "~>"
107
107
  - !ruby/object:Gem::Version
108
108
  version: '1.0'
109
- - !ruby/object:Gem::Dependency
110
- name: fakefs
111
- requirement: !ruby/object:Gem::Requirement
112
- requirements:
113
- - - "~>"
114
- - !ruby/object:Gem::Version
115
- version: '2.4'
116
- type: :development
117
- prerelease: false
118
- version_requirements: !ruby/object:Gem::Requirement
119
- requirements:
120
- - - "~>"
121
- - !ruby/object:Gem::Version
122
- version: '2.4'
123
- - !ruby/object:Gem::Dependency
124
- name: webmock
125
- requirement: !ruby/object:Gem::Requirement
126
- requirements:
127
- - - "~>"
128
- - !ruby/object:Gem::Version
129
- version: '3.0'
130
- type: :development
131
- prerelease: false
132
- version_requirements: !ruby/object:Gem::Requirement
133
- requirements:
134
- - - "~>"
135
- - !ruby/object:Gem::Version
136
- version: '3.0'
137
- - !ruby/object:Gem::Dependency
138
- name: conventional-changelog
139
- requirement: !ruby/object:Gem::Requirement
140
- requirements:
141
- - - "~>"
142
- - !ruby/object:Gem::Version
143
- version: '1.3'
144
- type: :development
145
- prerelease: false
146
- version_requirements: !ruby/object:Gem::Requirement
147
- requirements:
148
- - - "~>"
149
- - !ruby/object:Gem::Version
150
- version: '1.3'
151
- - !ruby/object:Gem::Dependency
152
- name: pact
153
- requirement: !ruby/object:Gem::Requirement
154
- requirements:
155
- - - "~>"
156
- - !ruby/object:Gem::Version
157
- version: '1.16'
158
- type: :development
159
- prerelease: false
160
- version_requirements: !ruby/object:Gem::Requirement
161
- requirements:
162
- - - "~>"
163
- - !ruby/object:Gem::Version
164
- version: '1.16'
165
- - !ruby/object:Gem::Dependency
166
- name: pact-support
167
- requirement: !ruby/object:Gem::Requirement
168
- requirements:
169
- - - "~>"
170
- - !ruby/object:Gem::Version
171
- version: '1.16'
172
- type: :development
173
- prerelease: false
174
- version_requirements: !ruby/object:Gem::Requirement
175
- requirements:
176
- - - "~>"
177
- - !ruby/object:Gem::Version
178
- version: '1.16'
179
- - !ruby/object:Gem::Dependency
180
- name: approvals
181
- requirement: !ruby/object:Gem::Requirement
182
- requirements:
183
- - - '='
184
- - !ruby/object:Gem::Version
185
- version: 0.0.26
186
- type: :development
187
- prerelease: false
188
- version_requirements: !ruby/object:Gem::Requirement
189
- requirements:
190
- - - '='
191
- - !ruby/object:Gem::Version
192
- version: 0.0.26
193
- - !ruby/object:Gem::Dependency
194
- name: rspec-its
195
- requirement: !ruby/object:Gem::Requirement
196
- requirements:
197
- - - "~>"
198
- - !ruby/object:Gem::Version
199
- version: '1.3'
200
- type: :development
201
- prerelease: false
202
- version_requirements: !ruby/object:Gem::Requirement
203
- requirements:
204
- - - "~>"
205
- - !ruby/object:Gem::Version
206
- version: '1.3'
207
109
  description: Client for the Pact Broker. Publish, retrieve and query pacts and verification
208
110
  results. Manage webhooks and environments.
209
111
  email:
@@ -224,6 +126,7 @@ files:
224
126
  - ".rspec"
225
127
  - ".ruby-version"
226
128
  - CHANGELOG.md
129
+ - DEVELOPING.md
227
130
  - Dockerfile
228
131
  - Gemfile
229
132
  - LICENSE.txt
@@ -263,6 +166,7 @@ files:
263
166
  - lib/pact_broker/client/cli/pact_commands.rb
264
167
  - lib/pact_broker/client/cli/pacticipant_commands.rb
265
168
  - lib/pact_broker/client/cli/record_deployment_long_desc.txt
169
+ - lib/pact_broker/client/cli/thor_unknown_options_monkey_patch.rb
266
170
  - lib/pact_broker/client/cli/version_commands.rb
267
171
  - lib/pact_broker/client/cli/version_selector_options_parser.rb
268
172
  - lib/pact_broker/client/cli/webhook_commands.rb
@@ -337,6 +241,7 @@ files:
337
241
  - pact-broker-client.gemspec
338
242
  - script/approve-all.sh
339
243
  - script/can-i-deploy.sh
244
+ - script/ci/record-release.sh
340
245
  - script/create-pacticipant.sh
341
246
  - script/foo-bar.json
342
247
  - script/oas.yml
@@ -357,12 +262,21 @@ files:
357
262
  - spec/fixtures/approvals/describe_pacticipant.approved.txt
358
263
  - spec/fixtures/approvals/list_environments.approved.txt
359
264
  - spec/fixtures/approvals/publish_provider_contract.approved.txt
265
+ - spec/fixtures/certificates/ca_cert.pem
266
+ - spec/fixtures/certificates/ca_cert.srl
267
+ - spec/fixtures/certificates/ca_key.pem
268
+ - spec/fixtures/certificates/client_cert.pem
269
+ - spec/fixtures/certificates/key.pem
270
+ - spec/fixtures/certificates/server.csr
271
+ - spec/fixtures/certificates/unsigned_cert.pem
272
+ - spec/fixtures/certificates/unsigned_key.pem
360
273
  - spec/fixtures/foo-bar.json
361
274
  - spec/integration/can_i_deploy_spec.rb
362
275
  - spec/integration/can_i_merge_spec.rb
363
276
  - spec/integration/create_version_tag_spec.rb
364
277
  - spec/integration/describe_environment_spec.rb
365
278
  - spec/integration/publish_provider_contract_spec.rb
279
+ - spec/integration/unknown_options_spec.rb
366
280
  - spec/lib/pact_broker/client/base_client_spec.rb
367
281
  - spec/lib/pact_broker/client/can_i_deploy_spec.rb
368
282
  - spec/lib/pact_broker/client/cli/broker_can_i_deploy_spec.rb
@@ -439,6 +353,7 @@ files:
439
353
  - spec/support/pacticipants_list.json
440
354
  - spec/support/pacts_latest_list.json
441
355
  - spec/support/shared_context.rb
356
+ - spec/support/ssl_server.rb
442
357
  - tasks/pact.rake
443
358
  homepage: https://github.com/pact-foundation/pact_broker-client.git
444
359
  licenses:
@@ -459,7 +374,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
459
374
  - !ruby/object:Gem::Version
460
375
  version: '0'
461
376
  requirements: []
462
- rubygems_version: 3.4.19
377
+ rubygems_version: 3.4.20
463
378
  signing_key:
464
379
  specification_version: 4
465
380
  summary: See description
@@ -471,12 +386,21 @@ test_files:
471
386
  - spec/fixtures/approvals/describe_pacticipant.approved.txt
472
387
  - spec/fixtures/approvals/list_environments.approved.txt
473
388
  - spec/fixtures/approvals/publish_provider_contract.approved.txt
389
+ - spec/fixtures/certificates/ca_cert.pem
390
+ - spec/fixtures/certificates/ca_cert.srl
391
+ - spec/fixtures/certificates/ca_key.pem
392
+ - spec/fixtures/certificates/client_cert.pem
393
+ - spec/fixtures/certificates/key.pem
394
+ - spec/fixtures/certificates/server.csr
395
+ - spec/fixtures/certificates/unsigned_cert.pem
396
+ - spec/fixtures/certificates/unsigned_key.pem
474
397
  - spec/fixtures/foo-bar.json
475
398
  - spec/integration/can_i_deploy_spec.rb
476
399
  - spec/integration/can_i_merge_spec.rb
477
400
  - spec/integration/create_version_tag_spec.rb
478
401
  - spec/integration/describe_environment_spec.rb
479
402
  - spec/integration/publish_provider_contract_spec.rb
403
+ - spec/integration/unknown_options_spec.rb
480
404
  - spec/lib/pact_broker/client/base_client_spec.rb
481
405
  - spec/lib/pact_broker/client/can_i_deploy_spec.rb
482
406
  - spec/lib/pact_broker/client/cli/broker_can_i_deploy_spec.rb
@@ -553,3 +477,4 @@ test_files:
553
477
  - spec/support/pacticipants_list.json
554
478
  - spec/support/pacts_latest_list.json
555
479
  - spec/support/shared_context.rb
480
+ - spec/support/ssl_server.rb