pact_broker-client 1.61.1 → 1.62.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 302e6410c4705e3215f63cd3cde0d0f776f2509e06f286fd7dfc3ae6f7762fef
4
- data.tar.gz: af9abb55766a45839a59bebfb2dd4eb93698a3f12f207a24e94c8e93219ecc57
3
+ metadata.gz: 03d1e24dc52514c490a7d3aa1825ae71cba4e313662d7bab06d23091c42d9686
4
+ data.tar.gz: 7f66cf8204b1089c896d3ea3294a926a5dc5c4c0b8b8cc20ef74306f96fe4e0c
5
5
  SHA512:
6
- metadata.gz: 7cdd9bffc84f8c5ff9a012732510dd9a5df4afe1d8c9bfe538b7173d1b92382982ce4ecde02a57b8fc2968ce83a7c4c6e882f882d9c872a48dcf329f97b059e0
7
- data.tar.gz: 3739ba7cd7295b088f5ff0b457c37f7eeb93ce4e03dc1e826b4f924e216d90ae00c04f8def2e32cf8a440f8ad3ea907da2e17908021b17d1b9231df736c6ae7d
6
+ metadata.gz: 30f083d1dc9c6effdd2cd9972ca252551ba3f13ce44dbe42f150fe11195a653a40aff596baa16f85dec1994a85161a0564a3ca822d9fb4286fa5ea0086bedc84
7
+ data.tar.gz: 75b6386136cfc65d1487cc2a4428195dc4655143e7cc81a8c033cb7723a3986fc8691bacf0c078658200d2930ae3ff619b0774cb67e5235c3fea0c96d01d426f
data/CHANGELOG.md CHANGED
@@ -1,3 +1,14 @@
1
+ <a name="v1.62.0"></a>
2
+ ### v1.62.0 (2022-05-10)
3
+
4
+ #### Features
5
+
6
+ * add command to publish provider contracts to pactflow (feature toggle required) (#107) ([80cc10e](/../../commit/80cc10e))
7
+
8
+ #### Bug Fixes
9
+
10
+ * use ruby < 2.3 syntax. (#108) ([20f1e01](/../../commit/20f1e01))
11
+
1
12
  <a name="v1.61.1"></a>
2
13
  ### v1.61.1 (2022-05-09)
3
14
 
data/bin/pactflow ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ require "pactflow/client/cli/pactflow"
3
+
4
+ Pactflow::Client::CLI::Pactflow.start
@@ -4,6 +4,8 @@
4
4
 
5
5
  * [A request for the index resource](#a_request_for_the_index_resource)
6
6
 
7
+ * [A request to create a provider contract](#a_request_to_create_a_provider_contract)
8
+
7
9
  * [A request to create a webhook for a team](#a_request_to_create_a_webhook_for_a_team_given_a_team_with_UUID_2abbc12a-427d-432a-a521-c870af1739d9_exists) given a team with UUID 2abbc12a-427d-432a-a521-c870af1739d9 exists
8
10
 
9
11
  #### Interactions
@@ -41,6 +43,40 @@ Pactflow will respond with:
41
43
  }
42
44
  }
43
45
  ```
46
+ <a name="a_request_to_create_a_provider_contract"></a>
47
+ Upon receiving **a request to create a provider contract** from Pact Broker Client, with
48
+ ```json
49
+ {
50
+ "method": "put",
51
+ "path": "/contracts/provider/Bar/version/1",
52
+ "headers": {
53
+ "Content-Type": "application/json",
54
+ "Accept": "application/hal+json"
55
+ },
56
+ "body": {
57
+ "content": "LS0tCjpzb21lOiBjb250cmFjdAo=",
58
+ "contractType": "oas",
59
+ "contentType": "application/yaml",
60
+ "verificationResults": {
61
+ "success": true,
62
+ "content": "c29tZSByZXN1bHRz",
63
+ "contentType": "text/plain",
64
+ "format": "text",
65
+ "verifier": "my custom tool",
66
+ "verifierVersion": "1.0"
67
+ }
68
+ }
69
+ }
70
+ ```
71
+ Pactflow will respond with:
72
+ ```json
73
+ {
74
+ "status": 201,
75
+ "headers": {
76
+ "Content-Type": "application/hal+json;charset=utf-8"
77
+ }
78
+ }
79
+ ```
44
80
  <a name="a_request_to_create_a_webhook_for_a_team_given_a_team_with_UUID_2abbc12a-427d-432a-a521-c870af1739d9_exists"></a>
45
81
  Given **a team with UUID 2abbc12a-427d-432a-a521-c870af1739d9 exists**, upon receiving **a request to create a webhook for a team** from Pact Broker Client, with
46
82
  ```json
@@ -8,6 +8,10 @@ module PactBroker
8
8
  PactBroker::Client::Hal::EntryPoint.new(pact_broker_base_url, create_http_client(pact_broker_client_options))
9
9
  end
10
10
 
11
+ def create_entry_point(entry_point, pact_broker_client_options)
12
+ PactBroker::Client::Hal::EntryPoint.new(entry_point, create_http_client(pact_broker_client_options))
13
+ end
14
+
11
15
  def create_http_client(pact_broker_client_options)
12
16
  PactBroker::Client::Hal::HttpClient.new(pact_broker_client_options.merge(pact_broker_client_options[:basic_auth] || {}))
13
17
  end
@@ -1,5 +1,5 @@
1
1
  module PactBroker
2
2
  module Client
3
- VERSION = '1.61.1'
3
+ VERSION = '1.62.0'
4
4
  end
5
5
  end
@@ -0,0 +1,12 @@
1
+ require "pactflow/client/cli/provider_contract_commands"
2
+ require "pact_broker/client/cli/custom_thor"
3
+
4
+ module Pactflow
5
+ module Client
6
+ module CLI
7
+ class Pactflow < PactBroker::Client::CLI::CustomThor
8
+ include ::Pactflow::Client::CLI::ProviderContractCommands
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,68 @@
1
+ require "pact_broker/client/hash_refinements"
2
+
3
+ module Pactflow
4
+ module Client
5
+ module CLI
6
+ module ProviderContractCommands
7
+ using PactBroker::Client::HashRefinements
8
+
9
+ def self.included(thor)
10
+ thor.class_eval do
11
+
12
+ if ENV.fetch("PACTFLOW_FEATURES", "").include?("publish-provider-contract")
13
+
14
+ desc 'publish-provider-contract CONTRACT_FILE ...', "Publish provider contract to Pactflow"
15
+ method_option :provider, required: true, desc: "The provider name"
16
+ method_option :provider_app_version, required: true, aliases: "-a", desc: "The provider application version"
17
+ method_option :branch, aliases: "-h", desc: "Repository branch of the provider version"
18
+ #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."
19
+ method_option :tag, aliases: "-t", type: :array, banner: "TAG", desc: "Tag name for provider version. Can be specified multiple times."
20
+ #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"
21
+ method_option :specification, default: "oas", desc: "The contract specification"
22
+ method_option :content_type, desc: "The content type. eg. application/yml"
23
+ method_option :verification_success, type: :boolean
24
+ method_option :verification_results, desc: "The path to the file containing the output from the verification process"
25
+ method_option :verification_results_content_type, desc: "The content type of the verification output eg. text/plain, application/yaml"
26
+ method_option :verification_results_format, desc: "The format of the verification output eg. junit, text"
27
+ method_option :verifier, desc: "The tool used to verify the provider contract"
28
+ method_option :verifier_version, desc: "The version of the tool used to verify the provider contract"
29
+ #method_option :build_url, desc: "The build URL that created the pact"
30
+
31
+ output_option_json_or_text
32
+ shared_authentication_options
33
+
34
+ def publish_provider_contract(provider_contract_path)
35
+ require "pactflow/client/provider_contracts/publish"
36
+
37
+ params = params = {
38
+ provider_name: options.provider.strip,
39
+ provider_version_number: options.provider_app_version.strip,
40
+ branch_name: options.branch && options.branch.strip,
41
+ tags: (options.tag && options.tag.collect(&:strip)) || [],
42
+ contract: {
43
+ content: File.read(provider_contract_path),
44
+ content_type: options.content_type,
45
+ specification: options.specification
46
+ },
47
+ verification_results: {
48
+ success: options.verification_success,
49
+ content: options.verification_results ? File.read(options.verification_results) : nil,
50
+ content_type: options.verification_results_content_type,
51
+ format: options.verification_results_format,
52
+ verifier: options.verifier,
53
+ verifier_version: options.verifier_version
54
+ }
55
+ }
56
+
57
+ command_options = { verbose: options.verbose, output: options.output }
58
+ result = ::Pactflow::Client::ProviderContracts::Publish.call(params, command_options, pact_broker_client_options)
59
+ $stdout.puts result.message
60
+ exit(1) unless result.success
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,79 @@
1
+ require "pact_broker/client/base_command"
2
+ require "pact_broker/client/versions/create"
3
+ require "base64"
4
+
5
+ module Pactflow
6
+ module Client
7
+ module ProviderContracts
8
+ class Publish < PactBroker::Client::BaseCommand
9
+ attr_reader :branch_name, :tags, :provider_name, :provider_version_number, :contract, :verification_results
10
+
11
+ def initialize(params, options, pact_broker_client_options)
12
+ super
13
+ @provider_name = params[:provider_name]
14
+ @provider_version_number = params[:provider_version_number]
15
+ @branch_name = params[:branch_name]
16
+ @tags = params[:tags] || []
17
+ @contract = params[:contract]
18
+ @verification_results = params[:verification_results]
19
+ end
20
+
21
+ private
22
+
23
+ def do_call
24
+ create_branch_version_and_tags
25
+ create_contract
26
+ PactBroker::Client::CommandResult.new(true, green("Successfully published provider contract for #{provider_name} version #{provider_version_number}"))
27
+ end
28
+
29
+ def create_branch_version_and_tags
30
+ if branch_name || tags.any?
31
+ pacticipant_version_params = {
32
+ pacticipant_name: provider_name,
33
+ version_number: provider_version_number,
34
+ branch_name: branch_name,
35
+ tags: tags
36
+ }
37
+ result = PactBroker::Client::Versions::Create.call(pacticipant_version_params, options, pact_broker_client_options)
38
+ if !result.success
39
+ raise PactBroker::Client::Error.new(result.message)
40
+ end
41
+ end
42
+ end
43
+
44
+ def create_contract
45
+ contract_path = "#{pact_broker_base_url}/contracts/provider/{provider}/version/{version}"
46
+ entrypoint = create_entry_point(contract_path, pact_broker_client_options)
47
+ entrypoint.expand(provider: provider_name, version: provider_version_number).put!(contract_params)
48
+ end
49
+
50
+ def contract_params
51
+ verification_results_params = {
52
+ success: verification_results[:success],
53
+ content: verification_results[:content] ? encode_content(verification_results[:content]) : nil,
54
+ contentType: verification_results[:content_type],
55
+ format: verification_results[:format],
56
+ verifier: verification_results[:verifier],
57
+ verifierVersion: verification_results[:verifier_version]
58
+ }.compact
59
+
60
+ body_params = {
61
+ content: encode_content(contract[:content]),
62
+ contractType: contract[:specification],
63
+ contentType: contract[:content_type],
64
+ }.compact
65
+
66
+ if verification_results_params.any?
67
+ body_params[:verificationResults] = verification_results_params
68
+ end
69
+
70
+ body_params
71
+ end
72
+
73
+ def encode_content oas
74
+ Base64.strict_encode64(oas)
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
data/script/oas.yml ADDED
@@ -0,0 +1,49 @@
1
+ openapi: 3.0.0
2
+ info:
3
+ title: Sample API
4
+ description: Optional multiline or single-line description in [CommonMark](http://commonmark.org/help/) or HTML.
5
+ version: 0.1.9
6
+ servers:
7
+ - url: https://test.pactflow.io
8
+ description: Prod
9
+ - url: https://test.test.pactflow.io
10
+ description: Test
11
+ paths:
12
+ /admin/teams/{uuid}:
13
+ get:
14
+ summary: Returns a team
15
+ parameters:
16
+ - name: uuid
17
+ in: path
18
+ description: The UUID of the team to return
19
+ required: true
20
+ example: 85ad09f5-e014-4e0f-a146-4377fa64b5ef
21
+ schema:
22
+ type: string
23
+ responses:
24
+ '200':
25
+ description: A JSON team
26
+ content:
27
+ application/json:
28
+ schema:
29
+ type: object
30
+ additionalProperties: false
31
+ properties:
32
+ name:
33
+ type: string
34
+ example: Team Awesome
35
+ uuid:
36
+ type: string
37
+ example: 85ad09f5-e014-4e0f-a146-4377fa64b5ef
38
+ numberOfMembers:
39
+ type: integer
40
+ example: 4
41
+ _links:
42
+ type: object
43
+ properties:
44
+ self:
45
+ type: object
46
+ properties:
47
+ href:
48
+ type: string
49
+ example: http://test.pactflow.io/admin/teams/85ad09f5-e014-4e0f-a146-4377fa64b5ef
@@ -0,0 +1,27 @@
1
+ export PACT_BROKER_BASE_URL="http://localhost:9292"
2
+ export PACTFLOW_FEATURES=publish-provider-contract
3
+ # bundle exec bin/pactflow publish-provider-contract \
4
+ # script/oas.yml \
5
+ # --provider Foo \
6
+ # --provider-app-version 1013b5650d61214e19f10558f97fb5a3bb082d44 \
7
+ # --branch main \
8
+ # --tag dev \
9
+ # --specification oas \
10
+ # --content-type application/yml \
11
+ # --no-verification-success \
12
+ # --verification-results script/verification-results.txt \
13
+ # --verification-results-content-type text/plain \
14
+ # --verification-results-format text \
15
+ # --verifier my-custom-tool \
16
+ # --verifier-version "1.0" \
17
+ # --verbose
18
+
19
+
20
+ bundle exec bin/pactflow publish-provider-contract \
21
+ script/oas.yml \
22
+ --provider Foo \
23
+ --provider-app-version 1013b5650d61214e19f10558f97fb5a3bb082d44 \
24
+ --branch main \
25
+ --tag dev \
26
+ --specification oas \
27
+ --content-type application/yml
@@ -0,0 +1 @@
1
+ These are some results.
@@ -6,6 +6,36 @@
6
6
  "name": "Pactflow"
7
7
  },
8
8
  "interactions": [
9
+ {
10
+ "description": "a request to create a provider contract",
11
+ "request": {
12
+ "method": "put",
13
+ "path": "/contracts/provider/Bar/version/1",
14
+ "headers": {
15
+ "Content-Type": "application/json",
16
+ "Accept": "application/hal+json"
17
+ },
18
+ "body": {
19
+ "content": "LS0tCjpzb21lOiBjb250cmFjdAo=",
20
+ "contractType": "oas",
21
+ "contentType": "application/yaml",
22
+ "verificationResults": {
23
+ "success": true,
24
+ "content": "c29tZSByZXN1bHRz",
25
+ "contentType": "text/plain",
26
+ "format": "text",
27
+ "verifier": "my custom tool",
28
+ "verifierVersion": "1.0"
29
+ }
30
+ }
31
+ },
32
+ "response": {
33
+ "status": 201,
34
+ "headers": {
35
+ "Content-Type": "application/hal+json;charset=utf-8"
36
+ }
37
+ }
38
+ },
9
39
  {
10
40
  "description": "a request for the index resource",
11
41
  "request": {
@@ -0,0 +1,92 @@
1
+ require_relative "pact_helper"
2
+ require "pactflow/client/provider_contracts/publish"
3
+ require "yaml"
4
+
5
+ RSpec.describe "publishing a provider contract to Pactflow", pact: true do
6
+ before do
7
+ # no point re-testing this
8
+ allow(PactBroker::Client::Versions::Create).to receive(:call).and_return(double("result", success: true))
9
+ end
10
+
11
+ include_context "pact broker"
12
+ include PactBrokerPactHelperMethods
13
+
14
+ let(:command_params) do
15
+ {
16
+ provider_name: "Bar",
17
+ provider_version_number: "1",
18
+ branch_name: "main",
19
+ tags: ["dev"],
20
+ contract: {
21
+ content: { some: "contract" }.to_yaml,
22
+ content_type: "application/yaml",
23
+ specification: "oas"
24
+ },
25
+ verification_results: {
26
+ success: true,
27
+ content: "some results",
28
+ content_type: "text/plain",
29
+ format: "text",
30
+ verifier: "my custom tool",
31
+ verifier_version: "1.0"
32
+ }
33
+ }
34
+ end
35
+
36
+ let(:body) { { some: "body" }.to_json }
37
+
38
+ let(:request_body) do
39
+ {
40
+ "content" => "LS0tCjpzb21lOiBjb250cmFjdAo=",
41
+ "contractType" => "oas",
42
+ "contentType" => "application/yaml",
43
+ "verificationResults" => {
44
+ "success" => true,
45
+ "content" => "c29tZSByZXN1bHRz",
46
+ "contentType" => "text/plain",
47
+ "format" => "text",
48
+ "verifier" => "my custom tool",
49
+ "verifierVersion" => "1.0"
50
+ }
51
+ }
52
+ end
53
+
54
+ let(:response_status) { 201 }
55
+ let(:success_response) do
56
+ {
57
+ status: response_status,
58
+ headers: pact_broker_response_headers
59
+ }
60
+ end
61
+
62
+ let(:options) do
63
+ {
64
+ verbose: false
65
+ }
66
+ end
67
+
68
+ let(:pact_broker_client_options) do
69
+ { pact_broker_base_url: pactflow.mock_service_base_url }
70
+ end
71
+
72
+ subject { Pactflow::Client::ProviderContracts::Publish.call(command_params, options, pact_broker_client_options) }
73
+
74
+ context "creating a provider contract with valid parameters" do
75
+ before do
76
+ pactflow
77
+ .upon_receiving("a request to create a provider contract")
78
+ .with(
79
+ method: :put,
80
+ path: "/contracts/provider/Bar/version/1",
81
+ headers: put_request_headers,
82
+ body: request_body)
83
+ .will_respond_with(success_response)
84
+ end
85
+
86
+ it "returns a CommandResult with success = true" do
87
+ expect(subject).to be_a PactBroker::Client::CommandResult
88
+ expect(subject.success).to be true
89
+ expect(subject.message).to include "Successfully published provider contract for Bar version 1"
90
+ end
91
+ end
92
+ 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.61.1
4
+ version: 1.62.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-09 00:00:00.000000000 Z
11
+ date: 2022-05-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httparty
@@ -204,6 +204,7 @@ email:
204
204
  - beth@bethesque.com
205
205
  executables:
206
206
  - pact-broker
207
+ - pactflow
207
208
  extensions: []
208
209
  extra_rdoc_files: []
209
210
  files:
@@ -220,6 +221,7 @@ files:
220
221
  - Rakefile
221
222
  - appveyor.yml
222
223
  - bin/pact-broker
224
+ - bin/pactflow
223
225
  - ci.sh
224
226
  - doc/CAN_I_DEPLOY_USAGE_WITH_TAGS.md
225
227
  - doc/pacts/markdown/Pact Broker Client - Pact Broker.md
@@ -314,17 +316,23 @@ files:
314
316
  - lib/pact_broker/client/webhooks/create.rb
315
317
  - lib/pact_broker/client/webhooks/test.rb
316
318
  - lib/pact_broker_client.rb
319
+ - lib/pactflow/client/cli/pactflow.rb
320
+ - lib/pactflow/client/cli/provider_contract_commands.rb
321
+ - lib/pactflow/client/provider_contracts/publish.rb
317
322
  - pact-broker-client.gemspec
318
323
  - script/approve-all.sh
319
324
  - script/can-i-deploy.sh
320
325
  - script/create-pacticipant.sh
326
+ - script/oas.yml
321
327
  - script/publish-pact.sh
328
+ - script/publish-provider-contract.sh
322
329
  - script/record-deployment.sh
323
330
  - script/record-deployments-and-releases.sh
324
331
  - script/record-undeployment.sh
325
332
  - script/release.sh
326
333
  - script/trigger-release.sh
327
334
  - script/update-cli-usage-in-readme.rb
335
+ - script/verification-results.txt
328
336
  - script/webhook-commands.sh
329
337
  - spec/fixtures/approvals/can_i_deploy_failure_dry_run.approved.txt
330
338
  - spec/fixtures/approvals/can_i_deploy_ignore.approved.txt
@@ -389,6 +397,7 @@ files:
389
397
  - spec/service_providers/pact_broker_client_tags_spec.rb
390
398
  - spec/service_providers/pact_broker_client_versions_spec.rb
391
399
  - spec/service_providers/pact_helper.rb
400
+ - spec/service_providers/pactflow_publish_provider_contract_spec.rb
392
401
  - spec/service_providers/pactflow_webhooks_create_spec.rb
393
402
  - spec/service_providers/pacticipants_create_spec.rb
394
403
  - spec/service_providers/publish_pacts_spec.rb
@@ -497,6 +506,7 @@ test_files:
497
506
  - spec/service_providers/pact_broker_client_tags_spec.rb
498
507
  - spec/service_providers/pact_broker_client_versions_spec.rb
499
508
  - spec/service_providers/pact_helper.rb
509
+ - spec/service_providers/pactflow_publish_provider_contract_spec.rb
500
510
  - spec/service_providers/pactflow_webhooks_create_spec.rb
501
511
  - spec/service_providers/pacticipants_create_spec.rb
502
512
  - spec/service_providers/publish_pacts_spec.rb