pact_broker 2.105.0 → 2.107.0.beta.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (178) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +57 -1
  3. data/Gemfile +3 -0
  4. data/README.md +1 -1
  5. data/db/migrations/20221130_add_provider_version_id_index_to_verifications.rb +28 -0
  6. data/db/migrations/20221208_add_index_to_pact_version_provider_tag_successful_verifications.rb +21 -0
  7. data/db/migrations/20221215_add_prov_ver_id_ndx_to_latest_verifi_id_for_pact_ver_and_prov_ver.rb +21 -0
  8. data/db/migrations/20230131_add_cons_ver_id_ndx_to_latest_pp_id_for_cons_ver.rb +21 -0
  9. data/db/migrations/20230216_add_branch_heads_branch_version_id_index.rb +21 -0
  10. data/db/migrations/20230428_add_index_for_webhook_executions_pact_publication_id.rb +17 -0
  11. data/docs/CONFIGURATION.md +1 -1
  12. data/docs/api/PAGINATION.md +43 -0
  13. data/lib/pact_broker/api/contracts/base_contract.rb +22 -7
  14. data/lib/pact_broker/api/contracts/can_i_deploy_query_schema.rb +34 -0
  15. data/lib/pact_broker/api/contracts/configuration.rb +2 -0
  16. data/lib/pact_broker/api/contracts/consumer_version_selector_contract.rb +140 -0
  17. data/lib/pact_broker/api/contracts/dry_validation_errors_formatter.rb +50 -0
  18. data/lib/pact_broker/api/contracts/dry_validation_macros.rb +79 -0
  19. data/lib/pact_broker/api/contracts/dry_validation_methods.rb +71 -0
  20. data/lib/pact_broker/api/contracts/environment_schema.rb +19 -33
  21. data/lib/pact_broker/api/contracts/pacticipant_create_schema.rb +4 -17
  22. data/lib/pact_broker/api/contracts/pacticipant_schema.rb +15 -24
  23. data/lib/pact_broker/api/contracts/pacts_for_verification_json_query_schema.rb +37 -146
  24. data/lib/pact_broker/api/contracts/pacts_for_verification_query_string_schema.rb +7 -20
  25. data/lib/pact_broker/api/contracts/publish_contracts_contract_contract.rb +62 -0
  26. data/lib/pact_broker/api/contracts/publish_contracts_schema.rb +25 -112
  27. data/lib/pact_broker/api/contracts/put_pact_params_contract.rb +21 -26
  28. data/lib/pact_broker/api/contracts/utf_8_validation.rb +19 -0
  29. data/lib/pact_broker/api/contracts/validation_helpers.rb +71 -0
  30. data/lib/pact_broker/api/contracts/verification_contract.rb +10 -29
  31. data/lib/pact_broker/api/contracts/webhook_contract.rb +20 -170
  32. data/lib/pact_broker/api/contracts/webhook_pacticipant_contract.rb +33 -0
  33. data/lib/pact_broker/api/contracts/webhook_request_contract.rb +125 -0
  34. data/lib/pact_broker/api/contracts.rb +3 -0
  35. data/lib/pact_broker/api/decorators/custom_error_problem_json_decorator.rb +36 -0
  36. data/lib/pact_broker/api/decorators/dashboard_text_decorator.rb +2 -2
  37. data/lib/pact_broker/api/decorators/extended_pact_decorator.rb +1 -1
  38. data/lib/pact_broker/api/decorators/matrix_decorator.rb +4 -4
  39. data/lib/pact_broker/api/decorators/matrix_text_decorator.rb +1 -1
  40. data/lib/pact_broker/api/decorators/pact_decorator.rb +1 -1
  41. data/lib/pact_broker/api/decorators/pacticipant_collection_decorator.rb +5 -2
  42. data/lib/pact_broker/api/decorators/pacticipant_decorator.rb +2 -1
  43. data/lib/pact_broker/api/decorators/pacts_for_verification_query_decorator.rb +4 -1
  44. data/lib/pact_broker/api/decorators/pagination_links.rb +11 -0
  45. data/lib/pact_broker/api/decorators/runtime_error_problem_json_decorator.rb +34 -0
  46. data/lib/pact_broker/api/decorators/validation_errors_problem_json_decorator.rb +66 -0
  47. data/lib/pact_broker/api/decorators/verifiable_pact_decorator.rb +4 -4
  48. data/lib/pact_broker/api/decorators/webhook_decorator.rb +2 -3
  49. data/lib/pact_broker/api/decorators/webhook_execution_result_decorator.rb +5 -12
  50. data/lib/pact_broker/api/resources/all_webhooks.rb +5 -11
  51. data/lib/pact_broker/api/resources/badge_methods.rb +1 -1
  52. data/lib/pact_broker/api/resources/base_resource.rb +31 -68
  53. data/lib/pact_broker/api/resources/branch_version.rb +3 -3
  54. data/lib/pact_broker/api/resources/can_i_deploy.rb +4 -19
  55. data/lib/pact_broker/api/resources/can_i_deploy_pacticipant_version_by_branch_to_environment.rb +1 -4
  56. data/lib/pact_broker/api/resources/can_i_deploy_pacticipant_version_by_tag_to_tag.rb +0 -2
  57. data/lib/pact_broker/api/resources/can_i_deploy_pacticipant_version_by_tag_to_tag_badge.rb +1 -2
  58. data/lib/pact_broker/api/resources/currently_deployed_versions_for_environment.rb +2 -2
  59. data/lib/pact_broker/api/resources/currently_supported_versions_for_environment.rb +2 -2
  60. data/lib/pact_broker/api/resources/dashboard.rb +3 -3
  61. data/lib/pact_broker/api/resources/deployed_version.rb +1 -1
  62. data/lib/pact_broker/api/resources/deployed_versions_for_version_and_environment.rb +2 -2
  63. data/lib/pact_broker/api/resources/environment.rb +1 -1
  64. data/lib/pact_broker/api/resources/environments.rb +2 -2
  65. data/lib/pact_broker/api/resources/error_handling_methods.rb +57 -0
  66. data/lib/pact_broker/api/resources/error_response_generator.rb +70 -0
  67. data/lib/pact_broker/api/resources/integrations.rb +1 -1
  68. data/lib/pact_broker/api/resources/label.rb +1 -1
  69. data/lib/pact_broker/api/resources/latest_pact.rb +2 -2
  70. data/lib/pact_broker/api/resources/latest_pacts.rb +1 -1
  71. data/lib/pact_broker/api/resources/latest_verifications_for_consumer_version.rb +2 -2
  72. data/lib/pact_broker/api/resources/matrix.rb +2 -2
  73. data/lib/pact_broker/api/resources/matrix_for_consumer_and_provider.rb +1 -1
  74. data/lib/pact_broker/api/resources/pact.rb +7 -4
  75. data/lib/pact_broker/api/resources/pact_triggered_webhooks.rb +1 -1
  76. data/lib/pact_broker/api/resources/pact_version.rb +1 -1
  77. data/lib/pact_broker/api/resources/pact_versions.rb +1 -1
  78. data/lib/pact_broker/api/resources/pact_webhooks.rb +7 -14
  79. data/lib/pact_broker/api/resources/pact_webhooks_status.rb +6 -2
  80. data/lib/pact_broker/api/resources/pacticipant.rb +1 -1
  81. data/lib/pact_broker/api/resources/pacticipant_webhooks.rb +7 -5
  82. data/lib/pact_broker/api/resources/pacticipants.rb +6 -3
  83. data/lib/pact_broker/api/resources/pacticipants_for_label.rb +1 -1
  84. data/lib/pact_broker/api/resources/pagination_methods.rb +8 -4
  85. data/lib/pact_broker/api/resources/previous_distinct_pact_version.rb +1 -1
  86. data/lib/pact_broker/api/resources/provider_pacts.rb +1 -1
  87. data/lib/pact_broker/api/resources/provider_pacts_for_verification.rb +4 -13
  88. data/lib/pact_broker/api/resources/publish_contracts.rb +8 -3
  89. data/lib/pact_broker/api/resources/released_version.rb +1 -1
  90. data/lib/pact_broker/api/resources/released_versions_for_version_and_environment.rb +2 -2
  91. data/lib/pact_broker/api/resources/tag.rb +1 -1
  92. data/lib/pact_broker/api/resources/tagged_pact_versions.rb +1 -1
  93. data/lib/pact_broker/api/resources/triggered_webhook_logs.rb +2 -2
  94. data/lib/pact_broker/api/resources/verification.rb +2 -2
  95. data/lib/pact_broker/api/resources/verification_triggered_webhooks.rb +1 -1
  96. data/lib/pact_broker/api/resources/verifications.rb +4 -6
  97. data/lib/pact_broker/api/resources/version.rb +1 -1
  98. data/lib/pact_broker/api/resources/versions.rb +6 -13
  99. data/lib/pact_broker/api/resources/webhook.rb +7 -6
  100. data/lib/pact_broker/api/resources/webhook_execution.rb +6 -4
  101. data/lib/pact_broker/api.rb +3 -13
  102. data/lib/pact_broker/app.rb +0 -2
  103. data/lib/pact_broker/application_context.rb +4 -4
  104. data/lib/pact_broker/certificates/certificate.rb +1 -0
  105. data/lib/pact_broker/config/setting.rb +1 -0
  106. data/lib/pact_broker/contracts/service.rb +1 -0
  107. data/lib/pact_broker/date_helper.rb +1 -1
  108. data/lib/pact_broker/db/clean_incremental.rb +67 -59
  109. data/lib/pact_broker/db/delete_overwritten_data.rb +6 -2
  110. data/lib/pact_broker/deployments/currently_deployed_version_id.rb +2 -0
  111. data/lib/pact_broker/deployments/deployed_version.rb +2 -0
  112. data/lib/pact_broker/deployments/deployed_version_service.rb +5 -1
  113. data/lib/pact_broker/deployments/environment.rb +2 -0
  114. data/lib/pact_broker/deployments/environment_service.rb +4 -3
  115. data/lib/pact_broker/deployments/released_version.rb +2 -0
  116. data/lib/pact_broker/deployments/released_version_service.rb +4 -0
  117. data/lib/pact_broker/diagnostic/resources/base_resource.rb +1 -1
  118. data/lib/pact_broker/doc/views/index/publish-contracts.markdown +5 -5
  119. data/lib/pact_broker/domain/label.rb +1 -0
  120. data/lib/pact_broker/domain/tag.rb +2 -0
  121. data/lib/pact_broker/domain/verification.rb +1 -1
  122. data/lib/pact_broker/domain/version.rb +4 -1
  123. data/lib/pact_broker/domain/webhook.rb +1 -1
  124. data/lib/pact_broker/index/service.rb +2 -2
  125. data/lib/pact_broker/integrations/integration.rb +1 -0
  126. data/lib/pact_broker/locale/en.yml +36 -14
  127. data/lib/pact_broker/matrix/query_ids.rb +4 -4
  128. data/lib/pact_broker/matrix/resolved_selector.rb +6 -1
  129. data/lib/pact_broker/matrix/service.rb +1 -0
  130. data/lib/pact_broker/messages.rb +5 -1
  131. data/lib/pact_broker/pacticipants/repository.rb +16 -14
  132. data/lib/pact_broker/pacticipants/service.rb +11 -8
  133. data/lib/pact_broker/pacts/pact_params.rb +6 -17
  134. data/lib/pact_broker/pacts/pact_version.rb +1 -0
  135. data/lib/pact_broker/pacts/selected_pact.rb +4 -0
  136. data/lib/pact_broker/policies.rb +4 -4
  137. data/lib/pact_broker/repositories/helpers.rb +11 -0
  138. data/lib/pact_broker/repositories/page.rb +24 -0
  139. data/lib/pact_broker/string_refinements.rb +4 -0
  140. data/lib/pact_broker/tasks/clean_task.rb +7 -3
  141. data/lib/pact_broker/test/http_test_data_builder.rb +46 -2
  142. data/lib/pact_broker/ui/app.rb +2 -2
  143. data/lib/pact_broker/ui/views/matrix/show.haml +1 -1
  144. data/lib/pact_broker/verifications/latest_verification_id_for_pact_version_and_provider_version.rb +1 -1
  145. data/lib/pact_broker/verifications/pact_version_provider_tag_successful_verification.rb +1 -0
  146. data/lib/pact_broker/verifications/repository.rb +14 -11
  147. data/lib/pact_broker/verifications/service.rb +0 -6
  148. data/lib/pact_broker/version.rb +1 -1
  149. data/lib/pact_broker/versions/branch.rb +1 -0
  150. data/lib/pact_broker/versions/branch_head.rb +2 -1
  151. data/lib/pact_broker/versions/branch_version.rb +11 -0
  152. data/lib/pact_broker/versions/repository.rb +12 -0
  153. data/lib/pact_broker/versions/service.rb +4 -0
  154. data/lib/pact_broker/webhooks/execution.rb +1 -1
  155. data/lib/pact_broker/webhooks/repository.rb +1 -1
  156. data/lib/pact_broker/webhooks/service.rb +3 -25
  157. data/lib/pact_broker/webhooks/triggered_webhook.rb +1 -0
  158. data/lib/pact_broker/webhooks/webhook_event.rb +1 -0
  159. data/lib/pact_broker/webmachine.rb +22 -0
  160. data/lib/rack/pact_broker/invalid_uri_protection.rb +1 -1
  161. data/lib/rack/pact_broker/request_target.rb +1 -1
  162. data/lib/rack/pact_broker/use_when.rb +6 -5
  163. data/lib/sequel/plugins/age.rb +13 -0
  164. data/lib/webmachine/application_monkey_patch.rb +15 -0
  165. data/lib/webmachine/describe_routes.rb +35 -8
  166. data/lib/webmachine/render_error_monkey_patch.rb +70 -0
  167. data/pact_broker.gemspec +7 -18
  168. metadata +72 -76
  169. data/lib/pact/doc/README.md +0 -5
  170. data/lib/pact_broker/api/contracts/dry_validation_predicates.rb +0 -36
  171. data/lib/pact_broker/api/contracts/dry_validation_workarounds.rb +0 -39
  172. data/lib/pact_broker/api/contracts/pacticipant_name_contract.rb +0 -24
  173. data/lib/pact_broker/api/contracts/pacticipant_name_validation.rb +0 -30
  174. data/lib/pact_broker/api/contracts/request_validations.rb +0 -33
  175. data/lib/pact_broker/api/resources/error_response_body_generator.rb +0 -41
  176. data/lib/pact_broker/api/resources/webhook_resource_methods.rb +0 -17
  177. data/lib/pact_broker/matrix/can_i_deploy_query_schema.rb +0 -46
  178. data/lib/rack/pact_broker/convert_404_to_hal.rb +0 -20
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c43c0dbf719c9e927fad6ffcee28b559036726a61a41813a3451554e5f1db087
4
- data.tar.gz: '0964dcfea819d1ccc1c1ccc15d8a7493670dfbefbde75aedb63ac9405c7c764d'
3
+ metadata.gz: 3783c3552a022360c2d78e4c3955aef888b18920d60f980ace930f7f03eef877
4
+ data.tar.gz: 0b327308a96b96c97fcd57b33b272b54d6a9106cac3d84ba7a49a45844d99fb3
5
5
  SHA512:
6
- metadata.gz: 12f323b624a2ff4dcc7827e254ec71c83a1d3ffe89532746feb67e360aa5fda938927f43176b86ea08b7b3fddf66d4ef0a5c8cf9ec6b4190332e572a2fd4ad0a
7
- data.tar.gz: a3a5aed03639c5ef8ab602da938e502e4b0434248c99de262bac7a1d6a09e42e4991d32748ae542bfdf1376db133957ff69652b99e49cc1fdfc22f0845907f22
6
+ metadata.gz: e6caba3dfdc61ebef92e21b34dc77f363b8cace4382d8b51d274fa757462e9dc67bf7e9c33f2211a6f9197e83db8e59bdb7ce66027c8343ce3ecb2dedea46a47
7
+ data.tar.gz: cc1f0c8b8b300054f0c338a7a50dec6c41532c602254c6d8ca3236bc497f235846e0ba54b8c7b4a79ba6dce5205e7883c229dfdfac70070fd025b7d2830c2c50
data/CHANGELOG.md CHANGED
@@ -1,3 +1,59 @@
1
+ <a name="v2.107.0.beta.1"></a>
2
+ ### v2.107.0.beta.1 (2023-05-01)
3
+
4
+ <a name="v2.107.0.beta.1"></a>
5
+ ### v2.107.0.beta.1 (2023-05-01)
6
+
7
+ #### Features
8
+
9
+ * add index to webhook_executions pact_publication_id column ([37d1a4cf](/../../commit/37d1a4cf))
10
+ * update webmachine to support ruby 3 ([9bb014e6](/../../commit/9bb014e6))
11
+ * upgrade dry-validation gem in preparation for ruby 3 upgrade ([3b4b66bf](/../../commit/3b4b66bf))
12
+ * restructure logs from DeleteOverwrittenData to match CleanIncremental ([f11a9417](/../../commit/f11a9417))
13
+ * add branch_heads_branch_version_id_index ([b1b4cefb](/../../commit/b1b4cefb))
14
+
15
+ #### Bug Fixes
16
+
17
+ * **pacts for verification**
18
+ * do not allow empty string for provider version branch when it is required for calculating WIP/pending pacts ([412c4289](/../../commit/412c4289))
19
+
20
+ * fix error raised when clean selectors include a selector with a max age and a selector with a max age and a branch ([53b171bd](/../../commit/53b171bd))
21
+
22
+ * **can-i-deploy**
23
+ * correct logic for detecting when only the pacticipant name has been specified for a selector ([85bcdb35](/../../commit/85bcdb35))
24
+
25
+ <a name="v2.106.0"></a>
26
+ ### v2.106.0 (2023-01-31)
27
+
28
+ #### Features
29
+
30
+ * add consumer_version_id index to latest_pact_publication_ids_for_consumer_versions ([b75ca5ee](/../../commit/b75ca5ee))
31
+ * improve the performance of the incremental clean queries ([c3a07c79](/../../commit/c3a07c79))
32
+ * add index to provider_version_id column in latest_verification_id_for_pact_version_and_provider_version ([0e1c43dd](/../../commit/0e1c43dd))
33
+ * Pacticipant pagination (#585) ([f1a9be20](/../../commit/f1a9be20))
34
+ * do not allow JSON request bodies that are not Objects or Arrays ([3d917286](/../../commit/3d917286))
35
+ * add index for verification_id in pact_version_provider_tag_successful_verifications table ([b82a773a](/../../commit/b82a773a))
36
+ * monkey patch Webmachine render_error method to support problem+json (#584) ([508f7ce2](/../../commit/508f7ce2))
37
+ * support problem+json for error messages (#583) ([92957ebb](/../../commit/92957ebb))
38
+ * add index to provider_version_id column in verifications table ([aac33725](/../../commit/aac33725))
39
+
40
+ * **clean**
41
+ * log automatically added selectors ([135c1c0e](/../../commit/135c1c0e))
42
+
43
+ #### Bug Fixes
44
+
45
+ * check that request body does not contain any invalid UTF-8 characters before JSON parsing ([0a08d644](/../../commit/0a08d644))
46
+
47
+ * **versions**
48
+ * add missing next and previous relations to paginated response ([3b46847e](/../../commit/3b46847e))
49
+ * eager load associations for versions endpoint ([2a57dc42](/../../commit/2a57dc42))
50
+
51
+ * **ui**
52
+ * no space after `tag:` (#581) ([1b9ebdfe](/../../commit/1b9ebdfe))
53
+
54
+ * **webhooks**
55
+ * correctly validate HTTP method when the given method is not a valid class name ([6da5a4f3](/../../commit/6da5a4f3))
56
+
1
57
  <a name="v2.105.0"></a>
2
58
  ### v2.105.0 (2022-10-19)
3
59
 
@@ -940,7 +996,7 @@
940
996
  * log schema versions and migration info on startup ([b385e535](/../../commit/b385e535))
941
997
  * allow options to be passed to Sequel migrate via the MigrationTask ([143613e7](/../../commit/143613e7))
942
998
 
943
- * allow Pactflow messages in logs to be hidden by setting PACT_BROKER_HIDE_PACTFLOW_MESSAGES=true ([a7550105](/../../commit/a7550105))
999
+ * allow PactFlow messages in logs to be hidden by setting PACT_BROKER_HIDE_PACTFLOW_MESSAGES=true ([a7550105](/../../commit/a7550105))
944
1000
 
945
1001
  * **can-i-deploy**
946
1002
  * experimental - add a warning message if there are interactions missing verification test results. ([f7ab8cc5](/../../commit/f7ab8cc5))
data/Gemfile CHANGED
@@ -2,6 +2,9 @@ source "https://rubygems.org"
2
2
 
3
3
  gemspec
4
4
 
5
+ # While https://github.com/brandonhilkert/sucker_punch/pull/253 is outstanding
6
+ gem "sucker_punch", git: "https://github.com/pact-foundation/sucker_punch.git", ref: "fix/rename-is-singleton-class-method-2"
7
+
5
8
  gem "rake", "~>12.3.3"
6
9
  gem "sqlite3", "~>1.3"
7
10
  gem "conventional-changelog", "~>1.3"
data/README.md CHANGED
@@ -10,7 +10,7 @@ The Pact Broker is an application for sharing of consumer driven contracts and v
10
10
  <a href="https://pactflow.io/?utm_source=github&utm_campaign=pact_broker_intro"><img src="docs/images/Pactflow logo - black small.png"></a>
11
11
  <br/>
12
12
 
13
- You can try out a Pact Broker for free at <a href="https://pactflow.io/?utm_source=github&utm_campaign=pact_broker_intro"/>pactflow.io</a>. Built by a group of core Pact maintainers, Pactflow is a fork of the OSS Pact Broker with extra goodies like an improved UI, field level verification results and federated login.
13
+ You can try out a Pact Broker for free at <a href="https://pactflow.io/?utm_source=github&utm_campaign=pact_broker_intro"/>pactflow.io</a>. Built by a group of core Pact maintainers, PactFlow is a fork of the OSS Pact Broker with extra goodies like an improved UI, field level verification results and federated login.
14
14
 
15
15
  **Why do I need a Pact Broker?**
16
16
 
@@ -0,0 +1,28 @@
1
+ require_relative "migration_helper"
2
+
3
+ include PactBroker::MigrationHelper
4
+
5
+ Sequel.migration do
6
+ up do
7
+ # MySQL automatically creates indexes for foreign keys then complains if you
8
+ # re-create it with a different name and try to drop it.
9
+
10
+ # https://stackoverflow.com/a/52274628/832671 - "When there is only one index that can be used
11
+ # for the foreign key, it can't be dropped. If you really wan't to drop it, you either have to drop
12
+ # the foreign key constraint or to create another index for it first."
13
+ if !mysql?
14
+ alter_table(:verifications) do
15
+ add_index([:provider_version_id], name: "verifications_provider_version_id_index")
16
+ end
17
+ end
18
+
19
+ end
20
+
21
+ down do
22
+ if !mysql?
23
+ alter_table(:verifications) do
24
+ drop_index([:provider_version_id], name: "verifications_provider_version_id_index")
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,21 @@
1
+ require_relative "migration_helper"
2
+
3
+ include PactBroker::MigrationHelper
4
+
5
+ Sequel.migration do
6
+ up do
7
+ if !mysql?
8
+ alter_table(:pact_version_provider_tag_successful_verifications) do
9
+ add_index([:verification_id], name: "pact_ver_prov_tag_success_verif_verif_id_ndx")
10
+ end
11
+ end
12
+ end
13
+
14
+ down do
15
+ if !mysql?
16
+ alter_table(:pact_version_provider_tag_successful_verifications) do
17
+ drop_index([:verification_id], name: "pact_ver_prov_tag_success_verif_verif_id_ndx")
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,21 @@
1
+ require_relative "migration_helper"
2
+
3
+ include PactBroker::MigrationHelper
4
+
5
+ Sequel.migration do
6
+ up do
7
+ if !mysql?
8
+ alter_table(:latest_verification_id_for_pact_version_and_provider_version) do
9
+ add_index([:provider_version_id], name: "latest_verif_id_for_pact_ver_and_prov_ver_prov_ver_id_ndx")
10
+ end
11
+ end
12
+ end
13
+
14
+ down do
15
+ if !mysql?
16
+ alter_table(:latest_verification_id_for_pact_version_and_provider_version) do
17
+ drop_index([:provider_version_id], name: "latest_verif_id_for_pact_ver_and_prov_ver_prov_ver_id_ndx")
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,21 @@
1
+ require_relative "migration_helper"
2
+
3
+ include PactBroker::MigrationHelper
4
+
5
+ Sequel.migration do
6
+ up do
7
+ if !mysql?
8
+ alter_table(:latest_pact_publication_ids_for_consumer_versions) do
9
+ add_index([:consumer_version_id], name: "latest_pp_ids_for_cons_ver_con_ver_id_ndx")
10
+ end
11
+ end
12
+ end
13
+
14
+ down do
15
+ if !mysql?
16
+ alter_table(:latest_pact_publication_ids_for_consumer_versions) do
17
+ drop_index([:consumer_version_id], name: "latest_pp_ids_for_cons_ver_con_ver_id_ndx")
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,21 @@
1
+ require_relative "migration_helper"
2
+
3
+ include PactBroker::MigrationHelper
4
+
5
+ Sequel.migration do
6
+ up do
7
+ if !mysql?
8
+ alter_table(:branch_heads) do
9
+ add_index([:branch_version_id], name: "branch_heads_branch_version_id_index")
10
+ end
11
+ end
12
+ end
13
+
14
+ down do
15
+ if !mysql?
16
+ alter_table(:branch_heads) do
17
+ drop_index([:branch_version_id], name: "branch_heads_branch_version_id_index")
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,17 @@
1
+ Sequel.migration do
2
+ up do
3
+ if !mysql?
4
+ alter_table(:webhook_executions) do
5
+ add_index([:pact_publication_id], name: "webhook_executions_pact_publication_id_index")
6
+ end
7
+ end
8
+ end
9
+
10
+ down do
11
+ if !mysql?
12
+ alter_table(:webhook_executions) do
13
+ drop_index([:pact_publication_id], name: "webhook_executions_pact_publication_id_index")
14
+ end
15
+ end
16
+ end
17
+ end
@@ -67,7 +67,7 @@ Ensure the application [`log_level`](#log_level) is set to `debug` when this set
67
67
 
68
68
  ### hide_pactflow_messages
69
69
 
70
- Set to `true` to hide the messages in the logs about Pactflow
70
+ Set to `true` to hide the messages in the logs about PactFlow
71
71
 
72
72
  **Environment variable name:** `PACT_BROKER_HIDE_PACTFLOW_MESSAGES`<br/>
73
73
  **YAML configuration key name:** `hide_pactflow_messages`<br/>
@@ -0,0 +1,43 @@
1
+ # Pagination
2
+
3
+ Pagination of results is available for some endpoints used by the Pact Broker. These paginated responses can be used to programmatically load smaller subsections of the api results, in turn enabling improved performance and easier client side management of the data.
4
+
5
+ For endpoints that support pagination a paginated response can be retrieved using the following query parameters:
6
+
7
+ * `pageNumber=1`
8
+ * `pageSize=100`
9
+
10
+ eg.
11
+
12
+ ```
13
+ https://pact-broker/pacticipants?pageSize=100&pageNumber=1
14
+ ```
15
+
16
+ Including one or both of these in the api call will result in a paginated response. Where only one parameter is included the other will use the default value specified above.
17
+
18
+ To retrieve the next or previous page of the paginated response use the URL provided in the response body under the `_links` section, labeled `next` or `previous`.
19
+ The first page will not have a previous link, while the last page will not have a next link.
20
+
21
+ The recommended approach to iterate the full list of resources is to fetch the first page, then call the `href` of the `next` relation until there is no `next` relation returned.
22
+
23
+ ```
24
+ "_links": {
25
+ "next": {
26
+ "href": "http://pact-broker/pacticipants?pageSize=100&pageNumber=2",
27
+ "title": "Next page"
28
+ }
29
+ }
30
+
31
+ ```
32
+
33
+ ## Paginated endpoints
34
+
35
+ The following endpoints in the Pact Broker support pagination via the above query parameters:
36
+
37
+ ### [Pacticipants](https://docs.pact.io/pact_broker/api/pacticipants)
38
+
39
+ Ordered Alphabetically by the Pacticipant name.
40
+
41
+ ### [Pacticipant Versions](https://docs.pact.io/pact_broker/overview#pacticipant-versions)
42
+
43
+ Ordered by date in reverse (most recent Pacticipant Version will be first).
@@ -1,14 +1,29 @@
1
- require "reform"
2
- require "reform/form/dry"
3
-
4
- Reform::Form.class_eval do
5
- feature Reform::Form::Dry
6
- end
1
+ require "dry-validation"
2
+ require "pact_broker/api/contracts/dry_validation_macros"
3
+ require "pact_broker/api/contracts/dry_validation_methods"
4
+ require "pact_broker/api/contracts/dry_validation_errors_formatter"
5
+ require "pact_broker/messages"
6
+ require "pact_broker/hash_refinements"
7
7
 
8
8
  module PactBroker
9
9
  module Api
10
10
  module Contracts
11
- class BaseContract < Reform::Form
11
+ class BaseContract < Dry::Validation::Contract
12
+ include DryValidationMethods
13
+ extend DryValidationErrorsFormatter
14
+
15
+ using PactBroker::HashRefinements
16
+
17
+ # The entry method for all the Dry::Validation::Contract classes
18
+ # eg. MyContract.call(params)
19
+ # It takes the params (doesn't matter if they're string or symbol keys)
20
+ # executes the dry-validation validation, and formats the errors into the Pactflow format.
21
+ #
22
+ # @param [Hash] the parameters to validate
23
+ # @return [Hash] the validation errors to display to the user
24
+ def self.call(params)
25
+ format_errors(new.call(params&.symbolize_keys).errors)
26
+ end
12
27
  end
13
28
  end
14
29
  end
@@ -0,0 +1,34 @@
1
+ require "dry-validation"
2
+ require "pact_broker/messages"
3
+ require "pact_broker/project_root"
4
+ require "pact_broker/string_refinements"
5
+
6
+ module PactBroker
7
+ module Api
8
+ module Contracts
9
+ class CanIDeployQuerySchema < BaseContract
10
+ using PactBroker::StringRefinements
11
+
12
+ params do
13
+ required(:pacticipant).filled(:string)
14
+ required(:version).filled(:string)
15
+ optional(:to).filled(:string)
16
+ optional(:environment).filled(:string)
17
+ end
18
+
19
+ rule(:pacticipant).validate(:pacticipant_with_name_exists)
20
+ rule(:environment).validate(:environment_with_name_exists)
21
+
22
+ rule(:to, :environment) do
23
+ if provided?(values[:to]) && provided?(values[:environment])
24
+ base.failure(PactBroker::Messages.message("errors.validation.cannot_specify_tag_and_environment"))
25
+ end
26
+
27
+ if not_provided?(values[:to]) && not_provided?(values[:environment])
28
+ base.failure(PactBroker::Messages.message("errors.validation.must_specify_environment_or_tag"))
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -1,5 +1,7 @@
1
1
  require "pact_broker/string_refinements"
2
2
 
3
+ # Allow contracts to be accessed by name and configured/overridden for pf
4
+
3
5
  module PactBroker
4
6
  module Api
5
7
  module Contracts
@@ -0,0 +1,140 @@
1
+ require "pact_broker/api/contracts/base_contract"
2
+
3
+ module PactBroker
4
+ module Api
5
+ module Contracts
6
+ class ConsumerVersionSelectorContract < BaseContract
7
+ option :parent # the parent hash in which the ConsumerVersionSelector is embedded
8
+
9
+ BRANCH_KEYS = [:latest, :tag, :fallbackTag, :branch, :fallbackBranch, :matchingBranch, :mainBranch]
10
+ ENVIRONMENT_KEYS = [:environment, :deployed, :released, :deployedOrReleased]
11
+ ALL_KEYS = BRANCH_KEYS + ENVIRONMENT_KEYS + [:consumer]
12
+
13
+ json do
14
+ optional(:mainBranch).filled(included_in?: [true])
15
+ optional(:tag).filled(:str?)
16
+ optional(:branch).filled(:str?)
17
+ optional(:matchingBranch).filled(included_in?: [true])
18
+ optional(:latest).filled(included_in?: [true, false])
19
+ optional(:fallbackTag).filled(:str?)
20
+ optional(:fallbackBranch).filled(:str?)
21
+ optional(:consumer).filled(:str?)
22
+ optional(:deployed).filled(included_in?: [true])
23
+ optional(:released).filled(included_in?: [true])
24
+ optional(:deployedOrReleased).filled(included_in?: [true])
25
+ optional(:environment).filled(:str?)
26
+ end
27
+
28
+ rule(:consumer).validate(:not_blank_if_present)
29
+
30
+ # has minimum required params
31
+ rule(*ALL_KEYS) do
32
+ if not_provided?(values[:mainBranch]) &&
33
+ not_provided?(values[:tag]) &&
34
+ not_provided?(values[:branch]) &&
35
+ not_provided?(values[:environment]) &&
36
+ values[:matchingBranch] != true &&
37
+ values[:deployed] != true &&
38
+ values[:released] != true &&
39
+ values[:deployedOrReleased] != true &&
40
+ values[:latest] != true
41
+
42
+ base.failure(validation_message("pacts_for_verification_selector_required_params_missing"))
43
+ end
44
+ end
45
+
46
+ # mainBranch
47
+ rule(*ALL_KEYS) do
48
+ if values[:mainBranch] && values.slice(*ALL_KEYS - [:consumer, :mainBranch, :latest]).any?
49
+ base.failure(validation_message("pacts_for_verification_selector_main_branch_with_other_param_disallowed"))
50
+ end
51
+ end
52
+
53
+ # mainBranch/latest
54
+ rule(:mainBranch, :latest) do
55
+ if values[:mainBranch] && values[:latest] == false
56
+ base.failure(validation_message("pacts_for_verification_selector_main_branch_and_latest_false_disallowed"))
57
+ end
58
+ end
59
+
60
+ # matchingBranch
61
+ rule(*ALL_KEYS) do
62
+ if values[:matchingBranch] && values.slice(*ALL_KEYS - [:consumer, :matchingBranch]).any?
63
+ base.failure(validation_message("pacts_for_verification_selector_matching_branch_with_other_param_disallowed"))
64
+ end
65
+
66
+ if values[:matchingBranch] && not_provided?(parent[:providerVersionBranch])
67
+ base.failure(validation_message("pacts_for_verification_selector_matching_branch_requires_provider_version_branch"))
68
+ end
69
+ end
70
+
71
+ # tag and branch
72
+ rule(:tag, :branch) do
73
+ if values[:tag] && values[:branch]
74
+ base.failure(validation_message("pacts_for_verification_selector_tag_and_branch_disallowed"))
75
+ end
76
+ end
77
+
78
+ # branch/environment keys
79
+ rule(*ALL_KEYS) do
80
+ non_environment_fields = values.slice(*BRANCH_KEYS).keys.sort
81
+ environment_related_fields = values.slice(*ENVIRONMENT_KEYS).keys.sort
82
+
83
+ if (non_environment_fields.any? && environment_related_fields.any?)
84
+ base.failure("cannot specify the #{PactBroker::Messages.pluralize("field", non_environment_fields.count)} #{non_environment_fields.join("/")} with the #{PactBroker::Messages.pluralize("field", environment_related_fields.count)} #{environment_related_fields.join("/")}")
85
+ end
86
+ end
87
+
88
+ # fallbackTag
89
+ rule(:fallbackTag, :tag, :latest) do
90
+ if values[:fallbackTag] && !values[:latest]
91
+ base.failure(validation_message("pacts_for_verification_selector_fallback_tag"))
92
+ end
93
+
94
+ if values[:fallbackTag] && !values[:tag]
95
+ base.failure(validation_message("pacts_for_verification_selector_fallback_tag_requires_tag"))
96
+ end
97
+ end
98
+
99
+ # fallbackBranch
100
+ rule(:fallbackBranch, :branch, :latest) do
101
+ if values[:fallbackBranch] && !values[:branch]
102
+ base.failure(validation_message("pacts_for_verification_selector_fallback_branch_requires_branch"))
103
+ end
104
+
105
+
106
+ if values[:fallbackBranch] && values[:latest] == false
107
+ base.failure(validation_message("pacts_for_verification_selector_fallback_branch_and_latest_false_disallowed"))
108
+ end
109
+ end
110
+
111
+ # branch/latest
112
+ rule(:branch, :latest) do
113
+ if values[:branch] && values[:latest] == false
114
+ base.failure(validation_message("pacts_for_verification_selector_branch_and_latest_false_disallowed"))
115
+ end
116
+ end
117
+
118
+ # environment
119
+ rule(:environment) do
120
+ validate_environment_with_name_exists(value, key) if provided?(value)
121
+ end
122
+
123
+ # deployed, released, deployedOrReleased
124
+ rule(:deployed, :released, :deployedOrReleased) do
125
+ if values[:deployed] && values[:released]
126
+ base.failure(validation_message("pacts_for_verification_selector_deployed_and_released_disallowed"))
127
+ end
128
+
129
+ if values[:deployed] && values[:deployedOrReleased]
130
+ base.failure(validation_message("pacts_for_verification_selector_deployed_and_deployed_or_released_disallowed"))
131
+ end
132
+
133
+ if values[:released] && values[:deployedOrReleased]
134
+ base.failure(validation_message("pacts_for_verification_selector_released_and_deployed_or_released_disallowed"))
135
+ end
136
+ end
137
+ end
138
+ end
139
+ end
140
+ end
@@ -0,0 +1,50 @@
1
+ require "pact_broker/error"
2
+
3
+ module PactBroker
4
+ module Api
5
+ module Contracts
6
+ module DryValidationErrorsFormatter
7
+
8
+ # Formats the dry validation errors in the expected PactBroker error format of { :key => ["errors"] }
9
+ # where there are no nested hashes.
10
+ # @param [Dry::Validation::MessageSet] errors
11
+ # @return [Hash]
12
+ def format_errors(errors)
13
+ errors.each_with_object({}) do | error, errors_hash |
14
+ integers = error.path.select{ | k | k.is_a?(Integer) }
15
+
16
+ if integers.size > 1
17
+ raise PactBroker::Error, "Cannot currently format an error message with more than one index"
18
+ end
19
+
20
+ if integers.empty?
21
+ key = error.path == [nil] ? nil : error.path.join(".").to_sym
22
+ add_error(errors_hash, key, error.text)
23
+ else
24
+ add_indexed_error(errors_hash, error)
25
+ end
26
+ end
27
+ end
28
+
29
+ # @private
30
+ def add_error(errors_hash, key, text)
31
+ errors_hash[key] ||= []
32
+ errors_hash[key] << text
33
+ end
34
+
35
+ # @private
36
+ def add_indexed_error(errors_hash, error)
37
+ error_path_classes = error.path.collect(&:class)
38
+ if error_path_classes == [Symbol, Integer, Symbol]
39
+ add_error(errors_hash, error.path.first, "#{error.path.last} #{error.text} (at index #{error.path[1]})")
40
+ elsif error_path_classes == [Symbol, Integer]
41
+ add_error(errors_hash, error.path.first, "#{error.text} (at index #{error.path[1]})")
42
+ else
43
+ # Don't have any usecases for this - will deal with it when it happens
44
+ raise PactBroker::Error, "Cannot currently format an error message with path classes #{error_path_classes}"
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,79 @@
1
+ require "pact_broker/api/contracts/dry_validation_methods"
2
+
3
+ Dry::Validation.register_macro(:not_multiple_lines) do
4
+ PactBroker::Api::Contracts::DryValidationMethods.validate_not_multiple_lines(value, key)
5
+ end
6
+
7
+ Dry::Validation.register_macro(:no_spaces_if_present) do
8
+ PactBroker::Api::Contracts::DryValidationMethods.validate_no_spaces_if_present(value, key)
9
+ end
10
+
11
+ Dry::Validation.register_macro(:not_blank_if_present) do
12
+ PactBroker::Api::Contracts::DryValidationMethods.validate_not_blank_if_present(value, key)
13
+ end
14
+
15
+ Dry::Validation.register_macro(:array_values_not_blank_if_any) do
16
+ value&.each_with_index do | item, index |
17
+ PactBroker::Api::Contracts::DryValidationMethods.validate_not_blank_if_present(item, key(path.keys + [index]))
18
+ end
19
+ end
20
+
21
+ Dry::Validation.register_macro(:valid_url_if_present) do
22
+ PactBroker::Api::Contracts::DryValidationMethods.validate_valid_url(value, key)
23
+ end
24
+
25
+ Dry::Validation.register_macro(:valid_version_number) do
26
+ PactBroker::Api::Contracts::DryValidationMethods.validate_version_number(value, key)
27
+ end
28
+
29
+ Dry::Validation.register_macro(:pacticipant_with_name_exists) do
30
+ PactBroker::Api::Contracts::DryValidationMethods.validate_pacticipant_with_name_exists(value, key)
31
+ end
32
+
33
+ Dry::Validation.register_macro(:environment_with_name_exists) do
34
+ PactBroker::Api::Contracts::DryValidationMethods.validate_environment_with_name_exists(value, key)
35
+ end
36
+
37
+ # Validate each object in an array with the specified contract,
38
+ # and merge the errors into the appropriate path in the parent
39
+ # validation results.
40
+ # eg.
41
+ # rule(:myChildArray).validate(validate_each_with_contract: MyChildContract)
42
+ #
43
+ # If the child contract defines a option called `parent` then it can access the parent
44
+ # hash for validation rules that need to work across the levels.
45
+ # eg. ConsumerVersionSelectorContract for the matchingBranch rule
46
+ #
47
+ # Will not add any errors if the array is nil
48
+ Dry::Validation.register_macro(:validate_each_with_contract) do |macro:|
49
+ value&.each_with_index do | item, index |
50
+ child_contract_class = macro.args[0]
51
+ messages = child_contract_class.new(parent: values).call(item).errors(full: true).to_hash.values.flatten
52
+ messages.each do | message |
53
+ key(path.keys + [index]).failure(message)
54
+ end
55
+ end
56
+ end
57
+
58
+ # Validate a child node with the specified contract,
59
+ # and merge the errors into the appropriate path in the parent
60
+ # validation results.
61
+ # eg.
62
+ # rule(:myChildHash).validate(validate_with_contract: MyChildContract)
63
+ #
64
+ # If the child contract defines a option called `parent` then it can access the parent
65
+ # hash for validation rules that need to work across the levels.
66
+ # eg. ConsumerVersionSelectorContract for the matchingBranch rule
67
+ #
68
+ # Will not add any errors if the value is nil
69
+ Dry::Validation.register_macro(:validate_with_contract) do |macro:|
70
+ if value
71
+ child_contract_class = macro.args[0]
72
+ errors = child_contract_class.new(parent: values).call(value).errors.to_hash
73
+ errors.each do | key, messages |
74
+ messages.each do | message |
75
+ key(path.keys + [key]).failure(message)
76
+ end
77
+ end
78
+ end
79
+ end