pact_broker 2.0.0.beta.6 → 2.0.0.beta.7

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.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +9 -0
  3. data/README.md +12 -12
  4. data/db/migrations/08_create_latest_pact_view.rb +4 -4
  5. data/db/migrations/14_add_timestamps_to_pact_views.rb +5 -4
  6. data/db/migrations/20_add_pact_version_content_sha_to_all_pacts_view.rb +12 -10
  7. data/db/migrations/28_create_all_pact_publications.rb +6 -5
  8. data/lib/pact_broker/api/decorators/verification_decorator.rb +0 -3
  9. data/lib/pact_broker/api/decorators/verification_summary_decorator.rb +36 -0
  10. data/lib/pact_broker/api/decorators/versions_decorator.rb +1 -1
  11. data/lib/pact_broker/api/resources/latest_verifications_for_consumer_version.rb +5 -5
  12. data/lib/pact_broker/api/resources/versions.rb +1 -1
  13. data/lib/pact_broker/app.rb +2 -0
  14. data/lib/pact_broker/configuration.rb +6 -1
  15. data/lib/pact_broker/domain/order_versions.rb +15 -5
  16. data/lib/pact_broker/domain/verification.rb +1 -1
  17. data/lib/pact_broker/domain/webhook.rb +0 -1
  18. data/lib/pact_broker/domain/webhook_request.rb +6 -4
  19. data/lib/pact_broker/logging.rb +4 -0
  20. data/lib/pact_broker/pacticipants/repository.rb +3 -2
  21. data/lib/pact_broker/pacticipants/service.rb +12 -9
  22. data/lib/pact_broker/pacts/all_pact_publications.rb +2 -2
  23. data/lib/pact_broker/pacts/repository.rb +11 -2
  24. data/lib/pact_broker/pacts/service.rb +4 -0
  25. data/lib/pact_broker/tags/repository.rb +5 -5
  26. data/lib/pact_broker/verifications/repository.rb +4 -3
  27. data/lib/pact_broker/verifications/service.rb +8 -0
  28. data/lib/pact_broker/verifications/summary_for_consumer_version.rb +41 -0
  29. data/lib/pact_broker/version.rb +1 -1
  30. data/lib/pact_broker/versions/parse_semantic_version.rb +14 -4
  31. data/lib/pact_broker/versions/repository.rb +1 -1
  32. data/lib/pact_broker/webhooks/job.rb +46 -0
  33. data/lib/pact_broker/webhooks/service.rb +9 -8
  34. data/lib/pact_broker/webhooks/webhook.rb +1 -1
  35. data/pact_broker.gemspec +4 -3
  36. data/pact_broker_client-pact_broker.json +4 -4
  37. data/script/foo-bar.json +22 -0
  38. data/script/publish-new.sh +7 -0
  39. data/script/publish.sh +2 -2
  40. data/script/recreate-pg-db.sh +10 -0
  41. data/spec/features/get_verifications_for_consumer_version_spec.rb +1 -1
  42. data/spec/fixtures/a_consumer-a_provider-2.json +1 -1
  43. data/spec/fixtures/a_consumer-a_provider-3.json +1 -1
  44. data/spec/fixtures/a_consumer-a_provider-conflict.json +1 -1
  45. data/spec/fixtures/a_consumer-a_provider-merged.json +2 -2
  46. data/spec/fixtures/a_consumer-a_provider.json +1 -1
  47. data/spec/fixtures/consumer-provider.json +1 -1
  48. data/spec/fixtures/renderer_pact.json +1 -1
  49. data/spec/lib/pact_broker/api/decorators/{verifications_decorator_spec.rb → verification_summary_decorator_spec.rb} +16 -13
  50. data/spec/lib/pact_broker/api/resources/latest_verifications_for_consumer_version_spec.rb +5 -5
  51. data/spec/lib/pact_broker/domain/order_versions_spec.rb +30 -10
  52. data/spec/lib/pact_broker/domain/webhook_request_spec.rb +3 -1
  53. data/spec/lib/pact_broker/pacticipants/repository_spec.rb +16 -0
  54. data/spec/lib/pact_broker/pacticipants/service_spec.rb +74 -24
  55. data/spec/lib/pact_broker/verifications/summary_for_consumer_version_spec.rb +72 -0
  56. data/spec/lib/pact_broker/versions/parse_semantic_version_spec.rb +5 -2
  57. data/spec/lib/pact_broker/webhooks/job_spec.rb +67 -0
  58. data/spec/lib/pact_broker/webhooks/service_spec.rb +40 -3
  59. data/spec/support/provider_state_builder.rb +3 -2
  60. data/tasks/db.rake +3 -2
  61. metadata +35 -14
  62. data/lib/pact_broker/api/decorators/verifications_decorator.rb +0 -30
  63. data/lib/pact_broker/pacts/all_pacts.rb +0 -12
  64. data/lib/pact_broker/pacts/latest_pacts.rb +0 -12
@@ -41,8 +41,8 @@ module PactBroker
41
41
  pacticipant_repository.find_by_name(name)
42
42
  end
43
43
 
44
- def self.find_all_pacticipant_versions name
45
- pacticipant_repository.find_all_pacticipant_versions(name)
44
+ def self.find_all_pacticipant_versions_in_reverse_order name
45
+ pacticipant_repository.find_all_pacticipant_versions_in_reverse_order(name)
46
46
  end
47
47
 
48
48
  def self.find_pacticipant_repository_url_by_pacticipant_name name
@@ -75,14 +75,17 @@ module PactBroker
75
75
  def self.delete name
76
76
  pacticipant = find_pacticipant_by_name name
77
77
  connection = PactBroker::Domain::Pacticipant.new.db
78
- connection.run("delete from tags where version_id IN (select id from versions where pacticipant_id IN (select id from pacticipants where name = '#{name}'))")
79
- connection.run("delete from pact_publications where consumer_version_id IN (select id from versions where pacticipant_id IN (select id from pacticipants where name = '#{name}'))")
80
- connection.run("delete from pact_publications where provider_id IN (select id from pacticipants where name = '#{name}')")
81
- connection.run("delete from pact_versions where provider_id IN (select id from pacticipants where name = '#{name}')")
82
- connection.run("delete from pact_versions where consumer_id IN (select id from pacticipants where name = '#{name}')")
83
- connection.run("delete from versions where pacticipant_id IN (select id from pacticipants where name = '#{name}')")
78
+ select_pacticipant = "select id from pacticipants where name = '#{name}'"
79
+ connection.run("delete from tags where version_id IN (select id from versions where pacticipant_id = #{pacticipant.id})")
80
+ connection.run("delete from pact_publications where consumer_version_id IN (select id from versions where pacticipant_id = #{pacticipant.id})")
81
+ connection.run("delete from pact_publications where provider_id = #{pacticipant.id}")
82
+ connection.run("delete from verifications where pact_version_id IN (select id from pact_versions where provider_id = #{pacticipant.id})")
83
+ connection.run("delete from verifications where pact_version_id IN (select id from pact_versions where consumer_id = #{pacticipant.id})")
84
+ connection.run("delete from pact_versions where provider_id = #{pacticipant.id}")
85
+ connection.run("delete from pact_versions where consumer_id = #{pacticipant.id}")
86
+ connection.run("delete from versions where pacticipant_id = #{pacticipant.id}")
84
87
  webhook_service.delete_by_pacticipant pacticipant
85
- connection.run("delete from pacticipants where name = '#{name}'")
88
+ connection.run("delete from pacticipants where id = #{pacticipant.id}")
86
89
  end
87
90
 
88
91
  def self.pacticipant_names
@@ -46,11 +46,11 @@ module PactBroker
46
46
  end
47
47
 
48
48
  def consumer_version_order_before order
49
- where('consumer_version_order < ?', order)
49
+ where(Sequel.lit("consumer_version_order < ?", order))
50
50
  end
51
51
 
52
52
  def consumer_version_order_after order
53
- where('consumer_version_order > ?', order)
53
+ where(Sequel.lit("consumer_version_order > ?", order))
54
54
  end
55
55
 
56
56
  def latest
@@ -49,10 +49,11 @@ module PactBroker
49
49
  end
50
50
 
51
51
  def find_all_pact_versions_between consumer_name, options
52
+ provider_name = options.fetch(:and)
52
53
  LatestPactPublicationsByConsumerVersion
53
54
  .eager(:tags)
54
55
  .consumer(consumer_name)
55
- .provider(options.fetch(:and))
56
+ .provider(provider_name)
56
57
  .reverse_order(:consumer_version_order)
57
58
  .collect(&:to_domain)
58
59
  end
@@ -65,6 +66,14 @@ module PactBroker
65
66
  end
66
67
  end
67
68
 
69
+ # Returns latest pact version for the consumer_version_number
70
+ def find_by_consumer_version consumer_name, consumer_version_number
71
+ LatestPactPublicationsByConsumerVersion
72
+ .consumer(consumer_name)
73
+ .consumer_version_number(consumer_version_number)
74
+ .collect(&:to_domain_with_content)
75
+ end
76
+
68
77
  def find_by_version_and_provider version_id, provider_id
69
78
  LatestPactPublicationsByConsumerVersion
70
79
  .eager(:tags)
@@ -136,7 +145,7 @@ module PactBroker
136
145
  .consumer(pact.consumer.name)
137
146
  .provider(pact.provider.name)
138
147
  .consumer_version_order_before(pact.consumer_version.order)
139
- .where('pact_version_sha != ?', current_pact_content_sha)
148
+ .where(Sequel.lit("pact_version_sha != ?", current_pact_content_sha))
140
149
  .latest
141
150
  .collect(&:to_domain_with_content)[0]
142
151
  end
@@ -25,6 +25,10 @@ module PactBroker
25
25
  pact_repository.find_pact(params[:consumer_name], params[:consumer_version_number], params[:provider_name], params[:revision_number])
26
26
  end
27
27
 
28
+ def find_by_consumer_version params
29
+ pact_repository.find_by_consumer_version(params[:consumer_name], params[:consumer_version_number])
30
+ end
31
+
28
32
  def delete params
29
33
  logger.info "Deleting pact version with params #{params}"
30
34
  pact_repository.delete(params)
@@ -14,12 +14,12 @@ module PactBroker
14
14
 
15
15
  def find args
16
16
  PactBroker::Domain::Tag
17
- .select(:tags__name, :tags__version_id, :tags__created_at, :tags__updated_at)
17
+ .select(Sequel.qualify("tags", "name"), Sequel.qualify("tags", "version_id"), Sequel.qualify("tags", "created_at"), Sequel.qualify("tags", "updated_at"))
18
18
  .join(:versions, {id: :version_id})
19
- .join(:pacticipants, {pacticipants__id: :versions__pacticipant_id})
20
- .where(name_like(:tags__name, args.fetch(:tag_name)))
21
- .where(name_like(:versions__number, args.fetch(:pacticipant_version_number)))
22
- .where(name_like(:pacticipants__name, args.fetch(:pacticipant_name)))
19
+ .join(:pacticipants, {Sequel.qualify("pacticipants", "id") => Sequel.qualify("versions", "pacticipant_id")})
20
+ .where(name_like(Sequel.qualify("tags", "name"), args.fetch(:tag_name)))
21
+ .where(name_like(Sequel.qualify("versions", "number"), args.fetch(:pacticipant_version_number)))
22
+ .where(name_like(Sequel.qualify("pacticipants", "name"), args.fetch(:pacticipant_name)))
23
23
  .single_record
24
24
  end
25
25
  end
@@ -19,7 +19,7 @@ module PactBroker
19
19
 
20
20
  def find consumer_name, provider_name, pact_version_sha, verification_number
21
21
  PactBroker::Domain::Verification
22
- .join(PactBroker::Pacts::AllPactPublications, pact_version_id: :pact_version_id)
22
+ .join(:all_pact_publications, pact_version_id: :pact_version_id)
23
23
  .consumer(consumer_name)
24
24
  .provider(provider_name)
25
25
  .pact_version_sha(pact_version_sha)
@@ -30,15 +30,16 @@ module PactBroker
30
30
  # Use LatestPactPublicationsByConsumerVersion not AllPactPublcations because we don't
31
31
  # want verifications for shadowed revisions as it would be misleading.
32
32
  LatestVerificationsByConsumerVersion
33
- .join(PactBroker::Pacts::LatestPactPublicationsByConsumerVersion, pact_version_id: :pact_version_id)
33
+ .join(:latest_pact_publications_by_consumer_versions, pact_version_id: :pact_version_id)
34
34
  .consumer(consumer_name)
35
35
  .consumer_version_number(consumer_version_number)
36
36
  .order(:provider_name)
37
+ .all
37
38
  end
38
39
 
39
40
  def find_latest_verification_for consumer_name, provider_name
40
41
  query = LatestVerificationsByConsumerVersion
41
- .join(PactBroker::Pacts::AllPactPublications, pact_version_id: :pact_version_id)
42
+ .join(:all_pact_publications, pact_version_id: :pact_version_id)
42
43
  .consumer(consumer_name)
43
44
  .provider(provider_name)
44
45
  .latest
@@ -1,5 +1,6 @@
1
1
  require 'pact_broker/repositories'
2
2
  require 'pact_broker/api/decorators/verification_decorator'
3
+ require 'pact_broker/verifications/summary_for_consumer_version'
3
4
 
4
5
  module PactBroker
5
6
 
@@ -9,6 +10,7 @@ module PactBroker
9
10
  extend self
10
11
 
11
12
  extend PactBroker::Repositories
13
+ extend PactBroker::Services
12
14
 
13
15
  def next_number_for pact
14
16
  verification_repository.verification_count_for_pact(pact) + 1
@@ -39,6 +41,12 @@ module PactBroker
39
41
  def find_latest_verification_for consumer, provider
40
42
  verification_repository.find_latest_verification_for consumer.name, provider.name
41
43
  end
44
+
45
+ def verification_summary_for_consumer_version params
46
+ verifications = find_latest_verifications_for_consumer_version(params)
47
+ pacts = pact_service.find_by_consumer_version(params)
48
+ SummaryForConsumerVersion.new(verifications, pacts)
49
+ end
42
50
  end
43
51
  end
44
52
  end
@@ -0,0 +1,41 @@
1
+ module PactBroker
2
+ module Verifications
3
+ class SummaryForConsumerVersion
4
+
5
+ attr_reader :verifications
6
+
7
+ def initialize verifications, pacts
8
+ @verifications = verifications
9
+ @pacts = pacts
10
+ end
11
+
12
+ def success
13
+ successful.count == pacts.count
14
+ end
15
+
16
+ def provider_summary
17
+ OpenStruct.new(
18
+ successful: successful,
19
+ failed: failed,
20
+ unknown: unknown
21
+ )
22
+ end
23
+
24
+ private
25
+
26
+ attr_reader :pacts
27
+
28
+ def successful
29
+ verifications.select(&:success).collect(&:provider_name)
30
+ end
31
+
32
+ def failed
33
+ verifications.select{|verification| !verification.success }.collect(&:provider_name)
34
+ end
35
+
36
+ def unknown
37
+ pacts.collect(&:provider_name) - verifications.collect(&:provider_name)
38
+ end
39
+ end
40
+ end
41
+ end
@@ -1,3 +1,3 @@
1
1
  module PactBroker
2
- VERSION = '2.0.0.beta.6'
2
+ VERSION = '2.0.0.beta.7'
3
3
  end
@@ -1,18 +1,28 @@
1
1
  require 'semver'
2
+ require 'pact_broker/configuration'
2
3
 
3
4
  module PactBroker
4
5
  module Versions
5
6
  class ParseSemanticVersion
6
- SEMVER_FORMAT = "%M.%m.%p%s%d"
7
+
7
8
 
8
9
  def self.call string_version
9
- version = ::SemVer.parse(string_version, SEMVER_FORMAT)
10
- return SemVerWrapper.new(version) unless version.nil?
10
+ PactBroker.configuration.semver_formats.each do |semver_format|
11
+ parsed_version = ::SemVer.parse(string_version, semver_format)
12
+ return SemVerWrapper.new(parsed_version, semver_format) unless parsed_version.nil?
13
+ end
14
+ nil
11
15
  end
12
16
 
13
17
  class SemVerWrapper < SimpleDelegator
18
+
19
+ def initialize target, semver_format
20
+ super target
21
+ @semver_format = semver_format
22
+ end
23
+
14
24
  def to_s
15
- format(SEMVER_FORMAT)
25
+ format(@semver_format)
16
26
  end
17
27
  end
18
28
  end
@@ -14,7 +14,7 @@ module PactBroker
14
14
 
15
15
  def find_by_pacticipant_name_and_number pacticipant_name, number
16
16
  PactBroker::Domain::Version
17
- .select(:versions__id, :versions__number, :versions__pacticipant_id, :versions__order, :versions__created_at, :versions__updated_at)
17
+ .select(Sequel[:versions][:id], Sequel[:versions][:number], Sequel[:versions][:pacticipant_id], Sequel[:versions][:order], Sequel[:versions][:created_at], Sequel[:versions][:updated_at])
18
18
  .join(:pacticipants, {id: :pacticipant_id})
19
19
  .where(name_like(:number, number))
20
20
  .where(name_like(:name, pacticipant_name))
@@ -0,0 +1,46 @@
1
+ require 'sucker_punch'
2
+ require 'pact_broker/webhooks/service'
3
+ require 'pact_broker/logging'
4
+
5
+ module PactBroker
6
+ module Webhooks
7
+ class Job
8
+
9
+ BACKOFF_TIMES = [10, 60, 120, 300, 600, 1200] #10 sec, 1 min, 2 min, 5 min, 10 min, 20 min => 38 minutes
10
+
11
+ include SuckerPunch::Job
12
+ include PactBroker::Logging
13
+
14
+ def perform data
15
+ @webhook = data[:webhook]
16
+ @error_count = data[:error_count] || 0
17
+ begin
18
+ webhook_execution_result = PactBroker::Webhooks::Service.execute_webhook_now webhook
19
+ reschedule_job unless webhook_execution_result.success?
20
+ rescue StandardError => e
21
+ handle_error e
22
+ end
23
+ end
24
+
25
+ private
26
+
27
+ attr_reader :webhook, :error_count
28
+
29
+ def handle_error e
30
+ log_error e
31
+ reschedule_job
32
+ end
33
+
34
+ def reschedule_job
35
+ case error_count
36
+ when 0...BACKOFF_TIMES.size
37
+ logger.debug "Re-enqeuing job for webhook #{webhook.uuid} to run in #{BACKOFF_TIMES[error_count]} seconds"
38
+ Job.perform_in(BACKOFF_TIMES[error_count], {webhook: webhook, error_count: error_count+1})
39
+ else
40
+ logger.error "Failed to execute webhook #{webhook.uuid} after #{BACKOFF_TIMES.size} times."
41
+ end
42
+ end
43
+
44
+ end
45
+ end
46
+ end
@@ -1,6 +1,8 @@
1
1
  require 'pact_broker/repositories'
2
2
  require 'pact_broker/logging'
3
+ require 'pact_broker/webhooks/job'
3
4
  require 'base64'
5
+ require 'securerandom'
4
6
 
5
7
  module PactBroker
6
8
 
@@ -50,6 +52,7 @@ module PactBroker
50
52
 
51
53
  def self.execute_webhooks pact
52
54
  webhooks = webhook_repository.find_by_consumer_and_provider pact.consumer, pact.provider
55
+
53
56
  if webhooks.any?
54
57
  run_later(webhooks)
55
58
  else
@@ -57,15 +60,13 @@ module PactBroker
57
60
  end
58
61
  end
59
62
 
60
- # TODO background job?
61
63
  def self.run_later webhooks
62
- Thread.new do
63
- webhooks.each do | webhook |
64
- begin
65
- webhook.execute
66
- rescue StandardError => e
67
- # Exceptions are already logged, no need to log again.
68
- end
64
+ webhooks.each do | webhook |
65
+ begin
66
+ logger.info "Scheduling job for #{webhook.description} with uuid #{webhook.uuid}"
67
+ Job.perform_async webhook: webhook
68
+ rescue StandardError => e
69
+ log_error e
69
70
  end
70
71
  end
71
72
  end
@@ -46,7 +46,7 @@ module PactBroker
46
46
  end
47
47
 
48
48
  def request_attributes
49
- values.merge(headers: parsed_headers, body: parsed_body, password: plain_text_password)
49
+ values.merge(headers: parsed_headers, body: parsed_body, password: plain_text_password, uuid: uuid)
50
50
  end
51
51
 
52
52
  def plain_text_password
@@ -24,7 +24,7 @@ Gem::Specification.new do |gem|
24
24
  gem.add_runtime_dependency 'httparty', '~> 0.14'
25
25
  gem.add_runtime_dependency 'json', '> 1.8', '< 3.0'
26
26
  gem.add_runtime_dependency 'roar', '~> 1.1'
27
- gem.add_runtime_dependency 'reform', '~> 2.2.0'
27
+ gem.add_runtime_dependency 'reform', '~> 2.2'
28
28
  gem.add_runtime_dependency 'dry-validation', '~> 0.10.5'
29
29
  gem.add_runtime_dependency 'sequel', '~> 4.23'
30
30
  gem.add_runtime_dependency 'webmachine', '1.4.0'
@@ -35,9 +35,10 @@ Gem::Specification.new do |gem|
35
35
  gem.add_runtime_dependency 'pact-support', '~>0.4', '>=0.4.2'
36
36
  gem.add_runtime_dependency 'padrino-core', '~>0.12.4'
37
37
  gem.add_runtime_dependency 'haml', '~>4.0'
38
+ gem.add_runtime_dependency 'sucker_punch', '~>2.0'
38
39
 
39
- gem.add_development_dependency 'sqlite3', '~>1.3'
40
- gem.add_development_dependency 'pry'
40
+ gem.add_development_dependency 'sqlite3'
41
+ gem.add_development_dependency 'pry-byebug'
41
42
  gem.add_development_dependency 'rake', '~>10.0'
42
43
  gem.add_development_dependency 'fakefs', '~>0.4'
43
44
  gem.add_development_dependency 'mysql2', '~>0.3.15'
@@ -35,7 +35,7 @@
35
35
  },
36
36
  {
37
37
  "description": "a request to publish a pact",
38
- "provider_state": "an error occurs while publishing a pact",
38
+ "providerState": "an error occurs while publishing a pact",
39
39
  "request": {
40
40
  "method": "put",
41
41
  "path": "/pacticipant/Condor/versions/1.3.0/pacts/Pricing%20Service",
@@ -72,7 +72,7 @@
72
72
  },
73
73
  {
74
74
  "description": "a request to retrieve the repository URL of the 'Pricing Service'",
75
- "provider_state": "the 'Pricing Service' does not exist in the pact-broker",
75
+ "providerState": "the 'Pricing Service' does not exist in the pact-broker",
76
76
  "request": {
77
77
  "method": "get",
78
78
  "path": "/pacticipant/Pricing%20Service/repository_url",
@@ -90,7 +90,7 @@
90
90
 
91
91
  {
92
92
  "description": "a request to register the repository URL of a pacticipant",
93
- "provider_state": "the 'Pricing Service' does not exist in the pact-broker",
93
+ "providerState": "the 'Pricing Service' does not exist in the pact-broker",
94
94
  "request": {
95
95
  "method": "patch",
96
96
  "path": "/pacticipant/Pricing%20Service",
@@ -108,7 +108,7 @@
108
108
  },
109
109
  {
110
110
  "description": "a request to retrieve the repository URL of the 'Pricing Service'",
111
- "provider_state": "the 'Pricing Service' already exists in the pact-broker",
111
+ "providerState": "the 'Pricing Service' already exists in the pact-broker",
112
112
  "request": {
113
113
  "method": "get",
114
114
  "path": "/pacticipant/Pricing%20Service/repository_url",
@@ -0,0 +1,22 @@
1
+ {
2
+ "consumer": {
3
+ "name": "Foo"
4
+ },
5
+ "provider": {
6
+ "name": "Bar"
7
+ },
8
+ "interactions": [
9
+ {
10
+ "description" : "a request for something",
11
+ "providerState": null,
12
+ "request": {
13
+ "method": "get",
14
+ "path" : "/something"
15
+ },
16
+ "response": {
17
+ "status": 200,
18
+ "body" : "something"
19
+ }
20
+ }
21
+ ]
22
+ }
@@ -0,0 +1,7 @@
1
+ # set -x
2
+ BODY=$(ruby -e "require 'json'; j = JSON.parse(File.read('script/foo-bar.json')); j['interactions'][0]['providerState'] = 'it is ' + Time.now.to_s; puts j.to_json")
3
+ echo ${BODY} >> tmp.json
4
+ curl -v -XPUT \-H "Content-Type: application/json" \
5
+ -d@tmp.json \
6
+ http://127.0.0.1:9292/pacts/provider/Bar/consumer/Foo/version/1.0.0
7
+ rm tmp.json