pact_broker-client 1.45.0 → 1.46.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: 99a06a67fbe9da6f970649c5159443669ed9ce419911e6178594944467255dd0
4
- data.tar.gz: c45dcfa2fd158febe01b9094e2125b4a1637c716da3a6d11d3bd13a8ce19867c
3
+ metadata.gz: fde8c782e40832e6e989a59a78e0bdedf62d117ceb4e44d322fe38e3911ff714
4
+ data.tar.gz: be91210f775ccf15d2bf49a2cecf3aebf1fc68133b87b5343224d75153b28254
5
5
  SHA512:
6
- metadata.gz: 6da2ec04fc73a54ae53bebc62ddb5ddfe1fe1db17b1f94d22a3e195edfb756ad6330e9a99ebfeb1a6f5d20be71c92df4c16c0a808a409623b9600fb59e2e6385
7
- data.tar.gz: c714b39a69e0f96ffccabe9b6bc3097c0401a6c1931a0de89e57eae7c1e0c04ef5133e1c3d124df49b2dd294bdd90fe2415baeba365e1bf44fc40b45b4602164
6
+ metadata.gz: 31ec264efd314d6cc03059f2eddfc5f0a842055e79c3d68fcbe20896619b6469aad06aa57e26c60585727d94443d7f5fd6e11626c14775e0dadb7fba63afbbe8
7
+ data.tar.gz: 1b78604dfa9f2860523432eea37d4943b7f222b685238ca60d0a8605e87afd42398f02568ddfd35ee330e3b055738db07a3331e800bc4ef839e63a1e2f6c26e5
data/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ <a name="v1.46.0"></a>
2
+ ### v1.46.0 (2021-06-24)
3
+
4
+ #### Features
5
+
6
+ * support specifying team UUID when creating a webhook in Pactflow ([c4201e1](/../../commit/c4201e1))
7
+
1
8
  <a name="v1.45.0"></a>
2
9
  ### v1.45.0 (2021-06-16)
3
10
 
data/README.md CHANGED
@@ -78,44 +78,44 @@ Usage:
78
78
  pact-broker can-i-deploy -a, --pacticipant=PACTICIPANT -b, --broker-base-url=BROKER_BASE_URL
79
79
 
80
80
  Options:
81
- -a, --pacticipant=PACTICIPANT
81
+ -a, --pacticipant=PACTICIPANT
82
82
  # The pacticipant name. Use once for each pacticipant being checked.
83
- -e, [--version=VERSION]
83
+ -e, [--version=VERSION]
84
84
  # The pacticipant version. Must be entered after the --pacticipant that it relates to.
85
- [--ignore=IGNORE]
86
- # The pacticipant name to ignore. Use once for each pacticipant being ignored.
87
- A specific version can be ignored by also specifying a --version after the
85
+ [--ignore=IGNORE]
86
+ # The pacticipant name to ignore. Use once for each pacticipant being ignored.
87
+ A specific version can be ignored by also specifying a --version after the
88
88
  pacticipant name option.
89
- -l, [--latest=[TAG]]
90
- # Use the latest pacticipant version. Optionally specify a TAG to use the
89
+ -l, [--latest=[TAG]]
90
+ # Use the latest pacticipant version. Optionally specify a TAG to use the
91
91
  latest version with the specified tag.
92
- [--to=TAG]
92
+ [--to=TAG]
93
93
  # This is too hard to explain in a short sentence. Look at the examples.
94
- -o, [--output=OUTPUT]
94
+ -o, [--output=OUTPUT]
95
95
  # json or table
96
-
96
+
97
97
  # Default: table
98
- [--retry-while-unknown=TIMES]
99
- # The number of times to retry while there is an unknown verification result
98
+ [--retry-while-unknown=TIMES]
99
+ # The number of times to retry while there is an unknown verification result
100
100
  (ie. the provider verification is likely still running)
101
-
101
+
102
102
  # Default: 0
103
- [--retry-interval=SECONDS]
103
+ [--retry-interval=SECONDS]
104
104
  # The time between retries in seconds. Use in conjuction with --retry-while-unknown
105
-
105
+
106
106
  # Default: 10
107
- [--dry-run], [--no-dry-run]
107
+ [--dry-run], [--no-dry-run]
108
108
  # When enabled, always exits process with a success code. Can also be enabled by setting
109
109
  the environment variable PACT_BROKER_CAN_I_DEPLOY_DRY_RUN=true.
110
- -b, --broker-base-url=BROKER_BASE_URL
110
+ -b, --broker-base-url=BROKER_BASE_URL
111
111
  # The base URL of the Pact Broker
112
- -u, [--broker-username=BROKER_USERNAME]
112
+ -u, [--broker-username=BROKER_USERNAME]
113
113
  # Pact Broker basic auth username
114
- -p, [--broker-password=BROKER_PASSWORD]
114
+ -p, [--broker-password=BROKER_PASSWORD]
115
115
  # Pact Broker basic auth password
116
- -k, [--broker-token=BROKER_TOKEN]
116
+ -k, [--broker-token=BROKER_TOKEN]
117
117
  # Pact Broker bearer token
118
- -v, [--verbose], [--no-verbose]
118
+ -v, [--verbose], [--no-verbose]
119
119
  # Verbose output. Default: false
120
120
  ```
121
121
 
@@ -235,27 +235,19 @@ Usage:
235
235
 
236
236
  Options:
237
237
  -X, --request=METHOD
238
- # HTTP method
238
+ # Webhook HTTP method
239
239
  -H, [--header=one two three]
240
- # Header
240
+ # Webhook Header
241
241
  -d, [--data=DATA]
242
- # Data
242
+ # Webhook payload (file or string)
243
243
  -u, [--user=USER]
244
- # Basic auth username and password eg. username:password
244
+ # Webhook basic auth username and password eg. username:password
245
245
  [--consumer=CONSUMER]
246
246
  # Consumer name
247
247
  [--provider=PROVIDER]
248
248
  # Provider name
249
- -b, --broker-base-url=BROKER_BASE_URL
250
- # The base URL of the Pact Broker
251
- [--broker-username=BROKER_USERNAME]
252
- # Pact Broker basic auth username
253
- -p, [--broker-password=BROKER_PASSWORD]
254
- # Pact Broker basic auth password
255
- -k, [--broker-token=BROKER_TOKEN]
256
- # Pact Broker bearer token
257
249
  [--description=DESCRIPTION]
258
- # The description of the webhook
250
+ # Webhook description
259
251
  [--contract-content-changed], [--no-contract-content-changed]
260
252
  # Trigger this webhook when the pact content changes
261
253
  [--contract-published], [--no-contract-published]
@@ -266,6 +258,16 @@ Options:
266
258
  # Trigger this webhook when a failed provider verification result is published
267
259
  [--provider-verification-succeeded], [--no-provider-verification-succeeded]
268
260
  # Trigger this webhook when a successful provider verification result is published
261
+ [--team-uuid=UUID]
262
+ # UUID of the Pactflow team to which the webhook should be assigned (Pactflow only)
263
+ -b, --broker-base-url=BROKER_BASE_URL
264
+ # The base URL of the Pact Broker
265
+ -u, [--broker-username=BROKER_USERNAME]
266
+ # Pact Broker basic auth username
267
+ -p, [--broker-password=BROKER_PASSWORD]
268
+ # Pact Broker basic auth password
269
+ -k, [--broker-token=BROKER_TOKEN]
270
+ # Pact Broker bearer token
269
271
  -v, [--verbose], [--no-verbose]
270
272
  # Verbose output. Default: false
271
273
 
@@ -283,27 +285,19 @@ Usage:
283
285
 
284
286
  Options:
285
287
  -X, --request=METHOD
286
- # HTTP method
288
+ # Webhook HTTP method
287
289
  -H, [--header=one two three]
288
- # Header
290
+ # Webhook Header
289
291
  -d, [--data=DATA]
290
- # Data
292
+ # Webhook payload (file or string)
291
293
  -u, [--user=USER]
292
- # Basic auth username and password eg. username:password
294
+ # Webhook basic auth username and password eg. username:password
293
295
  [--consumer=CONSUMER]
294
296
  # Consumer name
295
297
  [--provider=PROVIDER]
296
298
  # Provider name
297
- -b, --broker-base-url=BROKER_BASE_URL
298
- # The base URL of the Pact Broker
299
- [--broker-username=BROKER_USERNAME]
300
- # Pact Broker basic auth username
301
- -p, [--broker-password=BROKER_PASSWORD]
302
- # Pact Broker basic auth password
303
- -k, [--broker-token=BROKER_TOKEN]
304
- # Pact Broker bearer token
305
299
  [--description=DESCRIPTION]
306
- # The description of the webhook
300
+ # Webhook description
307
301
  [--contract-content-changed], [--no-contract-content-changed]
308
302
  # Trigger this webhook when the pact content changes
309
303
  [--contract-published], [--no-contract-published]
@@ -314,6 +308,16 @@ Options:
314
308
  # Trigger this webhook when a failed provider verification result is published
315
309
  [--provider-verification-succeeded], [--no-provider-verification-succeeded]
316
310
  # Trigger this webhook when a successful provider verification result is published
311
+ [--team-uuid=UUID]
312
+ # UUID of the Pactflow team to which the webhook should be assigned (Pactflow only)
313
+ -b, --broker-base-url=BROKER_BASE_URL
314
+ # The base URL of the Pact Broker
315
+ -u, [--broker-username=BROKER_USERNAME]
316
+ # Pact Broker basic auth username
317
+ -p, [--broker-password=BROKER_PASSWORD]
318
+ # Pact Broker basic auth password
319
+ -k, [--broker-token=BROKER_TOKEN]
320
+ # Pact Broker bearer token
317
321
  -v, [--verbose], [--no-verbose]
318
322
  # Verbose output. Default: false
319
323
  --uuid=UUID
@@ -2264,7 +2264,6 @@ Given **the 'Pricing Service' and 'Condor' already exist in the pact-broker**, u
2264
2264
  }
2265
2265
  ],
2266
2266
  "request": {
2267
- "url": null,
2268
2267
  "method": "POST",
2269
2268
  "headers": {
2270
2269
  "Foo": "bar",
@@ -0,0 +1,94 @@
1
+ ### A pact between Pact Broker Client and Pactflow
2
+
3
+ #### Requests from Pact Broker Client to Pactflow
4
+
5
+ * [A request for the index resource](#a_request_for_the_index_resource)
6
+
7
+ * [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
+
9
+ #### Interactions
10
+
11
+ <a name="a_request_for_the_index_resource"></a>
12
+ Upon receiving **a request for the index resource** from Pact Broker Client, with
13
+ ```json
14
+ {
15
+ "method": "get",
16
+ "path": "/",
17
+ "headers": {
18
+ "Accept": "application/hal+json"
19
+ }
20
+ }
21
+ ```
22
+ Pactflow will respond with:
23
+ ```json
24
+ {
25
+ "status": 200,
26
+ "headers": {
27
+ "Content-Type": "application/hal+json;charset=utf-8"
28
+ },
29
+ "body": {
30
+ "_links": {
31
+ "pb:webhooks": {
32
+ "href": "http://localhost:1235/HAL-REL-PLACEHOLDER-PB-WEBHOOKS"
33
+ },
34
+ "pb:pacticipants": {
35
+ "href": "http://localhost:1235/HAL-REL-PLACEHOLDER-PB-PACTICIPANTS"
36
+ },
37
+ "pb:pacticipant": {
38
+ "href": "http://localhost:1235/HAL-REL-PLACEHOLDER-PB-PACTICIPANT-{pacticipant}"
39
+ }
40
+ }
41
+ }
42
+ }
43
+ ```
44
+ <a name="a_request_to_create_a_webhook_for_a_team_given_a_team_with_UUID_2abbc12a-427d-432a-a521-c870af1739d9_exists"></a>
45
+ 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
+ ```json
47
+ {
48
+ "method": "post",
49
+ "path": "/HAL-REL-PLACEHOLDER-PB-WEBHOOKS",
50
+ "headers": {
51
+ "Content-Type": "application/json",
52
+ "Accept": "application/hal+json"
53
+ },
54
+ "body": {
55
+ "description": "a webhook",
56
+ "events": [
57
+ {
58
+ "name": "contract_content_changed"
59
+ }
60
+ ],
61
+ "request": {
62
+ "url": "https://webhook",
63
+ "method": "POST",
64
+ "headers": {
65
+ "Foo": "bar",
66
+ "Bar": "foo"
67
+ },
68
+ "body": {
69
+ "some": "body"
70
+ }
71
+ },
72
+ "teamUuid": "2abbc12a-427d-432a-a521-c870af1739d9"
73
+ }
74
+ }
75
+ ```
76
+ Pactflow will respond with:
77
+ ```json
78
+ {
79
+ "status": 201,
80
+ "headers": {
81
+ "Content-Type": "application/hal+json;charset=utf-8"
82
+ },
83
+ "body": {
84
+ "description": "a webhook",
85
+ "teamUuid": "2abbc12a-427d-432a-a521-c870af1739d9",
86
+ "_links": {
87
+ "self": {
88
+ "href": "http://localhost:1234/some-url",
89
+ "title": "A title"
90
+ }
91
+ }
92
+ }
93
+ }
94
+ ```
@@ -1,3 +1,4 @@
1
1
  ### Pacts for Pact Broker Client
2
2
 
3
3
  * [Pact Broker](Pact%20Broker%20Client%20-%20Pact%20Broker.md)
4
+ * [Pactflow](Pact%20Broker%20Client%20-%20Pactflow.md)
@@ -4,13 +4,13 @@ require 'thor/error'
4
4
  require 'pact_broker/client/cli/environment_commands'
5
5
  require 'pact_broker/client/cli/deployment_commands'
6
6
  require 'pact_broker/client/cli/pacticipant_commands'
7
+ require 'pact_broker/client/cli/webhook_commands'
7
8
 
8
9
  module PactBroker
9
10
  module Client
10
11
  module CLI
11
12
  # Thor::Error will have its backtrace hidden
12
13
  class PactPublicationError < ::Thor::Error; end
13
- class WebhookCreationError < ::Thor::Error; end
14
14
  class AuthError < ::Thor::Error; end
15
15
  class VersionCreationError < ::Thor::Error; end
16
16
 
@@ -21,6 +21,7 @@ module PactBroker
21
21
  include PactBroker::Client::CLI::DeploymentCommands
22
22
  end
23
23
  include PactBroker::Client::CLI::PacticipantCommands
24
+ include PactBroker::Client::CLI::WebhookCommands
24
25
 
25
26
 
26
27
  desc 'can-i-deploy', ''
@@ -131,31 +132,7 @@ module PactBroker
131
132
  exit(1) unless result.success
132
133
  end
133
134
 
134
- shared_options_for_webhook_commands
135
135
 
136
- desc 'create-webhook URL', 'Creates a webhook using the same switches as a curl request.'
137
- long_desc File.read(File.join(File.dirname(__FILE__), 'create_webhook_long_desc.txt'))
138
- def create_webhook webhook_url
139
- run_webhook_commands webhook_url
140
- end
141
-
142
- shared_options_for_webhook_commands
143
- method_option :uuid, type: :string, required: true, desc: "Specify the uuid for the webhook"
144
-
145
- desc 'create-or-update-webhook URL', 'Creates or updates a webhook with a provided uuid and using the same switches as a curl request.'
146
- long_desc File.read(File.join(File.dirname(__FILE__), 'create_or_update_webhook_long_desc.txt'))
147
- def create_or_update_webhook webhook_url
148
- run_webhook_commands webhook_url
149
- end
150
-
151
- desc 'test-webhook', 'Test the execution of a webhook'
152
- method_option :uuid, type: :string, required: true, desc: "Specify the uuid for the webhook"
153
- shared_authentication_options
154
- def test_webhook
155
- require 'pact_broker/client/webhooks/test'
156
- result = PactBroker::Client::Webhooks::Test.call(options, pact_broker_client_options)
157
- $stdout.puts result.message
158
- end
159
136
 
160
137
  ignored_and_hidden_potential_options_from_environment_variables
161
138
  desc 'generate-uuid', 'Generate a UUID for use when calling create-or-update-webhook'
@@ -297,64 +274,6 @@ module PactBroker
297
274
 
298
275
  client_options.compact
299
276
  end
300
-
301
- def parse_webhook_events
302
- events = []
303
- events << 'contract_content_changed' if options.contract_content_changed
304
- events << 'contract_published' if options.contract_published
305
- events << 'provider_verification_published' if options.provider_verification_published
306
- events << 'provider_verification_succeeded' if options.provider_verification_succeeded
307
- events << 'provider_verification_failed' if options.provider_verification_failed
308
- events
309
- end
310
-
311
- def parse_webhook_options(webhook_url)
312
- events = parse_webhook_events
313
-
314
- if events.size == 0
315
- raise WebhookCreationError.new("You must specify at least one of --contract-content-changed, --contract-published, --provider-verification-published, --provider-verification-succeeded or --provider-verification-failed")
316
- end
317
-
318
- username = options.user ? options.user.split(":", 2).first : nil
319
- password = options.user ? options.user.split(":", 2).last : nil
320
-
321
- headers = (options.header || []).each_with_object({}) { | header, headers | headers[header.split(":", 2).first.strip] = header.split(":", 2).last.strip }
322
-
323
- body = options.data
324
- if body && body.start_with?("@")
325
- filepath = body[1..-1]
326
- begin
327
- body = File.read(filepath)
328
- rescue StandardError => e
329
- raise WebhookCreationError.new("Couldn't read data from file \"#{filepath}\" due to #{e.class} #{e.message}")
330
- end
331
- end
332
-
333
- {
334
- uuid: options.uuid,
335
- description: options.description,
336
- http_method: options.request,
337
- url: webhook_url,
338
- headers: headers,
339
- username: username,
340
- password: password,
341
- body: body,
342
- consumer: options.consumer,
343
- provider: options.provider,
344
- events: events
345
- }
346
- end
347
-
348
- def run_webhook_commands webhook_url
349
- require 'pact_broker/client/webhooks/create'
350
-
351
- validate_credentials
352
- result = PactBroker::Client::Webhooks::Create.call(parse_webhook_options(webhook_url), options.broker_base_url, pact_broker_client_options)
353
- $stdout.puts result.message
354
- exit(1) unless result.success
355
- rescue PactBroker::Client::Error => e
356
- raise WebhookCreationError, "#{e.class} - #{e.message}"
357
- end
358
277
  end
359
278
  end
360
279
  end
@@ -91,22 +91,6 @@ module PactBroker
91
91
  method_option :verbose, aliases: "-v", type: :boolean, default: false, required: false, desc: "Verbose output. Default: false"
92
92
  end
93
93
 
94
- def self.shared_options_for_webhook_commands
95
- method_option :request, banner: "METHOD", aliases: "-X", desc: "Webhook HTTP method", required: true
96
- method_option :header, aliases: "-H", type: :array, desc: "Webhook Header"
97
- method_option :data, aliases: "-d", desc: "Webhook payload (file or string)"
98
- method_option :user, aliases: "-u", desc: "Webhook basic auth username and password eg. username:password"
99
- method_option :consumer, desc: "Consumer name"
100
- method_option :provider, desc: "Provider name"
101
- method_option :description, desc: "Wwebhook description"
102
- method_option :contract_content_changed, type: :boolean, desc: "Trigger this webhook when the pact content changes"
103
- method_option :contract_published, type: :boolean, desc: "Trigger this webhook when a pact is published"
104
- method_option :provider_verification_published, type: :boolean, desc: "Trigger this webhook when a provider verification result is published"
105
- method_option :provider_verification_failed, type: :boolean, desc: "Trigger this webhook when a failed provider verification result is published"
106
- method_option :provider_verification_succeeded, type: :boolean, desc: "Trigger this webhook when a successful provider verification result is published"
107
- shared_authentication_options
108
- end
109
-
110
94
  def self.verbose_option
111
95
  method_option :verbose, aliases: "-v", type: :boolean, default: false, required: false, desc: "Verbose output. Default: false"
112
96
  end
@@ -0,0 +1,122 @@
1
+ module PactBroker
2
+ module Client
3
+ module CLI
4
+ # Thor::Error will have its backtrace hidden
5
+ class WebhookCreationError < ::Thor::Error; end
6
+
7
+ module WebhookCommands
8
+ def self.included(thor)
9
+ thor.class_eval do
10
+
11
+ no_commands do
12
+ def self.shared_options_for_webhook_commands
13
+ method_option :request, banner: "METHOD", aliases: "-X", desc: "Webhook HTTP method", required: true
14
+ method_option :header, aliases: "-H", type: :array, desc: "Webhook Header"
15
+ method_option :data, aliases: "-d", desc: "Webhook payload (file or string)"
16
+ method_option :user, aliases: "-u", desc: "Webhook basic auth username and password eg. username:password"
17
+ method_option :consumer, desc: "Consumer name"
18
+ method_option :provider, desc: "Provider name"
19
+ method_option :description, desc: "Webhook description"
20
+ method_option :contract_content_changed, type: :boolean, desc: "Trigger this webhook when the pact content changes"
21
+ method_option :contract_published, type: :boolean, desc: "Trigger this webhook when a pact is published"
22
+ method_option :provider_verification_published, type: :boolean, desc: "Trigger this webhook when a provider verification result is published"
23
+ method_option :provider_verification_failed, type: :boolean, desc: "Trigger this webhook when a failed provider verification result is published"
24
+ method_option :provider_verification_succeeded, type: :boolean, desc: "Trigger this webhook when a successful provider verification result is published"
25
+ method_option :team_uuid, banner: "UUID", desc: "UUID of the Pactflow team to which the webhook should be assigned (Pactflow only)"
26
+ shared_authentication_options
27
+ end
28
+ end
29
+
30
+ shared_options_for_webhook_commands
31
+
32
+ desc 'create-webhook URL', 'Creates a webhook using the same switches as a curl request.'
33
+ long_desc File.read(File.join(File.dirname(__FILE__), 'create_webhook_long_desc.txt'))
34
+ def create_webhook webhook_url
35
+ run_webhook_commands webhook_url
36
+ end
37
+
38
+ shared_options_for_webhook_commands
39
+ method_option :uuid, type: :string, required: true, desc: "Specify the uuid for the webhook"
40
+
41
+ desc 'create-or-update-webhook URL', 'Creates or updates a webhook with a provided uuid and using the same switches as a curl request.'
42
+ long_desc File.read(File.join(File.dirname(__FILE__), 'create_or_update_webhook_long_desc.txt'))
43
+ def create_or_update_webhook webhook_url
44
+ run_webhook_commands webhook_url
45
+ end
46
+
47
+ desc 'test-webhook', 'Test the execution of a webhook'
48
+ method_option :uuid, type: :string, required: true, desc: "Specify the uuid for the webhook"
49
+ shared_authentication_options
50
+ def test_webhook
51
+ require 'pact_broker/client/webhooks/test'
52
+ result = PactBroker::Client::Webhooks::Test.call(options, pact_broker_client_options)
53
+ $stdout.puts result.message
54
+ end
55
+
56
+ no_commands do
57
+
58
+ def parse_webhook_events
59
+ events = []
60
+ events << 'contract_content_changed' if options.contract_content_changed
61
+ events << 'contract_published' if options.contract_published
62
+ events << 'provider_verification_published' if options.provider_verification_published
63
+ events << 'provider_verification_succeeded' if options.provider_verification_succeeded
64
+ events << 'provider_verification_failed' if options.provider_verification_failed
65
+ events
66
+ end
67
+
68
+ def parse_webhook_options(webhook_url)
69
+ events = parse_webhook_events
70
+
71
+ if events.size == 0
72
+ raise WebhookCreationError.new("You must specify at least one of --contract-content-changed, --contract-published, --provider-verification-published, --provider-verification-succeeded or --provider-verification-failed")
73
+ end
74
+
75
+ username = options.user ? options.user.split(":", 2).first : nil
76
+ password = options.user ? options.user.split(":", 2).last : nil
77
+
78
+ headers = (options.header || []).each_with_object({}) { | header, headers | headers[header.split(":", 2).first.strip] = header.split(":", 2).last.strip }
79
+
80
+ body = options.data
81
+ if body && body.start_with?("@")
82
+ filepath = body[1..-1]
83
+ begin
84
+ body = File.read(filepath)
85
+ rescue StandardError => e
86
+ raise WebhookCreationError.new("Couldn't read data from file \"#{filepath}\" due to #{e.class} #{e.message}")
87
+ end
88
+ end
89
+
90
+ {
91
+ uuid: options.uuid,
92
+ description: options.description,
93
+ http_method: options.request,
94
+ url: webhook_url,
95
+ headers: headers,
96
+ username: username,
97
+ password: password,
98
+ body: body,
99
+ consumer: options.consumer,
100
+ provider: options.provider,
101
+ events: events,
102
+ team_uuid: options.team_uuid
103
+ }
104
+ end
105
+
106
+ def run_webhook_commands webhook_url
107
+ require 'pact_broker/client/webhooks/create'
108
+
109
+ validate_credentials
110
+ result = PactBroker::Client::Webhooks::Create.call(parse_webhook_options(webhook_url), options.broker_base_url, pact_broker_client_options)
111
+ $stdout.puts result.message
112
+ exit(1) unless result.success
113
+ rescue PactBroker::Client::Error => e
114
+ raise WebhookCreationError, "#{e.class} - #{e.message}"
115
+ end
116
+ end
117
+ end
118
+ end
119
+ end
120
+ end
121
+ end
122
+ end
@@ -1,5 +1,5 @@
1
1
  module PactBroker
2
2
  module Client
3
- VERSION = '1.45.0'
3
+ VERSION = '1.46.0'
4
4
  end
5
5
  end
@@ -3,6 +3,7 @@ require 'pact_broker/client/hal'
3
3
  require 'ostruct'
4
4
  require 'json'
5
5
  require 'pact_broker/client/command_result'
6
+ require "pact_broker/client/backports"
6
7
 
7
8
  module PactBroker
8
9
  module Client
@@ -61,16 +62,17 @@ module PactBroker
61
62
 
62
63
  def request_body
63
64
  webhook_request_body = JSON.parse(params.body) rescue params.body
65
+ request_params = {
66
+ url: params.url,
67
+ method: params.http_method,
68
+ headers: params.headers,
69
+ body: webhook_request_body,
70
+ username: params.username,
71
+ password: params.password
72
+ }.compact
64
73
  {
65
74
  events: params.events.collect{ | event | { "name" => event }},
66
- request: {
67
- url: params.url,
68
- method: params.http_method,
69
- headers: params.headers,
70
- body: webhook_request_body,
71
- username: params.username,
72
- password: params.password
73
- }
75
+ request: request_params
74
76
  }.tap { |req| req[:description] = params.description if params.description }
75
77
  end
76
78
 
@@ -85,6 +87,10 @@ module PactBroker
85
87
  body[:provider] = { name: params.provider }
86
88
  end
87
89
 
90
+ if params.team_uuid
91
+ body[:teamUuid] = params.team_uuid
92
+ end
93
+
88
94
  body
89
95
  end
90
96
 
@@ -0,0 +1,12 @@
1
+ #!/bin/sh
2
+
3
+ bundle exec bin/pact-broker create-webhook \
4
+ 'https://api.github.com/repos/foo/bar/statuses/${pactbroker.consumerVersionNumber}' \
5
+ -X POST \
6
+ -H "Content-Type: application/json" \
7
+ -d '{ "state": "${pactbroker.githubVerificationStatus}", "description": "Pact Verification Tests ${pactbroker.providerVersionTags}", "context": "${pactbroker.providerName}", "target_url": "${pactbroker.verificationResultUrl}" }' \
8
+ --user username:password \
9
+ --description "Publish pact verification status to Github" \
10
+ --contract-published \
11
+ --provider-verification-published \
12
+ --team-uuid 4ac05ed8-9e3b-4159-96c0-ad19e3b93658
@@ -33,7 +33,8 @@ module PactBroker
33
33
  broker_username: "username",
34
34
  broker_password: "password",
35
35
  contract_content_changed: true,
36
- verbose: true
36
+ verbose: true,
37
+ team_uuid: "1234"
37
38
  }
38
39
  end
39
40
 
@@ -49,7 +50,8 @@ module PactBroker
49
50
  body: "data",
50
51
  consumer: "consumer",
51
52
  provider: "provider",
52
- events: ["contract_content_changed"]
53
+ events: ["contract_content_changed"],
54
+ team_uuid: "1234"
53
55
  }.tap { |it| Pact::Fixture.add_fixture(:create_webhook_params, it) }
54
56
  end
55
57
 
@@ -1846,7 +1846,6 @@
1846
1846
  }
1847
1847
  ],
1848
1848
  "request": {
1849
- "url": null,
1850
1849
  "method": "POST",
1851
1850
  "headers": {
1852
1851
  "Foo": "bar",
@@ -0,0 +1,118 @@
1
+ {
2
+ "consumer": {
3
+ "name": "Pact Broker Client"
4
+ },
5
+ "provider": {
6
+ "name": "Pactflow"
7
+ },
8
+ "interactions": [
9
+ {
10
+ "description": "a request for the index resource",
11
+ "request": {
12
+ "method": "get",
13
+ "path": "/",
14
+ "headers": {
15
+ "Accept": "application/hal+json"
16
+ }
17
+ },
18
+ "response": {
19
+ "status": 200,
20
+ "headers": {
21
+ "Content-Type": "application/hal+json;charset=utf-8"
22
+ },
23
+ "body": {
24
+ "_links": {
25
+ "pb:webhooks": {
26
+ "href": "http://localhost:1235/HAL-REL-PLACEHOLDER-PB-WEBHOOKS"
27
+ },
28
+ "pb:pacticipants": {
29
+ "href": "http://localhost:1235/HAL-REL-PLACEHOLDER-PB-PACTICIPANTS"
30
+ },
31
+ "pb:pacticipant": {
32
+ "href": "http://localhost:1235/HAL-REL-PLACEHOLDER-PB-PACTICIPANT-{pacticipant}"
33
+ }
34
+ }
35
+ },
36
+ "matchingRules": {
37
+ "$.body._links.pb:webhooks.href": {
38
+ "match": "regex",
39
+ "regex": "http:\\/\\/.*"
40
+ },
41
+ "$.body._links.pb:pacticipants.href": {
42
+ "match": "regex",
43
+ "regex": "http:\\/\\/.*"
44
+ },
45
+ "$.body._links.pb:pacticipant.href": {
46
+ "match": "regex",
47
+ "regex": "http:\\/\\/.*{pacticipant}"
48
+ }
49
+ }
50
+ }
51
+ },
52
+ {
53
+ "description": "a request to create a webhook for a team",
54
+ "providerState": "a team with UUID 2abbc12a-427d-432a-a521-c870af1739d9 exists",
55
+ "request": {
56
+ "method": "post",
57
+ "path": "/HAL-REL-PLACEHOLDER-PB-WEBHOOKS",
58
+ "headers": {
59
+ "Content-Type": "application/json",
60
+ "Accept": "application/hal+json"
61
+ },
62
+ "body": {
63
+ "description": "a webhook",
64
+ "events": [
65
+ {
66
+ "name": "contract_content_changed"
67
+ }
68
+ ],
69
+ "request": {
70
+ "url": "https://webhook",
71
+ "method": "POST",
72
+ "headers": {
73
+ "Foo": "bar",
74
+ "Bar": "foo"
75
+ },
76
+ "body": {
77
+ "some": "body"
78
+ }
79
+ },
80
+ "teamUuid": "2abbc12a-427d-432a-a521-c870af1739d9"
81
+ }
82
+ },
83
+ "response": {
84
+ "status": 201,
85
+ "headers": {
86
+ "Content-Type": "application/hal+json;charset=utf-8"
87
+ },
88
+ "body": {
89
+ "description": "a webhook",
90
+ "teamUuid": "2abbc12a-427d-432a-a521-c870af1739d9",
91
+ "_links": {
92
+ "self": {
93
+ "href": "http://localhost:1234/some-url",
94
+ "title": "A title"
95
+ }
96
+ }
97
+ },
98
+ "matchingRules": {
99
+ "$.body.description": {
100
+ "match": "type"
101
+ },
102
+ "$.body._links.self.href": {
103
+ "match": "regex",
104
+ "regex": "http:\\/\\/.*"
105
+ },
106
+ "$.body._links.self.title": {
107
+ "match": "type"
108
+ }
109
+ }
110
+ }
111
+ }
112
+ ],
113
+ "metadata": {
114
+ "pactSpecification": {
115
+ "version": "2.0.0"
116
+ }
117
+ }
118
+ }
@@ -8,7 +8,6 @@ Pact.configure do | config |
8
8
  end
9
9
 
10
10
  Pact.service_consumer 'Pact Broker Client' do
11
-
12
11
  has_pact_with "Pact Broker" do
13
12
  mock_service :pact_broker do
14
13
  port 1234
@@ -16,6 +15,12 @@ Pact.service_consumer 'Pact Broker Client' do
16
15
  end
17
16
  end
18
17
 
18
+ has_pact_with "Pactflow" do
19
+ mock_service :pactflow do
20
+ port 1235
21
+ pact_specification_version "2.0"
22
+ end
23
+ end
19
24
  end
20
25
 
21
26
  module PactBrokerPactHelperMethods
@@ -30,22 +35,22 @@ module PactBrokerPactHelperMethods
30
35
  path
31
36
  end
32
37
 
33
- def placeholder_url(relation, params = [])
34
- "#{pact_broker.mock_service_base_url}#{placeholder_path(relation, params)}"
38
+ def placeholder_url(relation, params = [], mock_service = pact_broker)
39
+ "#{mock_service.mock_service_base_url}#{placeholder_path(relation, params)}"
35
40
  end
36
41
 
37
- def placeholder_url_term(relation, params = [])
42
+ def placeholder_url_term(relation, params = [], mock_service = pact_broker)
38
43
  regexp = "http:\/\/.*"
39
44
  if params.any?
40
45
  joined_params_for_regexp = params.collect{ |param| "{#{param}}"}.join(".*")
41
46
  regexp = "#{regexp}#{joined_params_for_regexp}"
42
47
  end
43
48
 
44
- Pact.term(placeholder_url(relation, params), /#{regexp}/)
49
+ Pact.term(placeholder_url(relation, params, mock_service), /#{regexp}/)
45
50
  end
46
51
 
47
- def mock_pact_broker_index(context)
48
- pact_broker
52
+ def mock_pact_broker_index(context, mock_service = pact_broker)
53
+ mock_service
49
54
  .upon_receiving("a request for the index resource")
50
55
  .with(
51
56
  method: :get,
@@ -57,13 +62,13 @@ module PactBrokerPactHelperMethods
57
62
  body: {
58
63
  _links: {
59
64
  :'pb:webhooks' => {
60
- href: placeholder_url_term('pb:webhooks')
65
+ href: placeholder_url_term('pb:webhooks', [], mock_service)
61
66
  },
62
67
  :'pb:pacticipants' => {
63
- href: placeholder_url_term('pb:pacticipants')
68
+ href: placeholder_url_term('pb:pacticipants', [], mock_service)
64
69
  },
65
70
  :'pb:pacticipant' => {
66
- href: placeholder_url_term('pb:pacticipant', ['pacticipant'])
71
+ href: placeholder_url_term('pb:pacticipant', ['pacticipant'], mock_service)
67
72
  }
68
73
  }
69
74
  }
@@ -0,0 +1,86 @@
1
+ require_relative 'pact_helper'
2
+ require 'pact_broker/client/webhooks/create'
3
+
4
+ RSpec.describe "creating a webhook in Pactflow", pact: true do
5
+
6
+ include_context "pact broker"
7
+ include PactBrokerPactHelperMethods
8
+
9
+ let(:params) do
10
+ {
11
+ description: "a webhook",
12
+ events: %w{contract_content_changed},
13
+ http_method: "POST",
14
+ url: "https://webhook",
15
+ headers: { "Foo" => "bar", "Bar" => "foo"},
16
+ body: body,
17
+ team_uuid: "2abbc12a-427d-432a-a521-c870af1739d9"
18
+ }
19
+ end
20
+
21
+ let(:body) { { some: "body" }.to_json }
22
+
23
+ let(:request_body) do
24
+ {
25
+ "description" => "a webhook",
26
+ "events" => [
27
+ "name" => "contract_content_changed"
28
+ ],
29
+ "request" => {
30
+ "url" => "https://webhook",
31
+ "method" => "POST",
32
+ "headers" => {
33
+ "Foo" => "bar",
34
+ "Bar" => "foo"
35
+ },
36
+ "body" => {
37
+ "some" => "body"
38
+ },
39
+ },
40
+ "teamUuid" => "2abbc12a-427d-432a-a521-c870af1739d9"
41
+ }
42
+ end
43
+
44
+ let(:response_status) { 201 }
45
+ let(:success_response) do
46
+ {
47
+ status: response_status,
48
+ headers: pact_broker_response_headers,
49
+ body: {
50
+ description: Pact.like("a webhook"),
51
+ teamUuid: "2abbc12a-427d-432a-a521-c870af1739d9",
52
+ _links: {
53
+ self: {
54
+ href: Pact.term('http://localhost:1234/some-url', %r{http://.*}),
55
+ title: Pact.like("A title")
56
+ }
57
+ }
58
+ }
59
+ }
60
+ end
61
+
62
+ let(:pact_broker_client_options) { {} }
63
+
64
+ subject { PactBroker::Client::Webhooks::Create.call(params, pactflow.mock_service_base_url, pact_broker_client_options) }
65
+
66
+ context "when a valid webhook with a team specified is submitted" do
67
+ before do
68
+ mock_pact_broker_index(self, pactflow)
69
+ pactflow
70
+ .given("a team with UUID 2abbc12a-427d-432a-a521-c870af1739d9 exists")
71
+ .upon_receiving("a request to create a webhook for a team")
72
+ .with(
73
+ method: :post,
74
+ path: '/HAL-REL-PLACEHOLDER-PB-WEBHOOKS',
75
+ headers: post_request_headers,
76
+ body: request_body)
77
+ .will_respond_with(success_response)
78
+ end
79
+
80
+ it "returns a CommandResult with success = true" do
81
+ expect(subject).to be_a PactBroker::Client::CommandResult
82
+ expect(subject.success).to be true
83
+ expect(subject.message).to eq "Webhook \"a webhook\" created"
84
+ end
85
+ end
86
+ end
@@ -134,7 +134,7 @@ RSpec.describe "creating a webhook", pact: true do
134
134
  context "when an invalid webhook is submitted" do
135
135
  before do
136
136
  params[:url] = nil
137
- request_body["request"]["url"] = nil
137
+ request_body["request"].delete("url")
138
138
 
139
139
  pact_broker
140
140
  .given("the 'Pricing Service' and 'Condor' already exist in the pact-broker")
data/spec/spec_helper.rb CHANGED
@@ -15,6 +15,7 @@ RSpec.configure do | config |
15
15
  ENV.delete('PACT_BROKER_BASE_URL')
16
16
  ENV.delete('PACT_BROKER_USERNAME')
17
17
  ENV.delete('PACT_BROKER_PASSWORD')
18
+ ENV.delete('PACT_BROKER_TOKEN')
18
19
  end
19
20
 
20
21
  config.after(:all) do
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.45.0
4
+ version: 1.46.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: 2021-06-16 00:00:00.000000000 Z
11
+ date: 2021-06-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httparty
@@ -230,6 +230,7 @@ files:
230
230
  - doc/markdown/Pact Broker Client - Pact Broker.md
231
231
  - doc/markdown/README.md
232
232
  - doc/pacts/markdown/Pact Broker Client - Pact Broker.md
233
+ - doc/pacts/markdown/Pact Broker Client - Pactflow.md
233
234
  - doc/pacts/markdown/README.md
234
235
  - example/scripts/README.md
235
236
  - example/scripts/deploy-consumer.sh
@@ -252,6 +253,7 @@ files:
252
253
  - lib/pact_broker/client/cli/pacticipant_commands.rb
253
254
  - lib/pact_broker/client/cli/record_deployment_long_desc.txt
254
255
  - lib/pact_broker/client/cli/version_selector_options_parser.rb
256
+ - lib/pact_broker/client/cli/webhook_commands.rb
255
257
  - lib/pact_broker/client/colorize_notices.rb
256
258
  - lib/pact_broker/client/command_result.rb
257
259
  - lib/pact_broker/client/create_tag.rb
@@ -323,6 +325,7 @@ files:
323
325
  - script/record-undeployment.sh
324
326
  - script/release.sh
325
327
  - script/trigger-release.sh
328
+ - script/webhook-commands.sh
326
329
  - spec/fixtures/approvals/can_i_deploy_failure_dry_run.approved.txt
327
330
  - spec/fixtures/approvals/can_i_deploy_ignore.approved.txt
328
331
  - spec/fixtures/approvals/can_i_deploy_success_dry_run.approved.txt
@@ -368,6 +371,7 @@ files:
368
371
  - spec/lib/pact_broker/client/versions_spec.rb
369
372
  - spec/lib/pact_broker/client/webhooks/create_spec.rb
370
373
  - spec/pacts/pact_broker_client-pact_broker.json
374
+ - spec/pacts/pact_broker_client-pactflow.json
371
375
  - spec/service_providers/create_environment_spec.rb
372
376
  - spec/service_providers/extra_goodies_spec.rb
373
377
  - spec/service_providers/list_environments_spec.rb
@@ -383,6 +387,7 @@ files:
383
387
  - spec/service_providers/pact_broker_client_tags_spec.rb
384
388
  - spec/service_providers/pact_broker_client_versions_spec.rb
385
389
  - spec/service_providers/pact_helper.rb
390
+ - spec/service_providers/pactflow_webhooks_create_spec.rb
386
391
  - spec/service_providers/pacticipants_create_spec.rb
387
392
  - spec/service_providers/publish_pacts_spec.rb
388
393
  - spec/service_providers/record_deployment_spec.rb
@@ -422,7 +427,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
422
427
  - !ruby/object:Gem::Version
423
428
  version: '0'
424
429
  requirements: []
425
- rubygems_version: 3.2.20
430
+ rubygems_version: 3.2.21
426
431
  signing_key:
427
432
  specification_version: 4
428
433
  summary: See description
@@ -472,6 +477,7 @@ test_files:
472
477
  - spec/lib/pact_broker/client/versions_spec.rb
473
478
  - spec/lib/pact_broker/client/webhooks/create_spec.rb
474
479
  - spec/pacts/pact_broker_client-pact_broker.json
480
+ - spec/pacts/pact_broker_client-pactflow.json
475
481
  - spec/service_providers/create_environment_spec.rb
476
482
  - spec/service_providers/extra_goodies_spec.rb
477
483
  - spec/service_providers/list_environments_spec.rb
@@ -487,6 +493,7 @@ test_files:
487
493
  - spec/service_providers/pact_broker_client_tags_spec.rb
488
494
  - spec/service_providers/pact_broker_client_versions_spec.rb
489
495
  - spec/service_providers/pact_helper.rb
496
+ - spec/service_providers/pactflow_webhooks_create_spec.rb
490
497
  - spec/service_providers/pacticipants_create_spec.rb
491
498
  - spec/service_providers/publish_pacts_spec.rb
492
499
  - spec/service_providers/record_deployment_spec.rb