pact_broker 2.86.0 → 2.87.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/release_gem.yml +1 -1
  3. data/CHANGELOG.md +35 -0
  4. data/db/migrations/20210929_increase_event_context_column_size.rb +14 -0
  5. data/docker-compose-test.yml +2 -0
  6. data/lib/pact/doc/interaction_view_model.rb +2 -2
  7. data/lib/pact/doc/markdown/consumer_contract_renderer.rb +1 -1
  8. data/lib/pact_broker/api/contracts/configuration.rb +33 -0
  9. data/lib/pact_broker/api/contracts/publish_contracts_schema.rb +35 -16
  10. data/lib/pact_broker/api/decorators/matrix_decorator.rb +3 -1
  11. data/lib/pact_broker/api/decorators/verification_decorator.rb +5 -3
  12. data/lib/pact_broker/api/pact_broker_urls.rb +26 -6
  13. data/lib/pact_broker/api/resources/default_base_resource.rb +4 -0
  14. data/lib/pact_broker/api/resources/environment.rb +1 -1
  15. data/lib/pact_broker/api/resources/environments.rb +1 -1
  16. data/lib/pact_broker/api/resources/index.rb +7 -1
  17. data/lib/pact_broker/api/resources/publish_contracts.rb +1 -1
  18. data/lib/pact_broker/api/resources/verification.rb +5 -2
  19. data/lib/pact_broker/api/resources/webhook_execution_methods.rb +23 -17
  20. data/lib/pact_broker/api.rb +1 -0
  21. data/lib/pact_broker/application_context.rb +5 -0
  22. data/lib/pact_broker/db/delete_overwritten_data.rb +41 -23
  23. data/lib/pact_broker/deployments/deployed_version.rb +1 -0
  24. data/lib/pact_broker/deployments/deployed_version_service.rb +1 -0
  25. data/lib/pact_broker/deployments/environment_service.rb +4 -1
  26. data/lib/pact_broker/deployments/released_version_service.rb +1 -0
  27. data/lib/pact_broker/doc/controllers/app.rb +1 -0
  28. data/lib/pact_broker/doc/views/can-i-deploy.markdown +2 -1
  29. data/lib/pact_broker/doc/views/index/publish-contracts.markdown +38 -9
  30. data/lib/pact_broker/domain/index_item.rb +9 -0
  31. data/lib/pact_broker/domain/verification.rb +3 -0
  32. data/lib/pact_broker/index/service.rb +2 -2
  33. data/lib/pact_broker/locale/en.yml +3 -1
  34. data/lib/pact_broker/matrix/parse_can_i_deploy_query.rb +5 -3
  35. data/lib/pact_broker/pacticipants/repository.rb +1 -1
  36. data/lib/pact_broker/pacts/metadata.rb +7 -1
  37. data/lib/pact_broker/pacts/pacts_for_verification_repository.rb +3 -2
  38. data/lib/pact_broker/pacts/service.rb +5 -5
  39. data/lib/pact_broker/string_refinements.rb +1 -1
  40. data/lib/pact_broker/test/http_test_data_builder.rb +2 -0
  41. data/lib/pact_broker/ui/helpers/url_helper.rb +12 -0
  42. data/lib/pact_broker/ui/view_models/index_item.rb +15 -1
  43. data/lib/pact_broker/ui/view_models/index_item_branch_head.rb +39 -0
  44. data/lib/pact_broker/ui/view_models/index_item_provider_branch_head.rb +39 -0
  45. data/lib/pact_broker/ui/views/dashboard/show.haml +14 -7
  46. data/lib/pact_broker/verifications/service.rb +3 -3
  47. data/lib/pact_broker/version.rb +1 -1
  48. data/lib/pact_broker/versions/branch_head.rb +0 -2
  49. data/lib/pact_broker/versions/branch_version.rb +1 -0
  50. data/lib/pact_broker/versions/repository.rb +0 -1
  51. data/lib/pact_broker/webhooks/pact_and_verification_parameters.rb +17 -3
  52. data/lib/pact_broker/webhooks/trigger_service.rb +1 -1
  53. data/lib/pact_broker/webhooks/webhook.rb +5 -0
  54. data/public/stylesheets/index.css +5 -0
  55. data/script/data/auto-create-things-for-tags.rb +1 -0
  56. data/script/data/contract-published-requiring-verification.rb +0 -1
  57. data/spec/fixtures/invalid-publish-contract-body.json +38 -0
  58. data/spec/integration/webhooks/contract_publication_spec.rb +68 -0
  59. data/spec/integration/webhooks/contract_requiring_verification_published_spec.rb +67 -0
  60. data/spec/integration/webhooks/pact_publication_spec.rb +1 -1
  61. data/spec/lib/pact/doc/markdown/consumer_contract_renderer_spec.rb +2 -2
  62. data/spec/lib/pact_broker/api/contracts/publish_contracts_schema_spec.rb +13 -0
  63. data/spec/lib/pact_broker/api/decorators/matrix_decorator_spec.rb +1 -1
  64. data/spec/lib/pact_broker/api/decorators/verification_decorator_spec.rb +7 -6
  65. data/spec/lib/pact_broker/api/decorators/verification_summary_decorator_spec.rb +1 -1
  66. data/spec/lib/pact_broker/api/pact_broker_urls_spec.rb +18 -0
  67. data/spec/lib/pact_broker/api/resources/triggered_webhook_logs_spec.rb +6 -5
  68. data/spec/lib/pact_broker/matrix/parse_can_i_deploy_query_spec.rb +13 -0
  69. data/spec/lib/pact_broker/pacts/repository_find_for_verification_spec.rb +4 -5
  70. data/spec/lib/pact_broker/ui/view_models/index_item_spec.rb +1 -1
  71. data/spec/lib/pact_broker/verifications/service_spec.rb +6 -6
  72. data/spec/lib/pact_broker/webhooks/render_spec.rb +3 -2
  73. data/tasks/db.rake +4 -1
  74. metadata +13 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 349e4547b3d6dbd536df4c39648a8ab89975580509e895d98283535b4406cf06
4
- data.tar.gz: '096c7874fd1497771def8096b581bd68e675a0339ed43dfbc340e21f455a73f6'
3
+ metadata.gz: f376a0bea2db36abf0b4b601badefb182b836bad4c43be53063388ad65ecc1c0
4
+ data.tar.gz: 5ab7478d03702755dea935bde89173461b6221c4723c719267a9a6e8360d6e9c
5
5
  SHA512:
6
- metadata.gz: f1e9248d5f73dc92fc48ddc0ba33f735533dda17276398bbddf38b9437808fc7dc4ecb8fa16ed55532b88b72101883490778447eafd6996c4af8e1e2b1684ec0
7
- data.tar.gz: 750b601c780b37d3df11570e468348e58accaed804d9a34904200c24895be014c4a898d07d714aeb8c0828620db230317b4e41f844c77448c80f065b348053e5
6
+ metadata.gz: 7bb19660447b2f13d2f815b6ce13b3aa27dac289ba023d4463de204fd6605c1f2d787f8e08d36c5868947ba4fa44fb277cf04a77a9e90ad1a9c5e0642d5ec269
7
+ data.tar.gz: 1a68a6c2393f42469045b4fffd1fa548b4833e66401733e75a43382103c8481f38c54d5ed4241e3f4232596b5a23dab6af6a518bad5398d8777b23137c8d9fc9
@@ -35,7 +35,7 @@ jobs:
35
35
  needs: release
36
36
  strategy:
37
37
  matrix:
38
- repository: [pact-foundation/pact-broker-docker, DiUS/pact_broker-docker, pact-foundation/gem-released]
38
+ repository: [pact-foundation/pact-broker-docker, DiUS/pact_broker-docker]
39
39
  runs-on: ubuntu-latest
40
40
  steps:
41
41
  - name: Notify ${{ matrix.repository }} of gem release
data/CHANGELOG.md CHANGED
@@ -1,3 +1,38 @@
1
+ <a name="v2.87.0"></a>
2
+ ### v2.87.0 (2021-10-05)
3
+
4
+ #### Features
5
+
6
+ * **matrix**
7
+ * preselect the consumer version when clicking through to matrix page from integration dashboard ([b550b470](/../../commit/b550b470))
8
+
9
+ * **dashboard**
10
+ * show tooltip explaining auto created branches ([cdaf7f6e](/../../commit/cdaf7f6e))
11
+
12
+ * **can-i-deploy**
13
+ * support ignoring specific version numbers ([2ac5a946](/../../commit/2ac5a946))
14
+ * make verification results URL reference the appropriate consumer version as the pb:pact-version ([145bb37b](/../../commit/145bb37b))
15
+
16
+ * add pb:can-i-deploy-pacticipant-version-to-environment relation ([67328194](/../../commit/67328194))
17
+
18
+ * **webhooks**
19
+ * support ${pactbroker.providerVersionDescriptions} template parameter ([54a073eb](/../../commit/54a073eb))
20
+ * support ${pactbroker.buildUrl} template parameter ([9b79b33f](/../../commit/9b79b33f))
21
+ * support $pactbroker.consumerVersionBranch template parameter ([b97ba84c](/../../commit/b97ba84c))
22
+
23
+ #### Bug Fixes
24
+
25
+ * **mysql**
26
+ * increase size of event_context column ([c1596419](/../../commit/c1596419))
27
+
28
+ * correctly merge dry validation and custom validation error messages when publishing contracts ([688b1e3f](/../../commit/688b1e3f))
29
+
30
+ * **pacts for verification**
31
+ * correct logic for returning pact for main branch when no consumer version selectors are specified ([8847e442](/../../commit/8847e442))
32
+
33
+ * **db clean**
34
+ * optimise calls to identify overwritten data to delete ([aaef9e6d](/../../commit/aaef9e6d))
35
+
1
36
  <a name="v2.86.0"></a>
2
37
  ### v2.86.0 (2021-09-17)
3
38
 
@@ -0,0 +1,14 @@
1
+ require_relative "migration_helper"
2
+ include PactBroker::MigrationHelper
3
+
4
+ Sequel.migration do
5
+ up do
6
+ if mysql?
7
+ run("ALTER TABLE triggered_webhooks CHANGE event_context event_context mediumtext")
8
+ end
9
+ end
10
+
11
+ down do
12
+
13
+ end
14
+ end
@@ -49,6 +49,7 @@ services:
49
49
  - ./.rubocop:/home/.rubocop
50
50
  - ./.gitignore:/home/.gitignore
51
51
  - ./public:/home/public
52
+ - ./docs:/home/docs
52
53
 
53
54
  mysql:
54
55
  image: mysql:5.7.28
@@ -97,4 +98,5 @@ services:
97
98
  - ./.rubocop:/home/.rubocop
98
99
  - ./.gitignore:/home/.gitignore
99
100
  - ./public:/home/public
101
+ - ./docs:/home/docs
100
102
 
@@ -57,7 +57,7 @@ module Pact
57
57
  def formatted_provider_states mark_bold: false
58
58
  bold_marker = mark_bold ? MARKDOWN_BOLD_CHARACTERS : ""
59
59
 
60
- (@interaction.provider_states || []).map do |ps|
60
+ (@interaction.provider_states || []).map do |ps|
61
61
  "#{bold_marker}" \
62
62
  "#{markdown_escape(apply_capitals(ps.name.strip, false))}" \
63
63
  "#{bold_marker}"
@@ -129,7 +129,7 @@ module Pact
129
129
 
130
130
  def markdown_escape string
131
131
  return nil unless string
132
- string.gsub("*",'\*').gsub("_",'\_')
132
+ string.gsub("*","\\*").gsub("_","\\_")
133
133
  end
134
134
  end
135
135
  end
@@ -60,7 +60,7 @@ module Pact
60
60
  end
61
61
 
62
62
  def markdown_escape string
63
- string.gsub("*",'\*').gsub("_",'\_')
63
+ string.gsub("*","\\*").gsub("_","\\_")
64
64
  end
65
65
 
66
66
  def h(text)
@@ -0,0 +1,33 @@
1
+ require "pact_broker/string_refinements"
2
+
3
+ module PactBroker
4
+ module Api
5
+ module Contracts
6
+ class Configuration
7
+ using PactBroker::StringRefinements
8
+
9
+ def initialize(overrides = {})
10
+ @overrides = overrides
11
+ end
12
+
13
+ def class_for(name)
14
+ if overrides[name].is_a?(String)
15
+ Object.const_get(overrides[name])
16
+ elsif overrides[name].is_a?(Class)
17
+ overrides[name]
18
+ else
19
+ Object.const_get("PactBroker::Api::Contracts::#{name.to_s.camelcase(true)}")
20
+ end
21
+ end
22
+
23
+ def self.default_configuration
24
+ Configuration.new
25
+ end
26
+
27
+ private
28
+
29
+ attr_reader :overrides
30
+ end
31
+ end
32
+ end
33
+ end
@@ -34,14 +34,14 @@ module PactBroker
34
34
  end
35
35
 
36
36
  def self.call(params)
37
- select_first_message(
38
- flatten_indexed_messages(
39
- add_cross_field_validation_errors(
40
- params&.symbolize_keys,
41
- SCHEMA.call(params&.symbolize_keys).messages(full: true)
42
- )
43
- )
44
- )
37
+ dry_results = SCHEMA.call(params&.symbolize_keys).messages(full: true)
38
+ dry_results.then do | results |
39
+ add_cross_field_validation_errors(params&.symbolize_keys, results)
40
+ end.then do | results |
41
+ select_first_message(results)
42
+ end.then do | results |
43
+ flatten_indexed_messages(results)
44
+ end
45
45
  end
46
46
 
47
47
  def self.add_cross_field_validation_errors(params, errors)
@@ -61,43 +61,62 @@ module PactBroker
61
61
 
62
62
  def self.validate_consumer_name(params, contract, i, errors)
63
63
  if params[:pacticipantName] && contract[:consumerName] && (contract[:consumerName] != params[:pacticipantName])
64
- add_contract_error(validation_message("consumer_name_in_contract_mismatch_pacticipant_name", { consumer_name_in_contract: contract[:consumerName], pacticipant_name: params[:pacticipantName] } ), i, errors)
64
+ add_contract_error(:consumerName, validation_message("consumer_name_in_contract_mismatch_pacticipant_name", { consumer_name_in_contract: contract[:consumerName], pacticipant_name: params[:pacticipantName] } ), i, errors)
65
65
  end
66
66
  end
67
67
 
68
68
  def self.validate_consumer_name_in_content(params, contract, i, errors)
69
69
  consumer_name_in_content = contract.dig(:decodedParsedContent, :consumer, :name)
70
70
  if consumer_name_in_content && consumer_name_in_content != params[:pacticipantName]
71
- add_contract_error(validation_message("consumer_name_in_content_mismatch_pacticipant_name", { consumer_name_in_content: consumer_name_in_content, pacticipant_name: params[:pacticipantName] } ), i, errors)
71
+ add_contract_error(:consumerName, validation_message("consumer_name_in_content_mismatch_pacticipant_name", { consumer_name_in_content: consumer_name_in_content, pacticipant_name: params[:pacticipantName] } ), i, errors)
72
72
  end
73
73
  end
74
74
 
75
75
  def self.validate_provider_name_in_content(contract, i, errors)
76
76
  provider_name_in_content = contract.dig(:decodedParsedContent, :provider, :name)
77
77
  if provider_name_in_content && provider_name_in_content != contract[:providerName]
78
- add_contract_error(validation_message("provider_name_in_content_mismatch", { provider_name_in_content: provider_name_in_content, provider_name: contract[:providerName] } ), i, errors)
78
+ add_contract_error(:providerName, validation_message("provider_name_in_content_mismatch", { provider_name_in_content: provider_name_in_content, provider_name: contract[:providerName] } ), i, errors)
79
79
  end
80
80
  end
81
81
 
82
82
  def self.validate_encoding(contract, i, errors)
83
83
  if contract[:decodedContent].nil?
84
- add_contract_error(message("errors.base64?", scope: nil), i, errors)
84
+ add_contract_error(:content, message("errors.base64?", scope: nil), i, errors)
85
85
  end
86
86
  end
87
87
 
88
88
  def self.validate_content_matches_content_type(contract, i, errors)
89
89
  if contract[:decodedParsedContent].nil? && contract[:contentType]
90
- add_contract_error(validation_message("invalid_content_for_content_type", { content_type: contract[:contentType]}), i, errors)
90
+ add_contract_error(:content, validation_message("invalid_content_for_content_type", { content_type: contract[:contentType]}), i, errors)
91
91
  end
92
92
  end
93
93
 
94
94
 
95
- def self.add_contract_error(message, i, errors)
95
+ def self.add_contract_error(field, message, i, errors)
96
96
  errors[:contracts] ||= {}
97
- errors[:contracts][i] ||= []
98
- errors[:contracts][i] << message
97
+ errors[:contracts][i] ||= {}
98
+ errors[:contracts][i][field] ||= []
99
+ errors[:contracts][i][field] << message
99
100
  errors
100
101
  end
102
+
103
+ # Need to fix this whole dry-validation eff up
104
+ def self.select_first_message(results)
105
+ case results
106
+ when Hash then results.each_with_object({}) { |(key, value), new_hash| new_hash[key] = select_first_message(value) }
107
+ when Array then select_first_message_from_array(results)
108
+ else
109
+ results
110
+ end
111
+ end
112
+
113
+ def self.select_first_message_from_array(results)
114
+ if results.all?{ |value| value.is_a?(String) }
115
+ results[0...1]
116
+ else
117
+ results.collect { |value| select_first_message(value) }
118
+ end
119
+ end
101
120
  end
102
121
  end
103
122
  end
@@ -162,9 +162,11 @@ module PactBroker
162
162
 
163
163
  def verification_hash(line, base_url)
164
164
  if !line.success.nil?
165
- url_params = { consumer_name: line.consumer_name,
165
+ url_params = {
166
+ consumer_name: line.consumer_name,
166
167
  provider_name: line.provider_name,
167
168
  pact_version_sha: line.pact_version_sha,
169
+ consumer_version_number: line.consumer_version_number,
168
170
  verification_number: line.verification_number
169
171
  }
170
172
  {
@@ -21,18 +21,20 @@ module PactBroker
21
21
  end
22
22
 
23
23
  link :self do | options |
24
+ pact = options[:pact] || represented.latest_pact_publication
24
25
  {
25
26
  title: "Verification result",
26
- name: "Verification result #{represented.number} for #{represented.latest_pact_publication.name}",
27
+ name: "Verification result #{represented.number} for #{pact.name}",
27
28
  href: verification_url(represented, options.fetch(:base_url), )
28
29
  }
29
30
  end
30
31
 
31
32
  link "pb:pact-version" do | options |
33
+ pact = options[:pact] || represented.latest_pact_publication
32
34
  {
33
35
  title: "Pact",
34
- name: represented.latest_pact_publication.name,
35
- href: pact_url(options.fetch(:base_url), represented.latest_pact_publication)
36
+ name: pact.name,
37
+ href: pact_version_with_consumer_version_metadata_url(pact, options.fetch(:base_url))
36
38
  }
37
39
  end
38
40
 
@@ -64,6 +64,10 @@ module PactBroker
64
64
  "#{pactigration_base_url(base_url, pact)}/pact-version/#{pact.pact_version_sha}"
65
65
  end
66
66
 
67
+ def pact_version_with_consumer_version_metadata_url pact, base_url = ""
68
+ "#{pactigration_base_url(base_url, pact)}/pact-version/#{pact.pact_version_sha}/metadata/#{encode_metadata(build_metadata_for_consumer_version_number(pact.consumer_version_number))}"
69
+ end
70
+
67
71
  def pact_version_url_with_metadata pact, metadata, base_url = ""
68
72
  if metadata && metadata.any?
69
73
  "#{pact_version_url(pact, base_url)}/metadata/#{encode_metadata(metadata)}"
@@ -166,12 +170,28 @@ module PactBroker
166
170
  end
167
171
 
168
172
  def verification_url_from_params params, base_url = ""
169
- [ base_url, "pacts",
170
- "provider", url_encode(params.fetch(:provider_name)),
171
- "consumer", url_encode(params.fetch(:consumer_name)),
172
- "pact-version", params.fetch(:pact_version_sha),
173
- "verification-results", params.fetch(:verification_number)
174
- ].join("/")
173
+ if params[:consumer_version_number]
174
+ metadata = encode_metadata(build_metadata_for_consumer_version_number(params[:consumer_version_number]))
175
+
176
+ [
177
+ base_url,
178
+ "pacts",
179
+ "provider", url_encode(params.fetch(:provider_name)),
180
+ "consumer", url_encode(params.fetch(:consumer_name)),
181
+ "pact-version", params.fetch(:pact_version_sha),
182
+ "metadata", metadata,
183
+ "verification-results", params.fetch(:verification_number)
184
+ ].join("/")
185
+ else
186
+ [
187
+ base_url,
188
+ "pacts",
189
+ "provider", url_encode(params.fetch(:provider_name)),
190
+ "consumer", url_encode(params.fetch(:consumer_name)),
191
+ "pact-version", params.fetch(:pact_version_sha),
192
+ "verification-results", params.fetch(:verification_number)
193
+ ].join("/")
194
+ end
175
195
  end
176
196
 
177
197
  def latest_verifications_for_consumer_version_url version, base_url
@@ -254,6 +254,10 @@ module PactBroker
254
254
  application_context.decorator_configuration.class_for(name)
255
255
  end
256
256
 
257
+ def api_contract_class(name)
258
+ application_context.api_contract_configuration.class_for(name)
259
+ end
260
+
257
261
  def schema
258
262
  nil
259
263
  end
@@ -68,7 +68,7 @@ module PactBroker
68
68
  end
69
69
 
70
70
  def schema
71
- PactBroker::Api::Contracts::EnvironmentSchema
71
+ api_contract_class(:environment_schema)
72
72
  end
73
73
  end
74
74
  end
@@ -71,7 +71,7 @@ module PactBroker
71
71
  end
72
72
 
73
73
  def schema
74
- PactBroker::Api::Contracts::EnvironmentSchema
74
+ api_contract_class(:environment_schema)
75
75
  end
76
76
  end
77
77
  end
@@ -136,7 +136,13 @@ module PactBroker
136
136
  "pb:can-i-deploy-pacticipant-version-to-tag" =>
137
137
  {
138
138
  href: base_url + "/can-i-deploy?pacticipant={pacticipant}&version={version}&to={tag}",
139
- title: "Determine if an application can be safely deployed to an environment identified by the given tag",
139
+ title: "Determine if an application version can be safely deployed to an environment identified by the given tag",
140
+ templated: true
141
+ },
142
+ "pb:can-i-deploy-pacticipant-version-to-environment" =>
143
+ {
144
+ href: base_url + "/can-i-deploy?pacticipant={pacticipant}&version={version}&environment={environment}",
145
+ title: "Determine if an application version can be safely deployed to an environment",
140
146
  templated: true
141
147
  },
142
148
  "pb:provider-pacts-for-verification" => {
@@ -31,7 +31,7 @@ module PactBroker
31
31
  end
32
32
 
33
33
  def process_post
34
- handle_webhook_events do
34
+ handle_webhook_events(consumer_version_branch: parsed_contracts.branch, build_url: parsed_contracts.build_url) do
35
35
  results = contract_service.publish(parsed_contracts, base_url: base_url)
36
36
  response.body = decorator_class(:publish_contracts_results_decorator).new(results).to_json(decorator_options)
37
37
  end
@@ -4,11 +4,14 @@ require "pact_broker/domain/verification"
4
4
  require "pact_broker/api/contracts/verification_contract"
5
5
  require "pact_broker/api/decorators/verification_decorator"
6
6
  require "pact_broker/api/decorators/extended_verification_decorator"
7
+ require "pact_broker/api/resources/metadata_resource_methods"
7
8
 
8
9
  module PactBroker
9
10
  module Api
10
11
  module Resources
11
12
  class Verification < BaseResource
13
+ include MetadataResourceMethods
14
+
12
15
  def content_types_provided
13
16
  [
14
17
  ["application/hal+json", :to_json],
@@ -35,11 +38,11 @@ module PactBroker
35
38
  end
36
39
 
37
40
  def to_json
38
- decorator_for(verification).to_json(decorator_options)
41
+ decorator_for(verification).to_json(decorator_options(pact: pact))
39
42
  end
40
43
 
41
44
  def to_extended_json
42
- extended_decorator_for(verification).to_json(decorator_options)
45
+ extended_decorator_for(verification).to_json(decorator_options(pact: pact))
43
46
  end
44
47
 
45
48
  def delete_resource
@@ -5,29 +5,15 @@ module PactBroker
5
5
  module Api
6
6
  module Resources
7
7
  module WebhookExecutionMethods
8
- def webhook_execution_configuration
9
- application_context.webhook_execution_configuration_creator.call(self)
10
- end
11
-
12
- def webhook_options
13
- {
14
- database_connector: database_connector,
15
- webhook_execution_configuration: webhook_execution_configuration
16
- }
17
- end
18
-
19
- def webhook_event_listener
20
- @webhook_event_listener ||= PactBroker::Webhooks::EventListener.new(webhook_options)
21
- end
22
-
23
- def handle_webhook_events
8
+ def handle_webhook_events(event_context = {})
9
+ @webhook_event_listener = PactBroker::Webhooks::EventListener.new(webhook_options(event_context))
24
10
  PactBroker::Events.subscribe(webhook_event_listener) do
25
11
  yield
26
12
  end
27
13
  end
28
14
 
29
15
  def schedule_triggered_webhooks
30
- webhook_event_listener.schedule_triggered_webhooks
16
+ webhook_event_listener&.schedule_triggered_webhooks
31
17
  end
32
18
 
33
19
  def finish_request
@@ -36,6 +22,26 @@ module PactBroker
36
22
  end
37
23
  super
38
24
  end
25
+
26
+
27
+ def webhook_options(event_context = {})
28
+ {
29
+ database_connector: database_connector,
30
+ webhook_execution_configuration: webhook_execution_configuration.with_webhook_context(event_context)
31
+ }
32
+ end
33
+ private :webhook_options
34
+
35
+ def webhook_execution_configuration
36
+ application_context.webhook_execution_configuration_creator.call(self)
37
+ end
38
+ private :webhook_execution_configuration
39
+
40
+ def webhook_event_listener
41
+ @webhook_event_listener
42
+ end
43
+
44
+ private :webhook_event_listener
39
45
  end
40
46
  end
41
47
  end
@@ -49,6 +49,7 @@ module PactBroker
49
49
  add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "version", :consumer_version_number, "verification-results", "latest"], Api::Resources::LatestVerificationForPact, {resource_name: "latest_verification_results_for_pact_publication"}
50
50
  add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "pact-version", :pact_version_sha, "verification-results", "latest"], Api::Resources::LatestVerificationForPact, {resource_name: "latest_verification_results_for_pact_version"}
51
51
  add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "pact-version", :pact_version_sha, "verification-results", :verification_number], Api::Resources::Verification, {resource_name: "verification_result"}
52
+ add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "pact-version", :pact_version_sha, "metadata", :metadata, "verification-results", :verification_number], Api::Resources::Verification, {resource_name: "verification_result"}
52
53
  add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "pact-version", :pact_version_sha, "verification-results", :verification_number, "triggered-webhooks"], Api::Resources::VerificationTriggeredWebhooks, {resource_name: "verification_result_triggered_webhooks"}
53
54
  add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "latest", "verification-results","latest"], Api::Resources::LatestVerificationForLatestPact, {resource_name: "latest_verification_results_for_latest_pact_publication"}
54
55
  add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "latest", :tag, "verification-results","latest"], Api::Resources::LatestVerificationForLatestPact, {resource_name: "latest_verification_results_for_latest_tagged_pact_publication"}
@@ -1,4 +1,5 @@
1
1
  require "pact_broker/api/decorators/configuration"
2
+ require "pact_broker/api/contracts/configuration"
2
3
  require "pact_broker/api/decorators/decorator_context_creator"
3
4
  require "pact_broker/webhooks/execution_configuration_creator"
4
5
  require "pact_broker/errors/error_logger"
@@ -7,6 +8,7 @@ require "pact_broker/api/resources/error_response_body_generator"
7
8
  module PactBroker
8
9
  class ApplicationContext
9
10
  attr_reader :decorator_configuration,
11
+ :api_contract_configuration,
10
12
  :decorator_context_creator,
11
13
  :webhook_execution_configuration_creator,
12
14
  :resource_authorizer,
@@ -18,6 +20,7 @@ module PactBroker
18
20
  def initialize(params = {})
19
21
  params_with_defaults = {
20
22
  decorator_configuration: PactBroker::Api::Decorators::Configuration.default_configuration,
23
+ api_contract_configuration: PactBroker::Api::Contracts::Configuration.default_configuration,
21
24
  decorator_context_creator: PactBroker::Api::Decorators::DecoratorContextCreator,
22
25
  webhook_execution_configuration_creator: PactBroker::Webhooks::ExecutionConfigurationCreator,
23
26
  error_logger: PactBroker::Errors::ErrorLogger,
@@ -25,6 +28,7 @@ module PactBroker
25
28
  }.merge(params)
26
29
 
27
30
  @decorator_configuration = params_with_defaults[:decorator_configuration]
31
+ @api_contract_configuration = params_with_defaults[:api_contract_configuration]
28
32
  @decorator_context_creator = params_with_defaults[:decorator_context_creator]
29
33
  @webhook_execution_configuration_creator = params_with_defaults[:webhook_execution_configuration_creator]
30
34
  @resource_authorizer = params_with_defaults[:resource_authorizer]
@@ -32,6 +36,7 @@ module PactBroker
32
36
  @after_resource = params_with_defaults[:after_resource]
33
37
  @error_logger = params_with_defaults[:error_logger]
34
38
  @error_response_body_generator = params_with_defaults[:error_response_body_generator]
39
+
35
40
  end
36
41
 
37
42
  def self.default_application_context(overrides = {})
@@ -51,13 +51,17 @@ module PactBroker
51
51
  end
52
52
 
53
53
  def delete_webhook_data
54
- ids_to_keep = db[:latest_triggered_webhooks].select(:id)
55
- resolved_ids_to_delete = db[:triggered_webhooks]
56
- .where(id: ids_to_keep)
57
- .invert
58
- .where(Sequel.lit("created_at < ?", cut_off_date))
59
- .limit(limit)
60
- .collect{ |row| row[:id] }
54
+ ltw_join = {
55
+ Sequel[:triggered_webhooks][:id] => Sequel[:ltw][:id]
56
+ }
57
+ resolved_ids_to_delete = db[:triggered_webhooks]
58
+ .select(Sequel[:triggered_webhooks][:id])
59
+ .left_join(:latest_triggered_webhooks, ltw_join, { table_alias: :ltw })
60
+ .where(Sequel[:ltw][:id] => nil)
61
+ .where(Sequel.lit("triggered_webhooks.created_at < ?", cut_off_date))
62
+ .order(Sequel[:triggered_webhooks][:id])
63
+ .limit(limit)
64
+ .collect{ |row| row[:id] }
61
65
 
62
66
  PactBroker::Webhooks::TriggeredWebhook.where(id: resolved_ids_to_delete).delete unless dry_run?
63
67
  { triggered_webhooks: resolved_ids_to_delete.count }
@@ -65,36 +69,50 @@ module PactBroker
65
69
 
66
70
  def delete_orphan_pact_versions
67
71
  referenced_pact_version_ids = db[:pact_publications].select(:pact_version_id).union(db[:verifications].select(:pact_version_id))
68
- pact_version_ids_to_delete = db[:pact_versions].where(id: referenced_pact_version_ids).invert.order(:id).limit(limit).collect{ |row| row[:id] }
72
+ rpv_join = {
73
+ Sequel[:pact_versions][:id] => Sequel[:rpv][:pact_version_id]
74
+ }
75
+ pact_version_ids_to_delete = db[:pact_versions]
76
+ .select(Sequel[:pact_versions][:id])
77
+ .left_join(referenced_pact_version_ids, rpv_join, { table_alias: :rpv })
78
+ .where(Sequel[:rpv][:pact_version_id] => nil)
79
+ .order(Sequel[:pact_versions][:id])
80
+ .limit(limit)
81
+ .collect{ |row| row[:id] }
69
82
  db[:pact_versions].where(id: pact_version_ids_to_delete).delete unless dry_run?
70
83
  { pact_versions: pact_version_ids_to_delete.count }
71
84
  end
72
85
 
73
86
  def delete_overwritten_pact_publications
74
- ids_to_keep = db[:latest_pact_publication_ids_for_consumer_versions].select(:pact_publication_id)
87
+ lp_join = {
88
+ Sequel[:pact_publications][:id] => Sequel[:lp][:pact_publication_id]
89
+ }
75
90
 
76
91
  resolved_ids_to_delete = db[:pact_publications]
77
- .where(id: ids_to_keep)
78
- .invert
79
- .where(Sequel.lit("created_at < ?", cut_off_date))
80
- .order(:id)
81
- .limit(limit)
82
- .collect{ |row| row[:id] }
92
+ .select(Sequel[:pact_publications][:id])
93
+ .left_join(:latest_pact_publication_ids_for_consumer_versions, lp_join, { table_alias: :lp })
94
+ .where(Sequel[:lp][:pact_publication_id] => nil)
95
+ .where(Sequel.lit("pact_publications.created_at < ?", cut_off_date))
96
+ .order(:id)
97
+ .limit(limit)
98
+ .collect{ |row| row[:id] }
83
99
 
84
100
  PactBroker::Pacts::PactPublication.where(id: resolved_ids_to_delete).delete unless dry_run?
85
-
86
101
  { pact_publications: resolved_ids_to_delete.count }
87
102
  end
88
103
 
89
104
  def delete_overwritten_verifications
90
- ids_to_keep = db[:latest_verification_id_for_pact_version_and_provider_version].select(:verification_id)
105
+ lv_join = {
106
+ Sequel[:verifications][:id] => Sequel[:lv][:verification_id]
107
+ }
91
108
  resolved_ids_to_delete = db[:verifications]
92
- .where(id: ids_to_keep)
93
- .invert
94
- .where(Sequel.lit("created_at < ?", cut_off_date))
95
- .order(:id)
96
- .limit(limit)
97
- .collect{ |row| row[:id] }
109
+ .select(Sequel[:verifications][:id])
110
+ .left_join(:latest_verification_id_for_pact_version_and_provider_version, lv_join, { table_alias: :lv})
111
+ .where(Sequel[:lv][:verification_id] => nil)
112
+ .where(Sequel.lit("verifications.created_at < ?", cut_off_date))
113
+ .order(Sequel[:verifications][:id])
114
+ .limit(limit)
115
+ .collect{ |row| row[:id] }
98
116
 
99
117
  PactBroker::Domain::Verification.where(id: resolved_ids_to_delete).delete unless dry_run?
100
118
  { verification_results: resolved_ids_to_delete.count }
@@ -117,6 +117,7 @@ end
117
117
  # undeployed_at | timestamp without time zone |
118
118
  # target | text |
119
119
  # target_for_index | text | NOT NULL DEFAULT ''::text
120
+ # auto_created | boolean | DEFAULT false
120
121
  # Indexes:
121
122
  # deployed_versions_pkey | PRIMARY KEY btree (id)
122
123
  # deployed_versions_uuid_index | UNIQUE btree (uuid)
@@ -65,6 +65,7 @@ module PactBroker
65
65
  .where(pacticipant_id: pacticipant.id)
66
66
  .eager(:version)
67
67
  .eager(:environment)
68
+ .order(:created_at, :id)
68
69
  .all
69
70
  end
70
71