pact_broker 2.76.2 → 2.79.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (172) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +12 -0
  3. data/.github/workflows/release_gem.yml +1 -0
  4. data/.github/workflows/test-ruby-3.yml +19 -0
  5. data/.github/workflows/test.yml +16 -7
  6. data/.gitignore +3 -1
  7. data/CHANGELOG.md +53 -0
  8. data/DEVELOPER_DOCUMENTATION.md +13 -0
  9. data/DEVELOPER_SETUP.md +62 -3
  10. data/Dockerfile +1 -0
  11. data/ISSUES.md +7 -7
  12. data/config.ru +2 -1
  13. data/db/ddl_statements/head_pact_tags.rb +24 -1
  14. data/db/ddl_statements/latest_tagged_pact_consumer_version_orders.rb +11 -0
  15. data/db/ddl_statements/latest_tagged_pact_publications.rb +6 -0
  16. data/db/ddl_statements/latest_verification_ids_for_consumer_version_tags.rb +13 -0
  17. data/db/migrations/20210117_add_branch_to_version.rb +9 -0
  18. data/db/migrations/20210202_add_created_at_to_head_pact_tags.rb +14 -0
  19. data/db/migrations/20210205_add_pacticipant_id_to_tag.rb +17 -0
  20. data/db/migrations/20210206_add_index_to_tags_and_versions.rb +27 -0
  21. data/db/migrations/20210207_optimise_latest_verification_ids_for_consumer_version_tags.rb +13 -0
  22. data/db/migrations/20210208_optimise_latest_tagged_pact_cv_orders.rb +13 -0
  23. data/db/migrations/20210210_create_environments_table.rb +16 -0
  24. data/docker-compose-dev-postgres.yml +9 -1
  25. data/lib/pact_broker/api.rb +7 -2
  26. data/lib/pact_broker/api/contracts/dry_validation_predicates.rb +8 -0
  27. data/lib/pact_broker/api/contracts/environment_schema.rb +49 -0
  28. data/lib/pact_broker/api/decorators/base_decorator.rb +11 -0
  29. data/lib/pact_broker/api/decorators/dashboard_decorator.rb +5 -1
  30. data/lib/pact_broker/api/decorators/environment_decorator.rb +30 -0
  31. data/lib/pact_broker/api/decorators/environments_decorator.rb +21 -0
  32. data/lib/pact_broker/api/decorators/matrix_decorator.rb +3 -1
  33. data/lib/pact_broker/api/decorators/verifiable_pacts_query_decorator.rb +2 -0
  34. data/lib/pact_broker/api/decorators/version_decorator.rb +15 -2
  35. data/lib/pact_broker/api/pact_broker_urls.rb +8 -0
  36. data/lib/pact_broker/api/resources/default_base_resource.rb +18 -0
  37. data/lib/pact_broker/api/resources/environment.rb +76 -0
  38. data/lib/pact_broker/api/resources/environments.rb +75 -0
  39. data/lib/pact_broker/api/resources/index.rb +20 -0
  40. data/lib/pact_broker/api/resources/latest_version.rb +27 -0
  41. data/lib/pact_broker/api/resources/provider_pacts_for_verification.rb +1 -0
  42. data/lib/pact_broker/api/resources/version.rb +15 -9
  43. data/lib/pact_broker/app.rb +1 -1
  44. data/lib/pact_broker/certificates/certificate.rb +1 -1
  45. data/lib/pact_broker/config/setting.rb +1 -1
  46. data/lib/pact_broker/config/space_delimited_integer_list.rb +25 -0
  47. data/lib/pact_broker/configuration.rb +22 -1
  48. data/lib/pact_broker/db/data_migrations/helpers.rb +4 -0
  49. data/lib/pact_broker/db/data_migrations/set_extra_columns_for_tags.rb +29 -0
  50. data/lib/pact_broker/db/migrate_data.rb +1 -0
  51. data/lib/pact_broker/db/seed_example_data.rb +13 -13
  52. data/lib/pact_broker/deployments/environment.rb +15 -0
  53. data/lib/pact_broker/deployments/environment_service.rb +39 -0
  54. data/lib/pact_broker/doc/views/index/environment.markdown +37 -0
  55. data/lib/pact_broker/doc/views/index/environments.markdown +53 -0
  56. data/lib/pact_broker/doc/views/index/latest-pact-versions.markdown +1 -1
  57. data/lib/pact_broker/doc/views/index/pacticipant-version-tag.markdown +1 -0
  58. data/lib/pact_broker/doc/views/index/pacticipant-version.markdown +13 -0
  59. data/lib/pact_broker/domain/index_item.rb +18 -4
  60. data/lib/pact_broker/domain/pacticipant.rb +9 -5
  61. data/lib/pact_broker/domain/tag.rb +131 -71
  62. data/lib/pact_broker/domain/verification.rb +3 -2
  63. data/lib/pact_broker/domain/version.rb +58 -23
  64. data/lib/pact_broker/domain/webhook.rb +6 -3
  65. data/lib/pact_broker/index/service.rb +55 -49
  66. data/lib/pact_broker/locale/en.yml +3 -1
  67. data/lib/pact_broker/matrix/quick_row.rb +8 -0
  68. data/lib/pact_broker/metrics/service.rb +1 -1
  69. data/lib/pact_broker/pacts/eager_loaders.rb +52 -0
  70. data/lib/pact_broker/pacts/latest_pact_publication_id_for_consumer_version.rb +18 -13
  71. data/lib/pact_broker/pacts/lazy_loaders.rb +14 -0
  72. data/lib/pact_broker/pacts/pact_publication.rb +38 -84
  73. data/lib/pact_broker/pacts/pact_publication_dataset_module.rb +297 -0
  74. data/lib/pact_broker/pacts/pact_version.rb +1 -2
  75. data/lib/pact_broker/pacts/pacts_for_verification_repository.rb +286 -0
  76. data/lib/pact_broker/pacts/repository.rb +5 -240
  77. data/lib/pact_broker/pacts/selected_pact.rb +4 -0
  78. data/lib/pact_broker/pacts/selector.rb +56 -1
  79. data/lib/pact_broker/pacts/selectors.rb +16 -0
  80. data/lib/pact_broker/pacts/service.rb +2 -6
  81. data/lib/pact_broker/pacts/squash_pacts_for_verification.rb +1 -4
  82. data/lib/pact_broker/pacts/verifiable_pact.rb +23 -2
  83. data/lib/pact_broker/pacts/verifiable_pact_messages.rb +56 -16
  84. data/lib/pact_broker/repositories/helpers.rb +4 -0
  85. data/lib/pact_broker/services.rb +9 -0
  86. data/lib/pact_broker/tags/eager_loaders.rb +47 -0
  87. data/lib/pact_broker/tags/repository.rb +3 -1
  88. data/lib/pact_broker/tags/service.rb +0 -3
  89. data/lib/pact_broker/tags/tag_with_latest_flag.rb +1 -0
  90. data/lib/pact_broker/test/http_test_data_builder.rb +23 -7
  91. data/lib/pact_broker/test/test_data_builder.rb +50 -3
  92. data/lib/pact_broker/ui/view_models/index_item.rb +19 -2
  93. data/lib/pact_broker/ui/view_models/matrix_line.rb +38 -2
  94. data/lib/pact_broker/ui/views/index/show-with-tags.haml +14 -6
  95. data/lib/pact_broker/ui/views/matrix/show.haml +12 -2
  96. data/lib/pact_broker/verifications/latest_verification_id_for_pact_version_and_provider_version.rb +7 -5
  97. data/lib/pact_broker/version.rb +1 -1
  98. data/lib/pact_broker/versions/eager_loaders.rb +71 -0
  99. data/lib/pact_broker/versions/lazy_loaders.rb +13 -0
  100. data/lib/pact_broker/versions/repository.rb +22 -2
  101. data/lib/pact_broker/versions/service.rb +5 -1
  102. data/lib/pact_broker/webhooks/execution.rb +3 -2
  103. data/lib/pact_broker/webhooks/latest_triggered_webhook.rb +2 -0
  104. data/lib/pact_broker/webhooks/triggered_webhook.rb +11 -4
  105. data/lib/pact_broker/webhooks/webhook.rb +1 -1
  106. data/lib/pact_broker/webhooks/webhook_event.rb +1 -1
  107. data/lib/pact_broker/webhooks/webhook_execution_result.rb +6 -1
  108. data/lib/pact_broker/webhooks/webhook_request_logger.rb +7 -1
  109. data/lib/rack/pact_broker/set_base_url.rb +35 -5
  110. data/lib/sequel/plugins/upsert.rb +18 -4
  111. data/pact_broker.gemspec +1 -1
  112. data/public/javascripts/clipboard.js +8 -2
  113. data/public/stylesheets/index.css +26 -2
  114. data/public/stylesheets/matrix.css +0 -21
  115. data/regression/can_i_deploy_spec.rb +5 -4
  116. data/regression/index_spec.rb +26 -0
  117. data/regression/regression_helper.rb +29 -3
  118. data/regression/script/clear.sh +3 -0
  119. data/regression/script/run.sh +3 -0
  120. data/script/demonstrate-version-branches.rb +33 -0
  121. data/script/pry.rb +2 -2
  122. data/spec/features/create_environment_spec.rb +47 -0
  123. data/spec/features/create_tag_spec.rb +32 -0
  124. data/spec/features/create_version_spec.rb +70 -0
  125. data/spec/features/delete_environment_spec.rb +16 -0
  126. data/spec/features/end_deployment_spec.rb +29 -0
  127. data/spec/features/get_environment_spec.rb +19 -0
  128. data/spec/features/get_environments_spec.rb +20 -0
  129. data/spec/features/record_deployment_spec.rb +28 -0
  130. data/spec/features/update_environment_spec.rb +44 -0
  131. data/spec/fixtures/approvals/modifiable_resources.approved.json +6 -0
  132. data/spec/fixtures/dashboard.json +4 -2
  133. data/spec/lib/pact_broker/api/contracts/environment_schema_spec.rb +83 -0
  134. data/spec/lib/pact_broker/api/decorators/dashboard_decorator_spec.rb +4 -2
  135. data/spec/lib/pact_broker/api/decorators/matrix_decorator_spec.rb +11 -6
  136. data/spec/lib/pact_broker/api/decorators/verifiable_pacts_query_decorator_spec.rb +6 -0
  137. data/spec/lib/pact_broker/api/decorators/version_decorator_spec.rb +18 -0
  138. data/spec/lib/pact_broker/api/resources/default_base_resource_approval_spec.rb +1 -1
  139. data/spec/lib/pact_broker/api/resources/provider_pacts_for_verification_spec.rb +4 -0
  140. data/spec/lib/pact_broker/api/resources/webhook_execution_result_spec.rb +56 -0
  141. data/spec/lib/pact_broker/config/space_delimited_integer_list_spec.rb +47 -0
  142. data/spec/lib/pact_broker/configuration_spec.rb +12 -0
  143. data/spec/lib/pact_broker/domain/tag_spec.rb +101 -27
  144. data/spec/lib/pact_broker/domain/version_spec.rb +103 -15
  145. data/spec/lib/pact_broker/domain/webhook_spec.rb +1 -1
  146. data/spec/lib/pact_broker/index/service_spec.rb +89 -15
  147. data/spec/lib/pact_broker/pacts/pact_publication_dataset_module_spec.rb +400 -0
  148. data/spec/lib/pact_broker/pacts/pact_publication_spec.rb +434 -14
  149. data/spec/lib/pact_broker/pacts/repository_find_for_verification_fallback_spec.rb +1 -1
  150. data/spec/lib/pact_broker/pacts/repository_find_for_verification_spec.rb +1 -1
  151. data/spec/lib/pact_broker/pacts/repository_find_wip_pact_versions_for_provider_branch_spec.rb +224 -0
  152. data/spec/lib/pact_broker/pacts/repository_find_wip_pact_versions_for_provider_spec.rb +20 -7
  153. data/spec/lib/pact_broker/pacts/selector_spec.rb +3 -2
  154. data/spec/lib/pact_broker/pacts/service_find_for_verification_spec.rb +2 -3
  155. data/spec/lib/pact_broker/pacts/service_spec.rb +2 -2
  156. data/spec/lib/pact_broker/pacts/verifiable_pact_messages_spec.rb +57 -10
  157. data/spec/lib/pact_broker/tags/repository_spec.rb +2 -0
  158. data/spec/lib/pact_broker/versions/repository_spec.rb +54 -0
  159. data/spec/lib/pact_broker/webhooks/webhook_request_logger_spec.rb +8 -0
  160. data/spec/lib/rack/pact_broker/set_base_url_spec.rb +86 -0
  161. data/spec/lib/sequel/plugins/upsert_spec.rb +31 -3
  162. data/spec/migrations/change_migration_strategy_spec.rb +3 -3
  163. data/spec/service_consumers/hal_relation_proxy_app.rb +3 -1
  164. data/spec/service_consumers/provider_states_for_pact_broker_client.rb +16 -0
  165. data/spec/spec_helper.rb +17 -5
  166. data/spec/support/approvals.rb +24 -0
  167. data/spec/support/shared_examples_for_responses.rb +11 -0
  168. data/tasks/database.rb +1 -1
  169. data/tasks/db.rake +1 -0
  170. data/tasks/rspec.rake +1 -1
  171. data/vendor/hal-browser/styles.css +6 -0
  172. metadata +70 -11
@@ -0,0 +1,75 @@
1
+ require 'pact_broker/api/resources/base_resource'
2
+ require 'pact_broker/api/resources/environment'
3
+ require 'pact_broker/api/contracts/environment_schema'
4
+
5
+ module PactBroker
6
+ module Api
7
+ module Resources
8
+ class Environments < BaseResource
9
+ def content_types_provided
10
+ [["application/hal+json", :to_json]]
11
+ end
12
+
13
+ def content_types_accepted
14
+ [["application/json", :from_json]]
15
+ end
16
+
17
+ def allowed_methods
18
+ ["GET", "POST", "OPTIONS"]
19
+ end
20
+
21
+ def resource_exists?
22
+ true
23
+ end
24
+
25
+ def post_is_create?
26
+ true
27
+ end
28
+
29
+ def malformed_request?
30
+ if request.post?
31
+ invalid_json? || validation_errors_for_schema?(schema, params.merge(uuid: uuid))
32
+ else
33
+ false
34
+ end
35
+ end
36
+
37
+ def create_path
38
+ environment_url(OpenStruct.new(uuid: uuid), base_url)
39
+ end
40
+
41
+ def from_json
42
+ response.body = decorator_class(:environment_decorator).new(create_environment).to_json(decorator_options)
43
+ end
44
+
45
+ def policy_name
46
+ :'deployments::environment'
47
+ end
48
+
49
+ def to_json
50
+ decorator_class(:environments_decorator).new(environments).to_json(decorator_options)
51
+ end
52
+
53
+ def parsed_environment
54
+ @parsed_environment ||= decorator_class(:environment_decorator).new(PactBroker::Deployments::Environment.new).from_json(request_body)
55
+ end
56
+
57
+ def create_environment
58
+ environment_service.create(uuid, parsed_environment)
59
+ end
60
+
61
+ def uuid
62
+ @uuid ||= environment_service.next_uuid
63
+ end
64
+
65
+ def environments
66
+ @environments ||= environment_service.find_all
67
+ end
68
+
69
+ def schema
70
+ PactBroker::Api::Contracts::EnvironmentSchema
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -110,6 +110,12 @@ module PactBroker
110
110
  title: "Get, create or delete a tag for a pacticipant version",
111
111
  templated: true
112
112
  },
113
+ 'pb:pacticipant-version' =>
114
+ {
115
+ href: base_url + '/pacticipants/{pacticipant}/versions/{version}',
116
+ title: "Get, create or delete a pacticipant version",
117
+ templated: true
118
+ },
113
119
  'pb:metrics' =>
114
120
  {
115
121
  href: base_url + '/metrics',
@@ -144,6 +150,20 @@ module PactBroker
144
150
  }]
145
151
  }
146
152
 
153
+ if PactBroker.feature_enabled?(:environments)
154
+ links_hash['pb:environments'] = {
155
+ title: "Environments",
156
+ href: environments_url(base_url),
157
+ templated: false
158
+ }
159
+
160
+ links_hash['pb:environment'] = {
161
+ title: "Environment",
162
+ href: environments_url(base_url) + "/{uuid}",
163
+ templated: true
164
+ }
165
+ end
166
+
147
167
  if PactBroker.feature_enabled?('disable_pacts_for_verification', true)
148
168
  links_hash.delete('pb:provider-pacts-for-verification')
149
169
  links_hash.delete('beta:provider-pacts-for-verification')
@@ -0,0 +1,27 @@
1
+ require 'pact_broker/api/resources/version'
2
+
3
+ module PactBroker
4
+ module Api
5
+ module Resources
6
+ class LatestVersion < Version
7
+ def content_types_accepted
8
+ []
9
+ end
10
+
11
+ def allowed_methods
12
+ ["GET", "OPTIONS"]
13
+ end
14
+
15
+ private
16
+
17
+ def version
18
+ if identifier_from_path[:tag]
19
+ @version ||= version_service.find_by_pacticipant_name_and_latest_tag(identifier_from_path[:pacticipant_name], identifier_from_path[:tag])
20
+ else
21
+ @version ||= version_service.find_latest_by_pacticpant_name(identifier_from_path)
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -38,6 +38,7 @@ module PactBroker
38
38
  def pacts
39
39
  @pacts ||= pact_service.find_for_verification(
40
40
  provider_name,
41
+ parsed_query_params.provider_version_branch,
41
42
  parsed_query_params.provider_version_tags,
42
43
  parsed_query_params.consumer_version_selectors,
43
44
  {
@@ -10,20 +10,32 @@ module PactBroker
10
10
  [["application/hal+json", :to_json]]
11
11
  end
12
12
 
13
+ def content_types_accepted
14
+ [["application/json", :from_json]]
15
+ end
16
+
13
17
  def allowed_methods
14
- ["GET", "DELETE", "OPTIONS"]
18
+ ["GET", "PUT", "DELETE", "OPTIONS"]
15
19
  end
16
20
 
17
21
  def resource_exists?
18
22
  !!version
19
23
  end
20
24
 
25
+ def from_json
26
+ response_code = version ? 200 : 201
27
+ parsed_version = Decorators::VersionDecorator.new(OpenStruct.new).from_json(request_body)
28
+ @version = version_service.create_or_overwrite(pacticipant_name, pacticipant_version_number, parsed_version)
29
+ response.body = to_json
30
+ response_code
31
+ end
32
+
21
33
  def to_json
22
34
  decorator_class(:version_decorator).new(version).to_json(decorator_options)
23
35
  end
24
36
 
25
37
  def delete_resource
26
- version_service.delete version
38
+ version_service.delete(version)
27
39
  true
28
40
  end
29
41
 
@@ -34,13 +46,7 @@ module PactBroker
34
46
  private
35
47
 
36
48
  def version
37
- if identifier_from_path[:tag]
38
- @version ||= version_service.find_by_pacticipant_name_and_latest_tag(identifier_from_path[:pacticipant_name], identifier_from_path[:tag])
39
- elsif identifier_from_path[:pacticipant_version_number]
40
- @version ||= version_service.find_by_pacticipant_name_and_number(identifier_from_path)
41
- else
42
- @version ||= version_service.find_latest_by_pacticpant_name(identifier_from_path)
43
- end
49
+ @version ||= version_service.find_by_pacticipant_name_and_number(identifier_from_path)
44
50
  end
45
51
  end
46
52
  end
@@ -191,7 +191,7 @@ module PactBroker
191
191
  @app_builder.use Rack::Static, :urls => ["/favicon.ico"], :root => PactBroker.project_root.join("public/images"), header_rules: [[:all, {'Content-Type' => 'image/x-icon'}]]
192
192
  @app_builder.use Rack::PactBroker::ConvertFileExtensionToAcceptHeader
193
193
  # Rack::PactBroker::SetBaseUrl needs to be before the Rack::PactBroker::HalBrowserRedirect
194
- @app_builder.use Rack::PactBroker::SetBaseUrl, configuration.base_url
194
+ @app_builder.use Rack::PactBroker::SetBaseUrl, configuration.base_urls
195
195
 
196
196
  if configuration.use_hal_browser
197
197
  logger.info "Mounting HAL browser"
@@ -9,7 +9,7 @@ end
9
9
 
10
10
  # Table: certificates
11
11
  # Columns:
12
- # id | integer | PRIMARY KEY DEFAULT nextval('certificates_id_seq'::regclass)
12
+ # id | integer | PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY
13
13
  # uuid | text | NOT NULL
14
14
  # description | text |
15
15
  # content | text | NOT NULL
@@ -73,7 +73,7 @@ end
73
73
 
74
74
  # Table: config
75
75
  # Columns:
76
- # id | integer | PRIMARY KEY DEFAULT nextval('config_id_seq'::regclass)
76
+ # id | integer | PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY
77
77
  # name | text | NOT NULL
78
78
  # type | text | NOT NULL
79
79
  # value | text |
@@ -0,0 +1,25 @@
1
+ module PactBroker
2
+ module Config
3
+ class SpaceDelimitedIntegerList < Array
4
+ def initialize list
5
+ super(list)
6
+ end
7
+
8
+ def self.integer?(string)
9
+ (Integer(string) rescue nil) != nil
10
+ end
11
+
12
+ def self.parse(string)
13
+ array = (string || '')
14
+ .split(' ')
15
+ .select { |word| integer?(word) }
16
+ .collect(&:to_i)
17
+ SpaceDelimitedIntegerList.new(array)
18
+ end
19
+
20
+ def to_s
21
+ collect(&:to_s).join(' ')
22
+ end
23
+ end
24
+ end
25
+ end
@@ -1,6 +1,7 @@
1
1
  require 'pact_broker/version'
2
2
  require 'pact_broker/error'
3
3
  require 'pact_broker/config/space_delimited_string_list'
4
+ require 'pact_broker/config/space_delimited_integer_list'
4
5
  require 'semantic_logger'
5
6
 
6
7
  module PactBroker
@@ -30,6 +31,7 @@ module PactBroker
30
31
  :webhook_http_method_whitelist,
31
32
  :webhook_scheme_whitelist,
32
33
  :webhook_host_whitelist,
34
+ :webhook_http_code_success,
33
35
  :base_equality_only_on_content_that_affects_verification_results,
34
36
  :seed_example_data,
35
37
  :badge_provider_mode,
@@ -49,7 +51,7 @@ module PactBroker
49
51
  attr_accessor :check_for_potential_duplicate_pacticipant_names
50
52
  attr_accessor :webhook_retry_schedule
51
53
  attr_accessor :user_agent
52
- attr_reader :webhook_http_method_whitelist, :webhook_scheme_whitelist, :webhook_host_whitelist
54
+ attr_reader :webhook_http_method_whitelist, :webhook_scheme_whitelist, :webhook_host_whitelist, :webhook_http_code_success
53
55
  attr_accessor :semver_formats
54
56
  attr_accessor :enable_public_badge_access, :shields_io_base_url, :badge_provider_mode
55
57
  attr_accessor :disable_ssl_verification
@@ -105,6 +107,7 @@ module PactBroker
105
107
  config.check_for_potential_duplicate_pacticipant_names = true
106
108
  config.disable_ssl_verification = false
107
109
  config.webhook_http_method_whitelist = ['POST']
110
+ config.webhook_http_code_success = [200, 201, 202, 203, 204, 205, 206]
108
111
  config.webhook_scheme_whitelist = ['https']
109
112
  config.webhook_host_whitelist = []
110
113
  # TODO get rid of unsafe-inline
@@ -240,6 +243,10 @@ module PactBroker
240
243
  @webhook_http_method_whitelist = parse_space_delimited_string_list_property('webhook_http_method_whitelist', webhook_http_method_whitelist)
241
244
  end
242
245
 
246
+ def webhook_http_code_success= webhook_http_code_success
247
+ @webhook_http_code_success = parse_space_delimited_integer_list_property('webhook_http_code_success', webhook_http_code_success)
248
+ end
249
+
243
250
  def webhook_scheme_whitelist= webhook_scheme_whitelist
244
251
  @webhook_scheme_whitelist = parse_space_delimited_string_list_property('webhook_scheme_whitelist', webhook_scheme_whitelist)
245
252
  end
@@ -248,6 +255,10 @@ module PactBroker
248
255
  @webhook_host_whitelist = parse_space_delimited_string_list_property('webhook_host_whitelist', webhook_host_whitelist)
249
256
  end
250
257
 
258
+ def base_urls
259
+ base_url ? base_url.split(" ") : []
260
+ end
261
+
251
262
  def warning_error_classes
252
263
  warning_error_class_names.collect do | class_name |
253
264
  begin
@@ -269,5 +280,15 @@ module PactBroker
269
280
  raise ConfigurationError.new("Pact Broker configuration property `#{property_name}` must be a space delimited String or an Array")
270
281
  end
271
282
  end
283
+
284
+ def parse_space_delimited_integer_list_property property_name, property_value
285
+ case property_value
286
+ when String then Config::SpaceDelimitedIntegerList.parse(property_value)
287
+ when Array then Config::SpaceDelimitedIntegerList.new(property_value)
288
+ else
289
+ raise ConfigurationError.new("Pact Broker configuration property `#{property_name}` must be a space delimited String or an Array with Integer values")
290
+ end
291
+ end
292
+
272
293
  end
273
294
  end
@@ -5,6 +5,10 @@ module PactBroker
5
5
  def column_exists?(connection, table, column)
6
6
  connection.table_exists?(table) && connection.schema(table).find{|col| col.first == column }
7
7
  end
8
+
9
+ def columns_exist?(connection, table, columns)
10
+ columns.all?{ | column | column_exists?(connection, table, column) }
11
+ end
8
12
  end
9
13
  end
10
14
  end
@@ -0,0 +1,29 @@
1
+ require 'pact_broker/db/data_migrations/helpers'
2
+
3
+ module PactBroker
4
+ module DB
5
+ module DataMigrations
6
+ class SetExtraColumnsForTags
7
+ extend Helpers
8
+
9
+ def self.call(connection)
10
+ if columns_exist?(connection, :tags, [:version_id, :pacticipant_id]) &&
11
+ columns_exist?(connection, :versions, [:id, :pacticipant_id])
12
+ connection[:tags].where(pacticipant_id: nil).update(
13
+ pacticipant_id: connection[:versions].select(:pacticipant_id)
14
+ .where(Sequel[:versions][:id] => Sequel[:tags][:version_id])
15
+ )
16
+ end
17
+
18
+ if columns_exist?(connection, :tags, [:version_id, :version_order]) &&
19
+ columns_exist?(connection, :versions, [:id, :order])
20
+ connection[:tags].where(version_order: nil).update(
21
+ version_order: connection[:versions].select(:order)
22
+ .where(Sequel[:versions][:id] => Sequel[:tags][:version_id])
23
+ )
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -21,6 +21,7 @@ module PactBroker
21
21
  DataMigrations::DeleteDeprecatedWebhookExecutions.call(database_connection)
22
22
  DataMigrations::SetCreatedAtForLatestPactPublications.call(database_connection)
23
23
  DataMigrations::SetCreatedAtForLatestVerifications.call(database_connection)
24
+ DataMigrations::SetExtraColumnsForTags.call(database_connection)
24
25
  end
25
26
  end
26
27
  end
@@ -16,25 +16,25 @@ module PactBroker
16
16
  PactBroker::Test::TestDataBuilder.new
17
17
  .create_consumer(consumer_name, created_at: days_ago(16))
18
18
  .create_provider(provider_name, created_at: days_ago(16))
19
- .create_consumer_version("e15da45d3943bf10793a6d04cfb9f5dabe430fe2", created_at: days_ago(16))
19
+ .create_consumer_version("e15da45d3943bf10793a6d04cfb9f5dabe430fe2", branch: "main", created_at: days_ago(16))
20
20
  .create_consumer_version_tag("prod", created_at: days_ago(16))
21
- .create_consumer_version_tag("master", created_at: days_ago(16))
21
+ .create_consumer_version_tag("main", created_at: days_ago(16))
22
22
  .create_pact(json_content: pact_1, created_at: days_ago(16))
23
- .create_verification(provider_version: "1315e0b1924cb6f42751f977789be3559373033a", execution_date: days_ago(15))
24
- .create_provider_version_tag("master", created_at: days_ago(14))
23
+ .create_verification(provider_version: "1315e0b1924cb6f42751f977789be3559373033a", branch: "main", execution_date: days_ago(15))
24
+ .create_provider_version_tag("main", created_at: days_ago(14))
25
25
  .create_provider_version_tag("prod", created_at: days_ago(14))
26
- .create_verification(provider_version: "480e5aeb30467856ca995d0024d2c1800b0719e5", success: false, number: 2, execution_date: days_ago(14))
27
- .create_provider_version_tag("master", created_at: days_ago(14))
28
- .create_consumer_version("725c6ccb7cf7efc51b4394f9828585eea9c379d9", created_at: days_ago(7))
26
+ .create_verification(provider_version: "480e5aeb30467856ca995d0024d2c1800b0719e5", branch: "main", success: false, number: 2, execution_date: days_ago(14))
27
+ .create_provider_version_tag("main", created_at: days_ago(14))
28
+ .create_consumer_version("725c6ccb7cf7efc51b4394f9828585eea9c379d9", branch: "feat/new-thing", created_at: days_ago(7))
29
29
  .create_consumer_version_tag("feat-new-thing", created_at: days_ago(7))
30
30
  .create_pact(json_content: pact_2, created_at: days_ago(7))
31
- .create_consumer_version("7bd4d9173522826dc3e8704fd62dde0424f4c827", created_at: days_ago(1))
32
- .create_consumer_version_tag("master", created_at: days_ago(1))
31
+ .create_consumer_version("7bd4d9173522826dc3e8704fd62dde0424f4c827", branch: "main", created_at: days_ago(1))
32
+ .create_consumer_version_tag("main", created_at: days_ago(1))
33
33
  .create_pact(json_content: pact_3, created_at: days_ago(1))
34
- .create_verification(provider_version: "4fdf20082263d4c5038355a3b734be1c0054d1e1", execution_date: days_ago(1))
35
- .create_provider_version_tag("master", created_at: days_ago(1))
36
- .create_consumer_version("5556b8149bf8bac76bc30f50a8a2dd4c22c85f30", created_at: days_ago(0.5))
37
- .create_consumer_version_tag("master", created_at: days_ago(0.5))
34
+ .create_verification(provider_version: "4fdf20082263d4c5038355a3b734be1c0054d1e1", branch: "main", execution_date: days_ago(1))
35
+ .create_provider_version_tag("main", created_at: days_ago(1))
36
+ .create_consumer_version("5556b8149bf8bac76bc30f50a8a2dd4c22c85f30", branch: "main", created_at: days_ago(0.5))
37
+ .create_consumer_version_tag("main", created_at: days_ago(0.5))
38
38
  .republish_same_pact(created_at: days_ago(0.5))
39
39
  end
40
40
 
@@ -0,0 +1,15 @@
1
+ require 'sequel'
2
+ require 'sequel/plugins/serialization'
3
+
4
+
5
+ module PactBroker
6
+ module Deployments
7
+ class Environment < Sequel::Model
8
+ OPEN_STRUCT_TO_JSON = lambda { |thing| Sequel.object_to_json(thing.collect(&:to_h)) }
9
+ JSON_TO_OPEN_STRUCT = lambda { | json | Sequel.parse_json(json).collect{ | hash| OpenStruct.new(hash) } }
10
+ plugin :upsert, identifying_columns: [:uuid]
11
+ plugin :serialization
12
+ serialize_attributes [OPEN_STRUCT_TO_JSON, JSON_TO_OPEN_STRUCT], :contacts
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,39 @@
1
+ require 'pact_broker/deployments/environment'
2
+ require 'securerandom'
3
+
4
+ module PactBroker
5
+ module Deployments
6
+ module EnvironmentService
7
+
8
+ def self.next_uuid
9
+ SecureRandom.uuid
10
+ end
11
+
12
+ def self.create(uuid, environment)
13
+ environment.uuid = uuid
14
+ environment.save
15
+ end
16
+
17
+ def self.update(uuid, environment)
18
+ environment.uuid = uuid
19
+ environment.upsert
20
+ end
21
+
22
+ def self.find_all
23
+ PactBroker::Deployments::Environment.order(Sequel.function(:lower, :display_name)).all
24
+ end
25
+
26
+ def self.find(uuid)
27
+ PactBroker::Deployments::Environment.where(uuid: uuid).single_record
28
+ end
29
+
30
+ def self.find_by_name(name)
31
+ PactBroker::Deployments::Environment.where(name: name).single_record
32
+ end
33
+
34
+ def self.delete(uuid)
35
+ PactBroker::Deployments::Environment.where(uuid: uuid).delete
36
+ end
37
+ end
38
+ end
39
+ end