pact_broker 2.84.0 → 2.87.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (189) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/trigger_pact_docs_update.yml +22 -0
  3. data/CHANGELOG.md +63 -0
  4. data/DEVELOPER_DOCUMENTATION.md +0 -2
  5. data/db/migrations/20210913_add_pending_to_verifications.rb +7 -0
  6. data/db/migrations/20210914_add_labels_to_webhooks.rb +14 -0
  7. data/db/migrations/20210915_add_verified_by_to_verification.rb +6 -0
  8. data/db/migrations/20210929_increase_event_context_column_size.rb +14 -0
  9. data/docker-compose-ci-mysql.yml +1 -0
  10. data/docker-compose-test.yml +2 -0
  11. data/docs/CONFIGURATION.md +255 -66
  12. data/docs/configuration.yml +166 -101
  13. data/lib/db.rb +0 -1
  14. data/lib/pact/doc/interaction_view_model.rb +2 -2
  15. data/lib/pact/doc/markdown/consumer_contract_renderer.rb +4 -4
  16. data/lib/pact_broker/api/contracts/configuration.rb +33 -0
  17. data/lib/pact_broker/api/contracts/publish_contracts_schema.rb +35 -16
  18. data/lib/pact_broker/api/contracts/webhook_contract.rb +24 -2
  19. data/lib/pact_broker/api/decorators/matrix_decorator.rb +3 -1
  20. data/lib/pact_broker/api/decorators/reason_decorator.rb +2 -2
  21. data/lib/pact_broker/api/decorators/verification_decorator.rb +9 -3
  22. data/lib/pact_broker/api/decorators/verification_summary_decorator.rb +1 -2
  23. data/lib/pact_broker/api/decorators/webhook_decorator.rb +27 -4
  24. data/lib/pact_broker/api/middleware/configuration.rb +33 -0
  25. data/lib/pact_broker/api/pact_broker_urls.rb +35 -7
  26. data/lib/pact_broker/api/renderers/html_pact_renderer.rb +15 -11
  27. data/lib/pact_broker/api/resources/all_webhooks.rb +2 -2
  28. data/lib/pact_broker/api/resources/default_base_resource.rb +4 -0
  29. data/lib/pact_broker/api/resources/environment.rb +1 -1
  30. data/lib/pact_broker/api/resources/environments.rb +1 -1
  31. data/lib/pact_broker/api/resources/index.rb +7 -1
  32. data/lib/pact_broker/api/resources/pact_versions_for_branch.rb +40 -0
  33. data/lib/pact_broker/api/resources/publish_contracts.rb +1 -1
  34. data/lib/pact_broker/api/resources/verification.rb +5 -2
  35. data/lib/pact_broker/api/resources/verifications.rb +5 -1
  36. data/lib/pact_broker/api/resources/webhook_execution_methods.rb +23 -17
  37. data/lib/pact_broker/api.rb +2 -0
  38. data/lib/pact_broker/app.rb +2 -0
  39. data/lib/pact_broker/application_context.rb +5 -0
  40. data/lib/pact_broker/badges/service.rb +3 -1
  41. data/lib/pact_broker/config/runtime_configuration.rb +4 -0
  42. data/lib/pact_broker/config/runtime_configuration_database_methods.rb +1 -1
  43. data/lib/pact_broker/configuration.rb +33 -29
  44. data/lib/pact_broker/db/clean.rb +1 -2
  45. data/lib/pact_broker/db/delete_overwritten_data.rb +41 -23
  46. data/lib/pact_broker/deployments/deployed_version.rb +1 -0
  47. data/lib/pact_broker/deployments/deployed_version_service.rb +1 -0
  48. data/lib/pact_broker/deployments/environment_service.rb +4 -1
  49. data/lib/pact_broker/deployments/released_version_service.rb +1 -0
  50. data/lib/pact_broker/doc/controllers/app.rb +1 -0
  51. data/lib/pact_broker/doc/views/can-i-deploy.markdown +2 -1
  52. data/lib/pact_broker/doc/views/index/publish-contracts.markdown +38 -9
  53. data/lib/pact_broker/doc/views/pacticipant/label.markdown +12 -0
  54. data/lib/pact_broker/doc/views/webhooks.markdown +17 -0
  55. data/lib/pact_broker/domain/index_item.rb +9 -0
  56. data/lib/pact_broker/domain/pacticipant.rb +4 -0
  57. data/lib/pact_broker/domain/verification.rb +28 -4
  58. data/lib/pact_broker/domain/webhook.rb +27 -15
  59. data/lib/pact_broker/domain/webhook_pacticipant.rb +6 -0
  60. data/lib/pact_broker/domain/webhook_request.rb +2 -2
  61. data/lib/pact_broker/index/service.rb +77 -26
  62. data/lib/pact_broker/locale/en.yml +6 -1
  63. data/lib/pact_broker/matrix/head_row.rb +1 -1
  64. data/lib/pact_broker/matrix/parse_can_i_deploy_query.rb +5 -3
  65. data/lib/pact_broker/matrix/quick_row.rb +0 -1
  66. data/lib/pact_broker/matrix/repository.rb +0 -1
  67. data/lib/pact_broker/matrix/row.rb +2 -2
  68. data/lib/pact_broker/pacticipants/repository.rb +1 -1
  69. data/lib/pact_broker/pacts/latest_pact_publication_id_for_consumer_version.rb +0 -1
  70. data/lib/pact_broker/pacts/metadata.rb +11 -3
  71. data/lib/pact_broker/pacts/pact_publication.rb +44 -0
  72. data/lib/pact_broker/pacts/pact_publication_clean_selector_dataset_module.rb +19 -0
  73. data/lib/pact_broker/pacts/pact_publication_dataset_module.rb +68 -1
  74. data/lib/pact_broker/pacts/pact_version.rb +24 -1
  75. data/lib/pact_broker/pacts/pacts_for_verification_repository.rb +5 -4
  76. data/lib/pact_broker/pacts/repository.rb +52 -48
  77. data/lib/pact_broker/pacts/service.rb +5 -5
  78. data/lib/pact_broker/string_refinements.rb +1 -1
  79. data/lib/pact_broker/test/http_test_data_builder.rb +40 -11
  80. data/lib/pact_broker/test/test_data_builder.rb +27 -6
  81. data/lib/pact_broker/ui/app.rb +7 -1
  82. data/lib/pact_broker/ui/controllers/dashboard.rb +80 -0
  83. data/lib/pact_broker/ui/controllers/groups.rb +23 -8
  84. data/lib/pact_broker/ui/helpers/url_helper.rb +17 -1
  85. data/lib/pact_broker/ui/view_models/index_item.rb +64 -8
  86. data/lib/pact_broker/ui/view_models/index_item_branch_head.rb +39 -0
  87. data/lib/pact_broker/ui/view_models/index_item_provider_branch_head.rb +39 -0
  88. data/lib/pact_broker/ui/view_models/matrix_branch.rb +1 -1
  89. data/lib/pact_broker/ui/view_models/matrix_tag.rb +0 -1
  90. data/lib/pact_broker/ui/views/dashboard/show.haml +202 -0
  91. data/lib/pact_broker/ui/views/groups/show.html.erb +60 -14
  92. data/lib/pact_broker/ui/views/index/_dashboard_navbar.haml +7 -0
  93. data/lib/pact_broker/ui/views/index/_navbar.haml +0 -7
  94. data/lib/pact_broker/ui/views/index/show-with-tags.haml +3 -1
  95. data/lib/pact_broker/ui/views/index/show.haml +35 -13
  96. data/lib/pact_broker/ui/views/matrix/show.haml +7 -3
  97. data/lib/pact_broker/verifications/pseudo_branch_status.rb +2 -0
  98. data/lib/pact_broker/verifications/repository.rb +5 -2
  99. data/lib/pact_broker/verifications/service.rb +8 -4
  100. data/lib/pact_broker/version.rb +1 -1
  101. data/lib/pact_broker/versions/branch_head.rb +0 -2
  102. data/lib/pact_broker/versions/branch_version.rb +1 -0
  103. data/lib/pact_broker/versions/repository.rb +0 -1
  104. data/lib/pact_broker/webhooks/event_listener.rb +7 -5
  105. data/lib/pact_broker/webhooks/execution_configuration.rb +16 -0
  106. data/lib/pact_broker/webhooks/execution_configuration_creator.rb +3 -0
  107. data/lib/pact_broker/webhooks/job.rb +1 -1
  108. data/lib/pact_broker/webhooks/pact_and_verification_parameters.rb +18 -3
  109. data/lib/pact_broker/webhooks/repository.rb +10 -4
  110. data/lib/pact_broker/webhooks/trigger_service.rb +3 -3
  111. data/lib/pact_broker/webhooks/webhook.rb +71 -8
  112. data/lib/pact_broker/webhooks/webhook_execution_result.rb +3 -7
  113. data/lib/pact_broker/webhooks/webhook_request_logger.rb +4 -12
  114. data/lib/pact_broker/webhooks/webhook_request_template.rb +6 -8
  115. data/pact_broker.gemspec +4 -0
  116. data/public/javascripts/index.js +75 -68
  117. data/public/javascripts/pact.js +14 -14
  118. data/public/stylesheets/index.css +6 -2
  119. data/public/stylesheets/pact.css +11 -0
  120. data/script/data/auto-create-things-for-tags.rb +3 -0
  121. data/script/data/branches.rb +2 -2
  122. data/script/data/contract-published-requiring-verification.rb +0 -1
  123. data/script/data/environments.rb +0 -0
  124. data/script/data/pending.rb +26 -0
  125. data/script/data/tags.rb +35 -0
  126. data/script/data/verify-pact-for-multiple-selectors.rb +30 -0
  127. data/script/data/webhook.rb +22 -0
  128. data/script/docs/generate-configuration-docs.rb +24 -3
  129. data/script/generate-erd +55 -0
  130. data/script/seed.rb +50 -89
  131. data/spec/features/create_webhook_spec.rb +55 -10
  132. data/spec/features/delete_pact_versions_for_branch_spec.rb +34 -0
  133. data/spec/features/get_pact_spec.rb +2 -3
  134. data/spec/fixtures/approvals/modifiable_resources.approved.json +4 -0
  135. data/spec/fixtures/invalid-publish-contract-body.json +38 -0
  136. data/spec/fixtures/verification.json +4 -0
  137. data/spec/integration/app_spec.rb +6 -6
  138. data/spec/integration/webhooks/contract_publication_spec.rb +68 -0
  139. data/spec/integration/webhooks/contract_requiring_verification_published_spec.rb +67 -0
  140. data/spec/integration/webhooks/pact_publication_spec.rb +51 -0
  141. data/spec/lib/pact/doc/markdown/consumer_contract_renderer_spec.rb +2 -2
  142. data/spec/lib/pact_broker/api/contracts/publish_contracts_schema_spec.rb +13 -0
  143. data/spec/lib/pact_broker/api/contracts/webhook_contract_spec.rb +50 -0
  144. data/spec/lib/pact_broker/api/decorators/matrix_decorator_spec.rb +1 -1
  145. data/spec/lib/pact_broker/api/decorators/reason_decorator_spec.rb +2 -2
  146. data/spec/lib/pact_broker/api/decorators/verification_decorator_spec.rb +15 -7
  147. data/spec/lib/pact_broker/api/decorators/verification_summary_decorator_spec.rb +6 -2
  148. data/spec/lib/pact_broker/api/decorators/webhook_decorator_spec.rb +4 -4
  149. data/spec/lib/pact_broker/api/decorators/webhook_execution_result_decorator_spec.rb +1 -1
  150. data/spec/lib/pact_broker/api/middleware/configuration_spec.rb +43 -0
  151. data/spec/lib/pact_broker/api/pact_broker_urls_spec.rb +18 -0
  152. data/spec/lib/pact_broker/api/resources/triggered_webhook_logs_spec.rb +6 -5
  153. data/spec/lib/pact_broker/api/resources/verifications_spec.rb +2 -3
  154. data/spec/lib/pact_broker/api/resources/webhook_execution_spec.rb +1 -1
  155. data/spec/lib/pact_broker/badges/service_spec.rb +22 -0
  156. data/spec/lib/pact_broker/config/runtime_configuration_documentation_spec.rb +30 -0
  157. data/spec/lib/pact_broker/deployments/environment_service_spec.rb +1 -1
  158. data/spec/lib/pact_broker/domain/webhook_request_spec.rb +2 -1
  159. data/spec/lib/pact_broker/domain/webhook_spec.rb +15 -5
  160. data/spec/lib/pact_broker/index/service_spec.rb +1 -5
  161. data/spec/lib/pact_broker/index/service_view_spec.rb +144 -0
  162. data/spec/lib/pact_broker/matrix/head_row_spec.rb +9 -5
  163. data/spec/lib/pact_broker/matrix/parse_can_i_deploy_query_spec.rb +13 -0
  164. data/spec/lib/pact_broker/pacts/metadata_spec.rb +11 -2
  165. data/spec/lib/pact_broker/pacts/{latest_tagged_pact_publications_spec.rb → pact_publication_clean_selector_dataset_module_spec.rb} +7 -9
  166. data/spec/lib/pact_broker/pacts/pact_publication_latest_verification_spec.rb +29 -0
  167. data/spec/lib/pact_broker/pacts/pact_version_spec.rb +32 -0
  168. data/spec/lib/pact_broker/pacts/repository_find_for_verification_spec.rb +4 -5
  169. data/spec/lib/pact_broker/pacts/repository_spec.rb +48 -2
  170. data/spec/lib/pact_broker/ui/view_models/index_item_spec.rb +12 -9
  171. data/spec/lib/pact_broker/verifications/pseudo_branch_status_spec.rb +9 -1
  172. data/spec/lib/pact_broker/verifications/service_spec.rb +24 -8
  173. data/spec/lib/pact_broker/webhooks/job_spec.rb +4 -4
  174. data/spec/lib/pact_broker/webhooks/render_spec.rb +3 -2
  175. data/spec/lib/pact_broker/webhooks/repository_spec.rb +158 -15
  176. data/spec/lib/pact_broker/webhooks/trigger_service_spec.rb +9 -5
  177. data/spec/lib/pact_broker/webhooks/webhook_request_logger_spec.rb +6 -12
  178. data/spec/lib/pact_broker/webhooks/webhook_request_template_spec.rb +3 -2
  179. data/spec/lib/pact_broker/webhooks/webhook_spec.rb +8 -5
  180. data/spec/support/generated_markdown.md +3 -3
  181. data/tasks/db.rake +4 -1
  182. metadata +72 -14
  183. data/lib/pact_broker/pacts/all_pact_publications.rb +0 -158
  184. data/lib/pact_broker/pacts/latest_pact_publications.rb +0 -48
  185. data/lib/pact_broker/pacts/latest_pact_publications_by_consumer_version.rb +0 -26
  186. data/lib/pact_broker/pacts/latest_tagged_pact_publications.rb +0 -45
  187. data/lib/pact_broker/verifications/latest_verification_for_pact_version.rb +0 -39
  188. data/spec/lib/pact_broker/api/resources/webhook_execution_result_spec.rb +0 -56
  189. data/spec/lib/pact_broker/verifications/latest_verification_for_pact_version_spec.rb +0 -18
@@ -29,15 +29,17 @@ module PactBroker
29
29
  @options = options
30
30
  end
31
31
 
32
- def log(uuid, webhook_request, http_response, error, webhook_context)
32
+ # rubocop: disable Metrics/ParameterLists
33
+ def log(uuid, webhook_request, http_response, success, error, webhook_context)
33
34
  safe_response = http_response ? HttpResponseWithUtf8SafeBody.new(http_response) : nil
34
35
  log_webhook_context(webhook_context)
35
36
  log_request(webhook_request)
36
37
  log_response(uuid, safe_response, webhook_context[:base_url]) if safe_response
37
38
  log_error(uuid, error, webhook_context[:base_url]) if error
38
- log_completion_message(success?(safe_response))
39
+ log_completion_message(success)
39
40
  log_stream.string
40
41
  end
42
+ # rubocop: enable Metrics/ParameterLists
41
43
 
42
44
  private
43
45
 
@@ -115,16 +117,6 @@ module PactBroker
115
117
  execution_logger.error "Error executing webhook #{uuid}. #{response_body_hidden_message(base_url)}"
116
118
  end
117
119
  end
118
-
119
- def success?(response)
120
- if response
121
- # Response HTTP Code must be in success list otherwise it is false
122
- PactBroker.configuration.webhook_http_code_success.include? response.code.to_i
123
- else
124
- false
125
- end
126
- end
127
-
128
120
  end
129
121
  end
130
122
  end
@@ -21,16 +21,13 @@ module PactBroker
21
21
  alias_method :http_method, :method
22
22
 
23
23
  def initialize attributes = {}
24
- @method = attributes[:method]
25
- @url = attributes[:url]
26
- @username = attributes[:username]
27
- @password = attributes[:password]
24
+ attributes.each do | (name, value) |
25
+ instance_variable_set("@#{name}", value) if respond_to?(name)
26
+ end
28
27
  @headers = Rack::Utils::HeaderHash.new(attributes[:headers] || {})
29
- @body = attributes[:body]
30
- @uuid = attributes[:uuid]
31
28
  end
32
29
 
33
- def build(template_params)
30
+ def build(template_params, user_agent)
34
31
  attributes = {
35
32
  method: http_method,
36
33
  url: build_url(template_params),
@@ -38,7 +35,8 @@ module PactBroker
38
35
  username: build_string(username, template_params),
39
36
  password: build_string(password, template_params),
40
37
  uuid: uuid,
41
- body: build_body(template_params)
38
+ body: build_body(template_params),
39
+ user_agent: user_agent
42
40
  }
43
41
  PactBroker::Domain::WebhookRequest.new(attributes)
44
42
  end
data/pact_broker.gemspec CHANGED
@@ -48,6 +48,9 @@ Gem::Specification.new do |gem|
48
48
  gem.add_runtime_dependency "roar", "~> 1.1"
49
49
  gem.add_runtime_dependency "reform", "~> 2.3.3"
50
50
  gem.add_runtime_dependency "dry-validation", "~> 0.10.5"
51
+ # /usr/local/bundle/gems/dry-validation-0.10.7/lib/dry/validation/schema/class_interface.rb:7:in `<module:Validation>' [dry-configurable] default value as positional argument to settings is deprecated and will be removed in the next major version
52
+ # Provide a `default:` keyword argument instead
53
+ gem.add_runtime_dependency "dry-configurable", "0.12.1"
51
54
  gem.add_runtime_dependency "sequel", "~> 5.28"
52
55
  gem.add_runtime_dependency "webmachine", "1.6.0"
53
56
  gem.add_runtime_dependency "semver2", "~> 3.4.2"
@@ -66,4 +69,5 @@ Gem::Specification.new do |gem|
66
69
  gem.add_runtime_dependency "sanitize", ">= 5.2.1", "~> 5.2"
67
70
  gem.add_runtime_dependency "wisper", "~> 2.0"
68
71
  gem.add_runtime_dependency "anyway_config", "~> 2.1"
72
+ gem.add_runtime_dependency "request_store", "~> 1.5"
69
73
  end
@@ -24,14 +24,15 @@ function createIntegrationDeletionConfirmationText(rowData) {
24
24
  }, and all associated data (pacts, verifications, application versions, tags and webhooks) that are not associated with other integrations. Do you wish to continue?`;
25
25
  }
26
26
 
27
- function createPactTagDeletionConfirmationText({
27
+ function createPactTagOrBranchDeletionConfirmationText({
28
28
  providerName,
29
29
  consumerName,
30
- pactTagName
30
+ refName,
31
+ scope
31
32
  }) {
32
33
  return `This will delete the pacts for provider ${providerName} and all versions of ${
33
34
  consumerName
34
- } with tag ${pactTagName}. Do you wish to continue?`;
35
+ } ${scope} ${refName}. Do you wish to continue?`;
35
36
  }
36
37
 
37
38
  function handleDeletePactsSelected(clickedElement) {
@@ -50,24 +51,26 @@ function handleDeleteIntegrationsSelected(clickedElement) {
50
51
  handleDeleteResourcesSelected(tr, tr.data().integrationUrl, confirmationText);
51
52
  }
52
53
 
53
- function handleDeleteTagSelected({
54
+ function handleDeleteTagOrBranchSelected({
54
55
  providerName,
55
56
  consumerName,
56
- pactTagName,
57
- deletionUrl
57
+ refName,
58
+ deletionUrl,
59
+ scope
58
60
  }) {
59
61
  return function(clickedElement) {
60
62
  const tr = $(clickedElement).closest("tr");
61
- const confirmationText = createPactTagDeletionConfirmationText({
63
+ const confirmationText = createPactTagOrBranchDeletionConfirmationText({
62
64
  providerName,
63
65
  consumerName,
64
- pactTagName
66
+ refName,
67
+ scope
65
68
  });
66
69
  handleDeleteResourcesSelected(
67
70
  tr,
68
71
  deletionUrl,
69
72
  confirmationText,
70
- pactTagName
73
+ refName
71
74
  );
72
75
  };
73
76
  }
@@ -134,53 +137,32 @@ function handleDeleteResourcesSelected(
134
137
  rowData.providerName,
135
138
  tagName
136
139
  );
137
- const isRefreshingThePage = !!tagName;
138
140
  const cancelled = function() {
139
- unHighlightRows(rows);
141
+ unHighlightRows(row);
140
142
  };
141
143
  const confirmed = function() {
142
144
  deleteResources(
143
145
  deletionUrl,
144
- function() {
145
- handleDeletionSuccess(rows, isRefreshingThePage);
146
- },
146
+ handleDeletionSuccess,
147
147
  function(response) {
148
- handleDeletionFailure(rows, response);
148
+ handleDeletionFailure(row, response);
149
149
  }
150
150
  );
151
151
  };
152
152
 
153
- if (!isRefreshingThePage) {
154
- highlightRowsToBeDeleted(rows);
155
- }
156
- confirmDeleteResources(confirmationText, confirmed, cancelled);
157
- }
158
153
 
159
- function hideDeletedRows(rows) {
160
- rows
161
- .children("td, th")
162
- .animate({ padding: 0 })
163
- .wrapInner("<div />")
164
- .children()
165
- .slideUp(function() {
166
- $(this)
167
- .closest("tr")
168
- .remove();
169
- });
154
+ highlightRowsToBeDeleted(row);
155
+
156
+ confirmDeleteResources(confirmationText, confirmed, cancelled);
170
157
  }
171
158
 
172
159
  function refreshPage() {
173
160
  const url = new URL(window.location);
174
- url.searchParams.delete("search");
175
161
  window.location = url.toString();
176
162
  }
177
163
 
178
- function handleDeletionSuccess(rows, isRefreshingThePage) {
179
- if (isRefreshingThePage) {
180
- return refreshPage();
181
- }
182
-
183
- hideDeletedRows(rows);
164
+ function handleDeletionSuccess() {
165
+ return refreshPage();
184
166
  }
185
167
 
186
168
  function createErrorMessage(responseBody) {
@@ -228,37 +210,62 @@ function deleteResources(url, successCallback, errorCallback) {
228
210
  }
229
211
 
230
212
  function buildMaterialMenuItems(clickedElementData) {
231
- const baseOptions = [
232
- {
233
- type: "normal",
234
- text: "Delete pacts ...",
235
- click: handleDeletePactsSelected
236
- },
237
- {
238
- type: "normal",
239
- text: "Delete integration...",
240
- click: handleDeleteIntegrationsSelected
241
- }
242
- ];
243
-
244
- const taggedPacts = clickedElementData.taggedPacts || [];
245
213
  const providerName = clickedElementData.providerName;
246
214
  const consumerName = clickedElementData.consumerName;
247
- const taggedPactsOptions = taggedPacts.map(taggedPact => {
248
- const taggedPactObject = JSON.parse(taggedPact);
249
- const pactTagName = taggedPactObject.tag;
250
- const taggedPactUrl = taggedPactObject.deletionUrl;
251
- return {
252
- type: "normal",
253
- text: `Delete pacts for ${pactTagName}...`,
254
- click: handleDeleteTagSelected({
255
- providerName,
256
- consumerName,
257
- pactTagName,
258
- deletionUrl: taggedPactUrl
259
- })
260
- };
261
- });
262
215
 
263
- return [...baseOptions, ...taggedPactsOptions];
216
+ const branchOptions = (clickedElementData.pactBranches || []).map(branch => {
217
+ const refName = branch.name;
218
+ const deletionUrl = branch.deletionUrl;
219
+ return {
220
+ type: "normal",
221
+ text: `Delete pacts from branch ${refName}...`,
222
+ click: handleDeleteTagOrBranchSelected({
223
+ providerName,
224
+ consumerName,
225
+ refName,
226
+ deletionUrl: deletionUrl,
227
+ scope: "for branch"
228
+ })
229
+ };
230
+ });
231
+
232
+ const tagOptions = (clickedElementData.pactTags || []).map(tag => {
233
+ const refName = tag.name;
234
+ const deletionUrl = tag.deletionUrl;
235
+ return {
236
+ type: "normal",
237
+ text: `Delete pacts for tag ${refName}...`,
238
+ click: handleDeleteTagOrBranchSelected({
239
+ providerName,
240
+ consumerName,
241
+ refName,
242
+ deletionUrl,
243
+ scope: "with tag"
244
+ })
245
+ };
246
+ });
247
+
248
+
249
+ if (clickedElementData.view === "branch") {
250
+ return branchOptions;
251
+ } else if (clickedElementData.view === "tag") {
252
+ return tagOptions;
253
+ } else if (clickedElementData.view === "all") {
254
+ return [...branchOptions, ...tagOptions];
255
+ } else if (clickedElementData.index) {
256
+ return [
257
+ {
258
+ type: "normal",
259
+ text: "Delete pacts ...",
260
+ click: handleDeletePactsSelected
261
+ },
262
+ {
263
+ type: "normal",
264
+ text: "Delete integration...",
265
+ click: handleDeleteIntegrationsSelected
266
+ }
267
+ ];
268
+ } else {
269
+ return []
270
+ }
264
271
  }
@@ -8,20 +8,20 @@ $(document).ready(function() {
8
8
  position: "overlay",
9
9
  animationSpeed: 1,
10
10
  items: [
11
- // {
12
- // type: "normal",
13
- // text: "View in API Browser",
14
- // click: function(openMenuElement) {
15
- // window.location.href = openMenuElement.data().apiBrowserUrl;
16
- // }
17
- // },
18
- // {
19
- // type: "normal",
20
- // text: "View Matrix",
21
- // click: function(openMenuElement) {
22
- // window.location.href = openMenuElement.data().matrixUrl;
23
- // }
24
- // },
11
+ {
12
+ type: "normal",
13
+ text: "View in API Browser",
14
+ click: function(openMenuElement) {
15
+ window.location.href = openMenuElement.data().apiBrowserUrl;
16
+ }
17
+ },
18
+ {
19
+ type: "normal",
20
+ text: "View Matrix",
21
+ click: function(openMenuElement) {
22
+ window.location.href = openMenuElement.data().matrixUrl;
23
+ }
24
+ },
25
25
  {
26
26
  type: "normal",
27
27
  text: "Delete ...",
@@ -233,12 +233,16 @@ span.copy-success-icon {
233
233
  height: 16px;
234
234
  }
235
235
 
236
- .field {
236
+ .search-field {
237
237
  margin-top: 15px;
238
238
  margin-bottom: 15px;
239
239
  }
240
240
 
241
241
  div.top-of-group {
242
242
  margin-top: 20px;
243
- margin-bottom: 20px;
243
+ }
244
+
245
+
246
+ div[data-toggle="tooltip"] {
247
+ cursor: pointer;
244
248
  }
@@ -1,4 +1,5 @@
1
1
  div.pact-metadata {
2
+ margin-top: 40px;
2
3
  float: right;
3
4
  }
4
5
 
@@ -41,3 +42,13 @@ span.kebab-horizontal {
41
42
  span.more-options {
42
43
  float: right;
43
44
  }
45
+
46
+ /* same as .page-header */
47
+ h1 {
48
+ padding-bottom: 2rem;
49
+ margin: 40px 0 20px;
50
+ }
51
+
52
+ h3 {
53
+ margin-top: 2rem;
54
+ }
@@ -11,6 +11,9 @@ begin
11
11
  .create_pacticipant("AutoDetectTestProvider")
12
12
  .create_tagged_pacticipant_version(pacticipant: "AutoDetectTestProvider", version: "1", tag: "main")
13
13
  .deploy_to_prod(pacticipant: "AutoDetectTestProvider", version: "1")
14
+ .publish_pact(consumer: "AutoDetectTestConsumer", provider: "AutoDetectTestProvider", consumer_version: "1", tag: "feat/x", content_id: "2111")
15
+ .publish_pact(consumer: "AutoDetectTestConsumer", provider: "AutoDetectTestProvider", consumer_version: "2", tag: "feat/y", content_id: "21asdfd")
16
+ .deploy_to_prod(pacticipant: "AutoDetectTestConsumer", version: "1")
14
17
 
15
18
  rescue StandardError => e
16
19
  puts "#{e.class} #{e.message}"
@@ -11,7 +11,7 @@ begin
11
11
  .publish_contract(consumer: "branch-consumer", provider: "branch-provider", consumer_version: "1", content_id: "1111", branch: "main")
12
12
  .publish_contract(consumer: "branch-consumer", provider: "branch-provider", consumer_version: "1", content_id: "1111", branch: "feat/x")
13
13
  .publish_contract(consumer: "branch-consumer", provider: "branch-provider", consumer_version: "2", content_id: "1111", branch: "feat/x")
14
- .get_pacts_for_verification(provider: "branch-provider")
14
+ .get_pacts_for_verification(provider: "branch-provider", enable_pending: false)
15
15
  .verify_pact(
16
16
  provider_version_branch: "main",
17
17
  provider_version: "1",
@@ -25,7 +25,7 @@ begin
25
25
  .verify_pact(
26
26
  provider_version_branch: "feat/y",
27
27
  provider_version: "2",
28
- success: true
28
+ success: false
29
29
  )
30
30
 
31
31
  rescue StandardError => e
@@ -14,7 +14,6 @@ begin
14
14
  .create_pacticipant("NewWebhookTestConsumer")
15
15
  .create_pacticipant("NewWebhookTestProvider")
16
16
  .create_tagged_pacticipant_version(pacticipant: "NewWebhookTestProvider", version: "1", tag: "main")
17
- .deploy_to_prod(pacticipant: "NewWebhookTestProvider")
18
17
  .record_deployment(pacticipant: "NewWebhookTestProvider", version: "1", environment_name: "test")
19
18
  .record_deployment(pacticipant: "NewWebhookTestProvider", version: "1", environment_name: "prod")
20
19
  .create_version(pacticipant: "NewWebhookTestProvider", version: "2", branch: "main")
File without changes
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env ruby
2
+ begin
3
+
4
+ $LOAD_PATH << "#{Dir.pwd}/lib"
5
+ require "pact_broker/test/http_test_data_builder"
6
+ base_url = ENV["PACT_BROKER_BASE_URL"] || "http://localhost:9292"
7
+
8
+ td = PactBroker::Test::HttpTestDataBuilder.new(base_url)
9
+ td.delete_pacticipant("some-demo-provider")
10
+ .delete_pacticipant("some-demo-consumer")
11
+ .publish_contract(consumer: "some-demo-consumer", provider: "some-demo-provider", consumer_version: "1", content_id: "1111", branch: "main")
12
+ .publish_contract(consumer: "some-demo-consumer", provider: "some-demo-provider", consumer_version: "1", content_id: "1111", branch: "feat/x")
13
+ .publish_contract(consumer: "some-demo-consumer", provider: "some-demo-provider", consumer_version: "2", content_id: "1111", branch: "feat/x")
14
+ .get_pacts_for_verification(provider: "some-demo-provider")
15
+ .verify_pact(
16
+ provider_version_branch: "main",
17
+ provider_version: "1",
18
+ success: false
19
+ )
20
+
21
+
22
+ rescue StandardError => e
23
+ puts "#{e.class} #{e.message}"
24
+ puts e.backtrace
25
+ exit 1
26
+ end
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/env ruby
2
+ begin
3
+
4
+ $LOAD_PATH << "#{Dir.pwd}/lib"
5
+ require "pact_broker/test/http_test_data_builder"
6
+ base_url = ENV["PACT_BROKER_BASE_URL"] || "http://localhost:9292"
7
+
8
+ td = PactBroker::Test::HttpTestDataBuilder.new(base_url)
9
+ td.delete_pacticipant("tag-provider")
10
+ .delete_pacticipant("tag-consumer")
11
+ .publish_contract(consumer: "tag-consumer", provider: "tag-provider", consumer_version: "1", content_id: "1111", tag: "main")
12
+ .publish_contract(consumer: "tag-consumer", provider: "tag-provider", consumer_version: "1", content_id: "1111", tag: "feat/x")
13
+ .publish_contract(consumer: "tag-consumer", provider: "tag-provider", consumer_version: "2", content_id: "1111", tag: "feat/x")
14
+ .get_pacts_for_verification(provider: "tag-provider", consumer_version_selectors: [{ tag: "main", latest: true }])
15
+ .verify_pact(
16
+ provider_version_tag: "main",
17
+ provider_version: "1",
18
+ success: true
19
+ )
20
+ .verify_pact(
21
+ provider_version_tag: "feat/y",
22
+ provider_version: "1",
23
+ success: true
24
+ )
25
+ .verify_pact(
26
+ provider_version_tag: "feat/y",
27
+ provider_version: "2",
28
+ success: true
29
+ )
30
+
31
+ rescue StandardError => e
32
+ puts "#{e.class} #{e.message}"
33
+ puts e.backtrace
34
+ exit 1
35
+ end
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env ruby
2
+ begin
3
+
4
+ $LOAD_PATH << "#{Dir.pwd}/lib"
5
+ require "pact_broker/test/http_test_data_builder"
6
+ base_url = ENV["PACT_BROKER_BASE_URL"] || "http://localhost:9292"
7
+
8
+ td = PactBroker::Test::HttpTestDataBuilder.new(base_url)
9
+ td.delete_pacticipant("some-consumer")
10
+ .delete_pacticipant("some-provider")
11
+ .create_pacticipant("some-consumer")
12
+ .create_pacticipant("some-provider")
13
+ .publish_pact(consumer: "some-consumer", consumer_version: "1", provider: "some-provider", content_id: "111", branch: "main")
14
+ .publish_pact(consumer: "some-consumer", consumer_version: "2", provider: "some-provider", content_id: "111", branch: "feat/x")
15
+ .get_pacts_for_verification(
16
+ provider_version_tag: "main",
17
+ consumer_version_selectors: [{ branch: "main" }, { branch: "feat/x" }]
18
+ )
19
+ .verify_pact(
20
+ index: 0,
21
+ provider_version_tag: "main",
22
+ provider_version: "1",
23
+ success: true
24
+ )
25
+
26
+ rescue StandardError => e
27
+ puts "#{e.class} #{e.message}"
28
+ puts e.backtrace
29
+ exit 1
30
+ end
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env ruby
2
+ begin
3
+
4
+ $LOAD_PATH << "#{Dir.pwd}/lib"
5
+ require "pact_broker/test/http_test_data_builder"
6
+ base_url = ENV["PACT_BROKER_BASE_URL"] || "http://localhost:9292"
7
+
8
+ td = PactBroker::Test::HttpTestDataBuilder.new(base_url)
9
+ td.delete_webhook(uuid: "7a5da39c-8e50-4cc9-ae16-dfa5be043e8c")
10
+ .create_global_webhook_for_contract_changed(uuid: "7a5da39c-8e50-4cc9-ae16-dfa5be043e8c")
11
+ .delete_pacticipant("foo-consumer")
12
+ .delete_pacticipant("bar-provider")
13
+ .create_pacticipant("foo-consumer")
14
+ .create_pacticipant("bar-provider")
15
+ .publish_pact(consumer: "foo-consumer", consumer_version: "1", provider: "bar-provider", content_id: "111", tag: "main")
16
+
17
+
18
+ rescue StandardError => e
19
+ puts "#{e.class} #{e.message}"
20
+ puts e.backtrace
21
+ exit 1
22
+ end
@@ -1,7 +1,16 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require "yaml"
3
+ INTRO = <<EOM
4
+ <!-- This is a generated file. Please do not edit it directly. -->
5
+
6
+ The Pact Broker supports configuration via environment variables or a YAML file.
4
7
 
8
+ To configure the application using a YAML file, place it in the location `config/pact_broker.yml`,
9
+ relative to the working directory of the application, or set the environment
10
+ variable `PACT_BROKER_CONF` to the full path to the configuration file.
11
+ EOM
12
+
13
+ require "yaml"
5
14
  $stream = StringIO.new
6
15
 
7
16
  def write string
@@ -25,6 +34,7 @@ def in_backticks value
25
34
  end
26
35
 
27
36
  docs_dir = File.expand_path("../../../docs", __FILE__)
37
+ configuration_doc_path = File.join(docs_dir, "CONFIGURATION.md")
28
38
  environment_variable_file = File.join(docs_dir, "configuration.yml")
29
39
  doc = YAML.load(File.read(environment_variable_file))
30
40
 
@@ -42,6 +52,8 @@ write "# Pact Broker Configuration\n\n"
42
52
 
43
53
  write "\n"
44
54
 
55
+ write INTRO
56
+
45
57
  doc["groups"].each do | group |
46
58
  write "<br/>\n\n"
47
59
  write "## #{group["title"]}\n\n<hr/>\n"
@@ -55,9 +67,17 @@ doc["groups"].each do | group |
55
67
  write "### #{name}\n\n"
56
68
  write "#{metadata["description"]}\n\n"
57
69
 
70
+ write "**YAML configuration key name:** #{in_backticks(name)}<br/>"
71
+ write "**Environment variable name:** `PACT_BROKER_#{name.upcase}`<br/>"
72
+ write "**Supported versions:** #{metadata["supported_versions"]}<br/>" if metadata["supported_versions"]
58
73
  write "**Required:** #{metadata["required"] || "false"}<br/>" if metadata["required"]
59
74
  write "**Format:** #{metadata["format"]}<br/>" if metadata["format"]
60
- write "**Default:** #{in_backticks(metadata["default"])}<br/>" if !metadata["default"].nil?
75
+
76
+ write "**Default:** #{in_backticks(metadata["default_value"])}<br/>" if !metadata["default_value"].nil?
77
+ write "**Default:** #{metadata["default_description"]}<br/>" if !metadata["default_description"].nil?
78
+ if metadata["allowed_values_description"]
79
+ write "**Allowed values:** #{metadata["allowed_values_description"]}<br/>"
80
+ end
61
81
  if metadata["allowed_values"]
62
82
  allowed_values = metadata["allowed_values"].collect{ |val| in_backticks(val) }.join(", ")
63
83
  write "**Allowed values:** #{allowed_values}<br/>"
@@ -72,7 +92,7 @@ doc["groups"].each do | group |
72
92
  end
73
93
  end
74
94
 
75
- File.open(File.join(docs_dir, "CONFIGURATION.md"), "w") { |file| file << $stream.string }
95
+ File.open(configuration_doc_path, "w") { |file| file << $stream.string }
76
96
 
77
97
  required_env_vars = []
78
98
 
@@ -84,3 +104,4 @@ end
84
104
 
85
105
  puts "Required:"
86
106
  puts required_env_vars
107
+ puts configuration_doc_path
@@ -0,0 +1,55 @@
1
+ #! /usr/bin/env ruby
2
+
3
+ require "sequel"
4
+ Sequel::Model.plugin :subclasses
5
+
6
+ DATABASE_CREDENTIALS = {
7
+ adapter: "postgres",
8
+ database: ENV["DATABASE"] || "postgres",
9
+ username: ENV["DATABASE_USERNAME"] || "postgres",
10
+ password: ENV["DATABASE_PASSWORD"] || "postgres",
11
+ host: "localhost",
12
+ :encoding => "utf8"
13
+ }
14
+ Sequel.connect(DATABASE_CREDENTIALS)
15
+
16
+ $LOAD_PATH.unshift "./lib"
17
+ $LOAD_PATH.unshift "./tasks"
18
+ ENV["RACK_ENV"] = "development"
19
+ require "pact_broker/db/models"
20
+
21
+ def generate_erd_graphviz()
22
+ associations = []
23
+ Sequel::Model.descendents.each do |model|
24
+ next if model.name.nil?
25
+ model.associations.each do |a|
26
+ ar = model.association_reflection(a)
27
+ associations << [model.name, ar[:type], ar.associated_class.name]
28
+ end
29
+ end
30
+ styles = {
31
+ :many_to_one=>:bold,
32
+ :one_to_many=>:solid,
33
+ :many_to_many=>:dashed,
34
+ :one_to_one=>:dotted
35
+ }
36
+
37
+ graph = "digraph G {\n"
38
+ graph += associations.uniq.map{|c, t, ac| " \"#{c}\" -> \"#{ac}\" [style=#{styles[t]}];"}.sort.join("\n")
39
+ graph += "\n}"
40
+
41
+ graph
42
+ end
43
+
44
+ puts "Usage:"
45
+ puts "generate-erd [erd-filename]"
46
+ puts "CAUTION: Please make sure that you have graphviz installed"
47
+ puts
48
+
49
+ GRAPHVIZ_FILENAME = ARGV[0] || "erd"
50
+
51
+ puts "Generating graphviz file ..."
52
+ File.write("#{GRAPHVIZ_FILENAME}.dot", generate_erd_graphviz())
53
+
54
+ puts "Converting graphviz file to a pdf"
55
+ `dot -Tpdf "#{GRAPHVIZ_FILENAME}.dot" > "#{GRAPHVIZ_FILENAME}.pdf"`