pact_broker-client 1.72.0 → 1.74.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/release_gem.yml +4 -4
  3. data/.github/workflows/test.yml +5 -5
  4. data/.github/workflows/trigger_pact_docs_update.yml +1 -1
  5. data/CHANGELOG.md +21 -0
  6. data/DEVELOPING.md +17 -0
  7. data/Gemfile +5 -0
  8. data/README.md +21 -9
  9. data/doc/pacts/markdown/Pact Broker Client - Pact Broker.md +1 -2
  10. data/example/scripts/publish-pact-rake.sh +10 -0
  11. data/example/scripts/publish-pact.sh +25 -1
  12. data/example/scripts/publish-provider-contract.sh +2 -1
  13. data/lib/pact_broker/client/cli/custom_thor.rb +32 -2
  14. data/lib/pact_broker/client/cli/pact_commands.rb +34 -13
  15. data/lib/pact_broker/client/cli/thor_unknown_options_monkey_patch.rb +38 -0
  16. data/lib/pact_broker/client/cli/webhook_commands.rb +1 -1
  17. data/lib/pact_broker/client/git.rb +20 -3
  18. data/lib/pact_broker/client/hal/http_client.rb +19 -0
  19. data/lib/pact_broker/client/merge_pacts.rb +5 -2
  20. data/lib/pact_broker/client/publish_pacts_the_old_way.rb +1 -1
  21. data/lib/pact_broker/client/tasks/publication_task.rb +40 -23
  22. data/lib/pact_broker/client/version.rb +1 -1
  23. data/script/ci/record-release.sh +2 -2
  24. data/script/publish-pact.sh +1 -1
  25. data/script/update-cli-usage-in-readme.rb +7 -0
  26. data/spec/fixtures/MyConsumer-MyProvider (1).json +37 -0
  27. data/spec/fixtures/MyConsumer-MyProvider.json +37 -0
  28. data/spec/fixtures/certificates/ca_cert.pem +19 -0
  29. data/spec/fixtures/certificates/ca_cert.srl +1 -0
  30. data/spec/fixtures/certificates/ca_key.pem +28 -0
  31. data/spec/fixtures/certificates/client_cert.pem +17 -0
  32. data/spec/fixtures/certificates/key.pem +28 -0
  33. data/spec/fixtures/certificates/server.csr +15 -0
  34. data/spec/fixtures/certificates/unsigned_cert.pem +19 -0
  35. data/spec/fixtures/certificates/unsigned_key.pem +28 -0
  36. data/spec/integration/can_i_deploy_spec.rb +0 -9
  37. data/spec/integration/unknown_options_spec.rb +39 -0
  38. data/spec/lib/pact_broker/client/cli/broker_publish_spec.rb +38 -21
  39. data/spec/lib/pact_broker/client/cli/custom_thor_spec.rb +27 -0
  40. data/spec/lib/pact_broker/client/hal/http_client_spec.rb +76 -0
  41. data/spec/lib/pact_broker/client/merge_pacts_spec.rb +26 -0
  42. data/spec/lib/pact_broker/client/publish_pacts_the_old_way_spec.rb +1 -3
  43. data/spec/lib/pact_broker/client/tasks/publication_task_spec.rb +54 -31
  44. data/spec/pacts/pact_broker_client-pact_broker.json +1 -2
  45. data/spec/service_providers/publish_pacts_spec.rb +1 -2
  46. data/spec/support/ssl_server.rb +42 -0
  47. data/tasks/pact.rake +79 -0
  48. metadata +30 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 95192c76cf2b56651bb52de5cd2c5f1bea45d966e5dfa4e8ef78d1e11a3a2a51
4
- data.tar.gz: 1a095144bc411e428556f47da77160d5c7a182e4eb2201d75f30075adb1cb009
3
+ metadata.gz: 84c25ce85cb110411ce145b803e155a0cb8c30a356bb3a6dc8239ab14fbc97c4
4
+ data.tar.gz: 57a8dcaf85657dc9f99c233abf1cbd1fa0672e0c942ba8d0f009907afda87309
5
5
  SHA512:
6
- metadata.gz: 3553d23ad0bdae6e6f460a6a85dd3ab46789bf3cfe6241881c1f126642b73cf6ee9714f60e830c7108f8e0a0a188a7a2a6b1a42dda55be7ae2339b9ccfd3552b
7
- data.tar.gz: 3c039eb65e3f4f02c9f32ebf52936535ccb125e8105c4b1681aeafa90de007c7dc032824d20facf6e023c61e3b32147e188312b8a8244b506627fe69e8f414c0
6
+ metadata.gz: 732c56c1c831f3f154e9be33ef949208057db7705a7bca291d1a356923729acda5f762ff2e57ab51409afa71e425eec7bc775964816de74d215229a66583bedf
7
+ data.tar.gz: 97f2acafe53b570a5945d1e3c8750cf6f35f5a122ba58e5b8646ba2dc2b1702ad44489ab21ba53fa19220aca569bd8495c5ce6f694b9ec1784caf8a247cd6fed
@@ -10,7 +10,7 @@ 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
15
  - run: |
16
16
  gem install bundler -v 2.4
@@ -26,7 +26,7 @@ jobs:
26
26
  version: ${{ steps.release.outputs.version }}
27
27
  increment: ${{ steps.release.outputs.increment }}
28
28
  steps:
29
- - uses: actions/checkout@v3
29
+ - uses: actions/checkout@v4
30
30
  with:
31
31
  fetch-depth: 0
32
32
  - uses: pact-foundation/release-gem@v0.0.14
@@ -40,7 +40,7 @@ jobs:
40
40
  needs: release
41
41
  runs-on: ubuntu-latest
42
42
  steps:
43
- - uses: actions/checkout@v3
43
+ - uses: actions/checkout@v4
44
44
  - uses: ruby/setup-ruby@v1
45
45
  - name: Bundle install
46
46
  run: |
@@ -61,7 +61,7 @@ jobs:
61
61
  runs-on: ubuntu-latest
62
62
  steps:
63
63
  - name: Notify ${{ matrix.repository }} of gem release
64
- uses: peter-evans/repository-dispatch@v1
64
+ uses: peter-evans/repository-dispatch@v2
65
65
  with:
66
66
  token: ${{ secrets.GHTOKENFORPACTCLIRELEASE }}
67
67
  repository: ${{ matrix.repository }}
@@ -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 }}
@@ -16,7 +16,7 @@ jobs:
16
16
  runs-on: ubuntu-latest
17
17
  steps:
18
18
  - name: Trigger docs.pact.io update workflow
19
- uses: peter-evans/repository-dispatch@v1
19
+ uses: peter-evans/repository-dispatch@v2
20
20
  with:
21
21
  token: ${{ secrets.GHTOKENFORTRIGGERINGPACTDOCSUPDATE }}
22
22
  repository: pact-foundation/docs.pact.io
data/CHANGELOG.md CHANGED
@@ -1,3 +1,24 @@
1
+ <a name="v1.74.0"></a>
2
+ ### v1.74.0 (2023-10-14)
3
+
4
+ #### Features
5
+
6
+ * auto detect commit sha, add shorthand -r flag (#119) ([1dac9f8](/../../commit/1dac9f8))
7
+
8
+ #### Bug Fixes
9
+
10
+ * support merging v3 pacts ([d1e01d0](/../../commit/d1e01d0))
11
+
12
+ <a name="v1.73.0"></a>
13
+ ### v1.73.0 (2023-10-13)
14
+
15
+ #### Features
16
+
17
+ * print warnings and allow error to be raised when unknown option is used ([5412121](/../../commit/5412121))
18
+ * raise an error when an em dash is used instead of a normal dash ([0e8e773](/../../commit/0e8e773))
19
+ * support --help and -h flags ([a6458ab](/../../commit/a6458ab))
20
+ * handle x509 certs in HTTP Client (#142) ([c3aa8dc](/../../commit/c3aa8dc))
21
+
1
22
  <a name="v1.72.0"></a>
2
23
  ### v1.72.0 (2023-09-11)
3
24
 
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
@@ -21,3 +21,8 @@ group :development do
21
21
  gem 'rspec-its', '~> 1.3'
22
22
  gem 'pry-byebug'
23
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
 
@@ -51,18 +59,18 @@ Authentication using a bearer token can be specified using the environment varia
51
59
 
52
60
  ```
53
61
  Usage:
54
- pact-broker publish PACT_DIRS_OR_FILES ... -a, --consumer-app-version=CONSUMER_APP_VERSION -b, --broker-base-url=BROKER_BASE_URL
62
+ pact-broker publish PACT_DIRS_OR_FILES ... -b, --broker-base-url=BROKER_BASE_URL
55
63
 
56
64
  Options:
57
- -a, --consumer-app-version=CONSUMER_APP_VERSION
65
+ -a, [--consumer-app-version=CONSUMER_APP_VERSION]
58
66
  # The consumer application version
59
67
  -h, [--branch=BRANCH]
60
68
  # Repository branch of the consumer version
61
- [--auto-detect-version-properties], [--no-auto-detect-version-properties]
62
- # Automatically detect the repository branch from known CI
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.
69
+ -r, [--auto-detect-version-properties], [--no-auto-detect-version-properties]
70
+ # Automatically detect the repository commit, branch and build
71
+ URL from known CI environment variables or git CLI. Supports
72
+ Buildkite, Circle CI, Travis CI, GitHub Actions, Jenkins,
73
+ Hudson, AppVeyor, GitLab, CodeShip, Bitbucket and Azure DevOps.
66
74
  -t, [--tag=TAG]
67
75
  # Tag name for consumer version. Can be specified multiple
68
76
  times.
@@ -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": [
@@ -0,0 +1,10 @@
1
+ #!/bin/bash
2
+ # assumes you've set PACT_BROKER_BASE_URL, PACT_BROKER_TOKEN already
3
+
4
+ bundle exec rake pact:publish:pactflow_auto_on_nil_commit_nil_branch
5
+ bundle exec rake pact:publish:pactflow_auto_on_user_commit_user_branch
6
+ bundle exec rake pact:publish:pactflow_auto_on_user_commit_nil_branch
7
+ bundle exec rake pact:publish:pactflow_auto_on_nil_commit_user_branch
8
+ bundle exec rake pact:publish:pactflow_auto_off_user_commit_nil_branch
9
+ bundle exec rake pact:publish:pactflow_auto_off_nil_commit_nil_branch
10
+ bundle exec rake pact:publish:pactflow_auto_off_empty_string_commit_nil_branch
@@ -1,3 +1,27 @@
1
1
  # assumes you've set PACT_BROKER_BASE_URL, PACT_BROKER_USERNAME and PACT_BROKER_PASSWORD already
2
+ # Must be executed from root directory of project.
2
3
 
3
- bundle exec bin/pact-broker publish $(dirname "$0")/pact.json --consumer-app-version=1.0.0 --tag master --verbose
4
+ bundle exec bin/pact-broker publish $(dirname "$0")/pact.json
5
+ bundle exec bin/pact-broker publish $(dirname "$0")/pact.json --auto-detect-version-properties
6
+ bundle exec bin/pact-broker publish $(dirname "$0")/pact.json --auto-detect-version-properties --tag-with-git-branch
7
+ bundle exec bin/pact-broker publish $(dirname "$0")/pact.json --branch branch-user-override
8
+ bundle exec bin/pact-broker publish $(dirname "$0")/pact.json --branch branch-user-override --auto-detect-version-properties
9
+ bundle exec bin/pact-broker publish $(dirname "$0")/pact.json --branch branch-user-override --auto-detect-version-properties --tag-with-git-branch
10
+ bundle exec bin/pact-broker publish $(dirname "$0")/pact.json --consumer-app-version commit-user-override
11
+ bundle exec bin/pact-broker publish $(dirname "$0")/pact.json --consumer-app-version commit-user-override --branch branch-user-override
12
+ bundle exec bin/pact-broker publish $(dirname "$0")/pact.json --consumer-app-version commit-user-override --auto-detect-version-properties
13
+ bundle exec bin/pact-broker publish $(dirname "$0")/pact.json --consumer-app-version commit-user-override --auto-detect-version-properties --tag-with-git-branch
14
+ bundle exec bin/pact-broker publish $(dirname "$0")/pact.json --consumer-app-version commit-user-override --branch branch-user-override --auto-detect-version-properties
15
+ bundle exec bin/pact-broker publish $(dirname "$0")/pact.json --consumer-app-version commit-user-override --branch branch-user-override --auto-detect-version-properties --tag-with-git-branch
16
+
17
+ bundle exec bin/pact-broker publish $(dirname "$0")/pact.json -r
18
+ bundle exec bin/pact-broker publish $(dirname "$0")/pact.json -r -g
19
+ bundle exec bin/pact-broker publish $(dirname "$0")/pact.json -h branch-user-override
20
+ bundle exec bin/pact-broker publish $(dirname "$0")/pact.json -h branch-user-override -r
21
+ bundle exec bin/pact-broker publish $(dirname "$0")/pact.json -h branch-user-override -r -g
22
+ bundle exec bin/pact-broker publish $(dirname "$0")/pact.json -a commit-user-override
23
+ bundle exec bin/pact-broker publish $(dirname "$0")/pact.json -a commit-user-override -r
24
+ bundle exec bin/pact-broker publish $(dirname "$0")/pact.json -a commit-user-override -r -g
25
+ bundle exec bin/pact-broker publish $(dirname "$0")/pact.json -a commit-user-override -h branch-user-override
26
+ bundle exec bin/pact-broker publish $(dirname "$0")/pact.json -a commit-user-override -h branch-user-override -r
27
+ bundle exec bin/pact-broker publish $(dirname "$0")/pact.json -a commit-user-override -h branch-user-override -r -g
@@ -1,4 +1,5 @@
1
- # assumes you've set PACT_BROKER_BASE_URL, PACT_BROKER_USERNAME and PACT_BROKER_PASSWORD already
1
+ # Assumes you've set PACT_BROKER_BASE_URL, PACT_BROKER_USERNAME and PACT_BROKER_PASSWORD already
2
+ # Must be executed from root directory of project.
2
3
 
3
4
  bundle exec bin/pactflow publish-provider-contract $(dirname "$0")/oas.yml \
4
5
  --provider pactflow-cli-test-provider \
@@ -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']
@@ -1,4 +1,5 @@
1
1
  require "pact_broker/client/hash_refinements"
2
+ require 'pact_broker/client/string_refinements'
2
3
 
3
4
  module PactBroker
4
5
  module Client
@@ -8,13 +9,14 @@ module PactBroker
8
9
 
9
10
  module PactCommands
10
11
  using PactBroker::Client::HashRefinements
12
+ using PactBroker::Client::StringRefinements
11
13
 
12
14
  def self.included(thor)
13
15
  thor.class_eval do
14
16
  desc 'publish PACT_DIRS_OR_FILES ...', "Publish pacts to a Pact Broker."
15
- method_option :consumer_app_version, required: true, aliases: "-a", desc: "The consumer application version"
17
+ method_option :consumer_app_version, aliases: "-a", desc: "The consumer application version"
16
18
  method_option :branch, aliases: "-h", desc: "Repository branch of the consumer version"
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."
19
+ method_option :auto_detect_version_properties, aliases: "-r", type: :boolean, default: false, desc: "Automatically detect the repository commit, branch and build URL 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
20
  method_option :tag, aliases: "-t", type: :array, banner: "TAG", desc: "Tag name for consumer version. Can be specified multiple times."
19
21
  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
22
  method_option :build_url, desc: "The build URL that created the pact"
@@ -23,8 +25,10 @@ module PactBroker
23
25
  shared_authentication_options
24
26
 
25
27
  def publish(*pact_files)
26
- require 'pact_broker/client/error'
28
+ require "pact_broker/client/error"
29
+ require "pact_broker/client/git"
27
30
  validate_credentials
31
+ validate_consumer_version
28
32
  validate_pact_files(pact_files)
29
33
  result = publish_pacts(pact_files)
30
34
  $stdout.puts result.message
@@ -50,17 +54,21 @@ module PactBroker
50
54
  end
51
55
  end
52
56
 
57
+ def validate_consumer_version
58
+ if consumer_app_version.blank?
59
+ raise ::Thor::RequiredArgumentMissingError, "No value provided for required option --consumer-app-version"
60
+ end
61
+ end
53
62
 
54
63
  def publish_pacts pact_files
55
64
  require 'pact_broker/client/publish_pacts'
56
65
 
57
66
  write_options = options[:merge] ? { write: :merge } : {}
58
67
  consumer_version_params = {
59
- number: options.consumer_app_version,
68
+ number: consumer_app_version,
60
69
  branch: branch,
61
70
  tags: tags,
62
- build_url: options.build_url,
63
- version_required: (!!options.branch || !!options.build_url || explict_auto_detect_version_properties)
71
+ build_url: build_url
64
72
  }.compact
65
73
 
66
74
  PactBroker::Client::PublishPacts.call(
@@ -99,25 +107,38 @@ module PactBroker
99
107
  end
100
108
 
101
109
  def tags
102
- require 'pact_broker/client/git'
103
-
104
110
  t = [*options.tag]
105
111
  t << PactBroker::Client::Git.branch(raise_error: true) if options.tag_with_git_branch
106
112
  t.compact.uniq
107
113
  end
108
114
 
109
115
  def branch
110
- require 'pact_broker/client/git'
111
-
112
116
  if options.branch.nil? && options.auto_detect_version_properties
113
- PactBroker::Client::Git.branch(raise_error: explict_auto_detect_version_properties)
117
+ PactBroker::Client::Git.branch(raise_error: true)
114
118
  else
115
119
  options.branch
116
120
  end
117
121
  end
118
122
 
119
- def explict_auto_detect_version_properties
120
- @explict_auto_detect_version_properties ||= ARGV.include?("--auto-detect-version-properties")
123
+ def consumer_app_version
124
+ if defined?(@consumer_app_version)
125
+ @consumer_app_version
126
+ else
127
+ @consumer_app_version = if options.consumer_app_version.blank? && options.auto_detect_version_properties
128
+ PactBroker::Client::Git.commit(raise_error: true)
129
+ else
130
+ options.consumer_app_version
131
+ end
132
+ end
133
+
134
+ end
135
+
136
+ def build_url
137
+ if options.build_url.blank? && options.auto_detect_version_properties
138
+ PactBroker::Client::Git.build_url
139
+ else
140
+ options.build_url
141
+ end
121
142
  end
122
143
  end
123
144
  end
@@ -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"
@@ -2,7 +2,6 @@ require 'pact_broker/client/error'
2
2
  require 'pact_broker/client/hash_refinements'
3
3
 
4
4
  =begin
5
-
6
5
  BUILDKITE_BRANCH BUILDKITE_COMMIT https://buildkite.com/docs/pipelines/environment-variables
7
6
  CIRCLE_BRANCH CIRCLE_SHA1 https://circleci.com/docs/2.0/env-vars/
8
7
  TRAVIS_COMMIT TRAVIS_BRANCH - TRAVIS_PULL_REQUEST_BRANCH TRAVIS_PULL_REQUEST_SHA https://docs.travis-ci.com/user/environment-variables/
@@ -26,18 +25,21 @@ module PactBroker
26
25
  using PactBroker::Client::HashRefinements
27
26
 
28
27
  COMMAND = 'git rev-parse --abbrev-ref HEAD'.freeze
28
+ COMMIT_COMMAND = 'git rev-parse HEAD'.freeze
29
29
  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 CIRRUS_BRANCH}.freeze
30
30
  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 CIRRUS_CHANGE_IN_REPO}
31
31
  BUILD_URL_ENV_VAR_NAMES = %w{BUILDKITE_BUILD_URL CIRCLE_BUILD_URL TRAVIS_BUILD_WEB_URL BUILD_URL }
32
32
 
33
- def self.commit
34
- find_commit_from_env_vars
33
+ def self.commit(options)
34
+ find_commit_from_env_vars || commit_from_git_command(options[:raise_error])
35
35
  end
36
36
 
37
37
  def self.branch(options)
38
38
  find_branch_from_known_env_vars || find_branch_from_env_var_ending_with_branch || branch_from_git_command(options[:raise_error])
39
39
  end
40
40
 
41
+ # This does not belong in the Git module.
42
+ # TODO move it.
41
43
  def self.build_url
42
44
  github_build_url || BUILD_URL_ENV_VAR_NAMES.collect{ | name | value_from_env_var(name) }.compact.first
43
45
  end
@@ -79,6 +81,10 @@ module PactBroker
79
81
  branch_names.size == 1 ? branch_names[0] : nil
80
82
  end
81
83
 
84
+ def self.commit_from_git_command(raise_error)
85
+ execute_git_commit_command(raise_error)
86
+ end
87
+
82
88
  def self.validate_branch_names(branch_names)
83
89
  if branch_names.size == 0
84
90
  raise PactBroker::Client::Error, "Command `#{COMMAND}` didn't return anything that could be identified as the current branch."
@@ -93,6 +99,17 @@ module PactBroker
93
99
  `#{COMMAND}`
94
100
  end
95
101
 
102
+ def self.execute_git_commit_command(raise_error)
103
+ `#{COMMIT_COMMAND}`
104
+ rescue StandardError => e
105
+ if raise_error
106
+ raise PactBroker::Client::Error,
107
+ "Could not determine current git commit using command `#{COMMIT_COMMAND}`. #{e.class} #{e.message}"
108
+ else
109
+ return nil
110
+ end
111
+ end
112
+
96
113
  def self.execute_and_parse_command(raise_error)
97
114
  execute_git_command
98
115
  .split("\n")
@@ -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
@@ -53,14 +53,17 @@ module PactBroker
53
53
  end
54
54
 
55
55
  def almost_duplicate_message(original, new_interaction)
56
- "Two interactions have been found with same description (#{new_interaction[:description].inspect}) and provider state (#{new_interaction[:providerState].inspect}) but a different request or response. " +
56
+ "Two interactions have been found with same description (#{new_interaction[:description].inspect}) and provider state (#{(new_interaction[:providerState] || new_interaction[:providerStates]).inspect}) but a different request or response. " +
57
57
  "Please use a different description or provider state, or hard-code any random data.\n\n" +
58
58
  original.to_json + "\n\n" + new_interaction.to_json
59
59
  end
60
60
 
61
61
  def same_description_and_state? original, additional
62
62
  original[:description] == additional[:description] &&
63
- original[:providerState] == additional[:providerState]
63
+ (
64
+ (original[:providerState] && original[:providerState] == additional[:providerState]) ||
65
+ (original[:providerStates] && original[:providerStates] == additional[:providerStates])
66
+ )
64
67
  end
65
68
  end
66
69
  end
@@ -42,7 +42,7 @@ module PactBroker
42
42
 
43
43
  private
44
44
 
45
- attr_reader :pact_broker_base_url, :pact_file_paths, :consumer_version_number, :branch, :tags, :build_url, :pact_broker_client_options, :version_required
45
+ attr_reader :pact_broker_base_url, :pact_file_paths, :consumer_version_number, :branch, :tags, :build_url, :pact_broker_client_options
46
46
 
47
47
  def pact_broker_client
48
48
  @pact_broker_client ||= PactBroker::Client::PactBrokerClient.new(base_url: pact_broker_base_url, client_options: pact_broker_client_options)