pact_broker 2.34.0 → 2.35.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (118) hide show
  1. checksums.yaml +4 -4
  2. data/.dockerignore +2 -0
  3. data/.github/FUNDING.yml +4 -0
  4. data/.travis.yml +1 -1
  5. data/CHANGELOG.md +34 -0
  6. data/DEVELOPER_DOCUMENTATION.md +24 -1
  7. data/DEVELOPER_SETUP.md +40 -20
  8. data/Dockerfile +22 -0
  9. data/db/migrations/000028_create_all_pact_publications.rb +0 -1
  10. data/db/migrations/20180311_optimise_head_matrix.rb +0 -1
  11. data/lib/pact/doc/doc_file.rb +0 -1
  12. data/lib/pact_broker/api/contracts/webhook_contract.rb +1 -1
  13. data/lib/pact_broker/api/decorators/decorator_context.rb +5 -5
  14. data/lib/pact_broker/api/decorators/pact_decorator.rb +0 -1
  15. data/lib/pact_broker/api/decorators/pact_pacticipant_decorator.rb +0 -1
  16. data/lib/pact_broker/api/decorators/tag_decorator.rb +0 -1
  17. data/lib/pact_broker/api/decorators/webhook_decorator.rb +0 -1
  18. data/lib/pact_broker/api/decorators/webhook_execution_result_decorator.rb +8 -5
  19. data/lib/pact_broker/api/decorators/webhook_request_template_decorator.rb +1 -4
  20. data/lib/pact_broker/api/decorators/webhooks_decorator.rb +1 -2
  21. data/lib/pact_broker/api/resources/base_resource.rb +0 -1
  22. data/lib/pact_broker/api/resources/error_handler.rb +14 -7
  23. data/lib/pact_broker/api/resources/pact.rb +4 -9
  24. data/lib/pact_broker/api/resources/pact_webhooks.rb +0 -1
  25. data/lib/pact_broker/api/resources/verifications.rb +4 -8
  26. data/lib/pact_broker/api/resources/webhook.rb +4 -8
  27. data/lib/pact_broker/api/resources/webhook_execution.rb +36 -17
  28. data/lib/pact_broker/api/resources/webhook_execution_methods.rb +13 -0
  29. data/lib/pact_broker/api/resources/webhook_resource_methods.rb +8 -15
  30. data/lib/pact_broker/api/resources/webhooks.rb +3 -12
  31. data/lib/pact_broker/api.rb +1 -1
  32. data/lib/pact_broker/app.rb +2 -0
  33. data/lib/pact_broker/domain/webhook.rb +29 -18
  34. data/lib/pact_broker/hash_refinements.rb +13 -0
  35. data/lib/pact_broker/locale/en.yml +16 -0
  36. data/lib/pact_broker/logging.rb +1 -1
  37. data/lib/pact_broker/pacts/diff.rb +0 -1
  38. data/lib/pact_broker/pacts/pact_version.rb +13 -7
  39. data/lib/pact_broker/pacts/repository.rb +4 -6
  40. data/lib/pact_broker/pacts/service.rb +3 -4
  41. data/lib/pact_broker/repositories/helpers.rb +1 -1
  42. data/lib/pact_broker/string_refinements.rb +13 -0
  43. data/lib/pact_broker/tags/repository.rb +0 -1
  44. data/lib/pact_broker/ui/views/index/_css_and_js.haml +1 -0
  45. data/lib/pact_broker/ui/views/index/show-with-tags.haml +8 -2
  46. data/lib/pact_broker/ui/views/matrix/show.haml +12 -2
  47. data/lib/pact_broker/verifications/repository.rb +0 -1
  48. data/lib/pact_broker/verifications/service.rb +7 -5
  49. data/lib/pact_broker/version.rb +1 -1
  50. data/lib/pact_broker/versions/parse_semantic_version.rb +0 -1
  51. data/lib/pact_broker/webhooks/execution.rb +0 -1
  52. data/lib/pact_broker/webhooks/execution_configuration.rb +45 -0
  53. data/lib/pact_broker/webhooks/job.rb +5 -8
  54. data/lib/pact_broker/webhooks/pact_and_verification_parameters.rb +39 -12
  55. data/lib/pact_broker/webhooks/redact_logs.rb +21 -4
  56. data/lib/pact_broker/webhooks/render.rb +11 -2
  57. data/lib/pact_broker/webhooks/repository.rb +11 -5
  58. data/lib/pact_broker/webhooks/service.rb +21 -27
  59. data/lib/pact_broker/webhooks/triggered_webhook.rb +0 -1
  60. data/lib/pact_broker/webhooks/webhook_request_logger.rb +13 -0
  61. data/lib/pact_broker/webhooks/webhook_request_template.rb +32 -18
  62. data/lib/rack/pact_broker/add_vary_header.rb +39 -0
  63. data/lib/rack/pact_broker/convert_file_extension_to_accept_header.rb +2 -0
  64. data/lib/webmachine/rack_adapter_monkey_patch.rb +0 -1
  65. data/public/javascripts/clipboard.js +73 -0
  66. data/public/javascripts/matrix.js +0 -2
  67. data/public/stylesheets/index.css +19 -0
  68. data/script/prod/clean-up.sql +11 -0
  69. data/script/query.rb +0 -1
  70. data/script/seed-matrix.rb +0 -1
  71. data/script/seed.rb +0 -1
  72. data/spec/features/delete_version_spec.rb +0 -1
  73. data/spec/features/execute_unsaved_webhook_spec.rb +56 -0
  74. data/spec/features/execute_webhook_spec.rb +2 -5
  75. data/spec/features/get_version_spec.rb +0 -1
  76. data/spec/lib/pact_broker/api/contracts/put_pact_params_contract_spec.rb +0 -1
  77. data/spec/lib/pact_broker/api/contracts/verification_contract_spec.rb +0 -1
  78. data/spec/lib/pact_broker/api/decorators/relationships_csv_decorator_spec.rb +0 -2
  79. data/spec/lib/pact_broker/api/decorators/verification_decorator_spec.rb +0 -1
  80. data/spec/lib/pact_broker/api/decorators/webhook_execution_result_decorator_spec.rb +26 -9
  81. data/spec/lib/pact_broker/api/decorators/webhook_request_template_decorator_spec.rb +3 -1
  82. data/spec/lib/pact_broker/api/decorators/webhooks_decorator_spec.rb +3 -2
  83. data/spec/lib/pact_broker/api/resources/badge_spec.rb +0 -2
  84. data/spec/lib/pact_broker/api/resources/dashboard_spec.rb +0 -1
  85. data/spec/lib/pact_broker/api/resources/error_handler_spec.rb +3 -0
  86. data/spec/lib/pact_broker/api/resources/group_spec.rb +0 -1
  87. data/spec/lib/pact_broker/api/resources/pact_spec.rb +0 -2
  88. data/spec/lib/pact_broker/api/resources/pacticipant_spec.rb +0 -1
  89. data/spec/lib/pact_broker/api/resources/tag_spec.rb +0 -2
  90. data/spec/lib/pact_broker/api/resources/verifications_spec.rb +9 -7
  91. data/spec/lib/pact_broker/api/resources/webhook_execution_spec.rb +13 -15
  92. data/spec/lib/pact_broker/api/resources/webhooks_spec.rb +0 -1
  93. data/spec/lib/pact_broker/certificates/service_spec.rb +11 -5
  94. data/spec/lib/pact_broker/domain/group_spec.rb +0 -1
  95. data/spec/lib/pact_broker/domain/webhook_spec.rb +11 -4
  96. data/spec/lib/pact_broker/feature_toggle_spec.rb +0 -1
  97. data/spec/lib/pact_broker/groups/service_spec.rb +0 -1
  98. data/spec/lib/pact_broker/hash_refinements_spec.rb +15 -0
  99. data/spec/lib/pact_broker/matrix/repository_spec.rb +0 -2
  100. data/spec/lib/pact_broker/pacticipants/find_potential_duplicate_pacticipant_names_spec.rb +0 -1
  101. data/spec/lib/pact_broker/pacts/pact_version_spec.rb +16 -0
  102. data/spec/lib/pact_broker/pacts/repository_spec.rb +11 -0
  103. data/spec/lib/pact_broker/pacts/service_spec.rb +12 -5
  104. data/spec/lib/pact_broker/relationships/groupify_spec.rb +0 -2
  105. data/spec/lib/pact_broker/tags/repository_spec.rb +0 -1
  106. data/spec/lib/pact_broker/verifications/service_spec.rb +10 -3
  107. data/spec/lib/pact_broker/versions/repository_spec.rb +0 -1
  108. data/spec/lib/pact_broker/webhooks/execution_configuration_spec.rb +18 -0
  109. data/spec/lib/pact_broker/webhooks/job_spec.rb +21 -24
  110. data/spec/lib/pact_broker/webhooks/redact_logs_spec.rb +16 -5
  111. data/spec/lib/pact_broker/webhooks/repository_spec.rb +16 -1
  112. data/spec/lib/pact_broker/webhooks/service_spec.rb +23 -64
  113. data/spec/lib/pact_broker/webhooks/webhook_request_template_spec.rb +108 -24
  114. data/spec/migrations/23_pact_versions_spec.rb +3 -1
  115. data/spec/spec_helper.rb +4 -2
  116. data/spec/support/database_cleaner.rb +0 -1
  117. metadata +19 -5
  118. data/spec/support/jobs.rb +0 -12
@@ -1,24 +1,17 @@
1
1
  module PactBroker
2
2
  module Api
3
-
4
3
  module Resources
5
-
6
4
  module WebhookResourceMethods
7
-
8
- def malformed_webhook_request? webhook
9
- begin
10
- if (errors = webhook.validate).any?
11
- set_json_validation_error_messages errors
12
- return true
13
- end
14
- rescue
15
- set_json_error_message 'Invalid JSON'
16
- return true
5
+ def webhook_validation_errors? webhook
6
+ errors = webhook_service.errors(webhook)
7
+ if !errors.empty?
8
+ set_json_validation_error_messages(errors.messages)
9
+ true
10
+ else
11
+ false
17
12
  end
18
- false
19
13
  end
20
14
  end
21
-
22
15
  end
23
16
  end
24
- end
17
+ end
@@ -2,11 +2,13 @@ require 'pact_broker/api/resources/base_resource'
2
2
  require 'pact_broker/api/decorators/webhook_decorator'
3
3
  require 'pact_broker/api/decorators/webhooks_decorator'
4
4
  require 'pact_broker/api/contracts/webhook_contract'
5
+ require 'pact_broker/api/resources/webhook_resource_methods'
5
6
 
6
7
  module PactBroker
7
8
  module Api
8
9
  module Resources
9
10
  class Webhooks < BaseResource
11
+ include WebhookResourceMethods
10
12
 
11
13
  def allowed_methods
12
14
  ["POST", "GET", "OPTIONS"]
@@ -27,22 +29,11 @@ module PactBroker
27
29
 
28
30
  def malformed_request?
29
31
  if request.post?
30
- return invalid_json? || validation_errors?(webhook)
32
+ return invalid_json? || webhook_validation_errors?(webhook)
31
33
  end
32
34
  false
33
35
  end
34
36
 
35
- def validation_errors? webhook
36
- errors = webhook_service.errors(webhook)
37
-
38
- unless errors.empty?
39
- response.headers['Content-Type'] = 'application/hal+json;charset=utf-8'
40
- response.body = { errors: errors.messages }.to_json
41
- end
42
-
43
- !errors.empty?
44
- end
45
-
46
37
  def create_path
47
38
  webhook_url next_uuid, base_url
48
39
  end
@@ -71,12 +71,12 @@ module PactBroker
71
71
  add ['pacts', 'provider', :provider_name, 'consumer', :consumer_name, 'webhooks', 'status'], Api::Resources::PactWebhooksStatus, {resource_name: "pact_webhooks_status"}
72
72
  add ['pacts', 'provider', :provider_name, 'consumer', :consumer_name, 'version', :consumer_version_number, 'triggered-webhooks'], Api::Resources::PactTriggeredWebhooks, {resource_name: "pact_triggered_webhooks"}
73
73
 
74
+ add ['webhooks', 'execute' ], Api::Resources::WebhookExecution, {resource_name: "execute_unsaved_webhook"}
74
75
  add ['webhooks', :uuid ], Api::Resources::Webhook, {resource_name: "webhook"}
75
76
  add ['webhooks', :uuid, 'trigger', :trigger_uuid, 'logs' ], Api::Resources::TriggeredWebhookLogs, {resource_name: "triggered_webhook_logs"}
76
77
  add ['webhooks', :uuid, 'execute' ], Api::Resources::WebhookExecution, {resource_name: "execute_webhook"}
77
78
  add ['webhooks'], Api::Resources::AllWebhooks, {resource_name: "webhooks"}
78
79
 
79
-
80
80
  add ['relationships'], Api::Resources::Relationships, {resource_name: "relationships"}
81
81
  add ['groups', :pacticipant_name], Api::Resources::Group, {resource_name: "group"}
82
82
 
@@ -15,6 +15,7 @@ require 'rack/pact_broker/configurable_make_it_later'
15
15
  require 'rack/pact_broker/no_auth'
16
16
  require 'rack/pact_broker/convert_404_to_hal'
17
17
  require 'rack/pact_broker/reset_thread_data'
18
+ require 'rack/pact_broker/add_vary_header'
18
19
  require 'sucker_punch'
19
20
 
20
21
  module PactBroker
@@ -151,6 +152,7 @@ module PactBroker
151
152
  @app_builder.use Rack::PactBroker::ResetThreadData
152
153
  @app_builder.use Rack::PactBroker::StoreBaseURL
153
154
  @app_builder.use Rack::PactBroker::AddPactBrokerVersionHeader
155
+ @app_builder.use Rack::PactBroker::AddVaryHeader
154
156
  @app_builder.use Rack::Static, :urls => ["/stylesheets", "/css", "/fonts", "/js", "/javascripts", "/images"], :root => PactBroker.project_root.join("public")
155
157
  @app_builder.use Rack::Static, :urls => ["/favicon.ico"], :root => PactBroker.project_root.join("public/images"), header_rules: [[:all, {'Content-Type' => 'image/x-icon'}]]
156
158
  @app_builder.use Rack::PactBroker::ConvertFileExtensionToAcceptHeader
@@ -54,14 +54,8 @@ module PactBroker
54
54
 
55
55
  def execute pact, verification, options
56
56
  logger.info "Executing #{self}"
57
- webhook_request = request.build(pact: pact, verification: verification, webhook_context: options.fetch(:webhook_context))
58
- http_response = nil
59
- error = nil
60
- begin
61
- http_response = webhook_request.execute
62
- rescue StandardError => e
63
- error = e
64
- end
57
+ webhook_request = request.build(template_parameters(pact, verification, options))
58
+ http_response, error = execute_request(webhook_request)
65
59
 
66
60
  PactBroker::Webhooks::WebhookExecutionResult.new(
67
61
  webhook_request.http_request,
@@ -71,16 +65,6 @@ module PactBroker
71
65
  )
72
66
  end
73
67
 
74
- def generate_logs(webhook_request, http_response, error, logging_options)
75
- webhook_request_logger = PactBroker::Webhooks::WebhookRequestLogger.new(logging_options)
76
- webhook_request_logger.log(
77
- uuid,
78
- webhook_request,
79
- http_response,
80
- error
81
- )
82
- end
83
-
84
68
  def to_s
85
69
  "webhook for consumer=#{consumer_name} provider=#{provider_name} uuid=#{uuid}"
86
70
  end
@@ -100,6 +84,33 @@ module PactBroker
100
84
  def trigger_on_provider_verification_published?
101
85
  events.any?(&:provider_verification_published?)
102
86
  end
87
+
88
+ private
89
+
90
+ def execute_request(webhook_request)
91
+ http_response = nil
92
+ error = nil
93
+ begin
94
+ http_response = webhook_request.execute
95
+ rescue StandardError => e
96
+ error = e
97
+ end
98
+ return http_response, error
99
+ end
100
+
101
+ def template_parameters(pact, verification, options)
102
+ PactBroker::Webhooks::PactAndVerificationParameters.new(pact, verification, options.fetch(:webhook_context)).to_hash
103
+ end
104
+
105
+ def generate_logs(webhook_request, http_response, error, logging_options)
106
+ webhook_request_logger = PactBroker::Webhooks::WebhookRequestLogger.new(logging_options)
107
+ webhook_request_logger.log(
108
+ uuid,
109
+ webhook_request,
110
+ http_response,
111
+ error
112
+ )
113
+ end
103
114
  end
104
115
  end
105
116
  end
@@ -0,0 +1,13 @@
1
+ module PactBroker
2
+ module HashRefinements
3
+ refine Hash do
4
+ def deep_merge(other_hash, &block)
5
+ block_actual = Proc.new {|key, oldval, newval|
6
+ newval = block.call(key, oldval, newval) if block_given?
7
+ [oldval, newval].all? {|v| v.is_a?(Hash)} ? oldval.merge(newval, &block_actual) : newval
8
+ }
9
+ merge(other_hash, &block_actual)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -13,6 +13,22 @@ en:
13
13
  pact_broker:
14
14
  messages:
15
15
  response_body_hidden: For security purposes, the response details are not logged. To enable response logging, configure the webhook_host_whitelist property. See /doc/webhooks#whitelist for more information.
16
+ webhooks:
17
+ parameters:
18
+ pactbroker:
19
+ consumerName: the consumer name
20
+ providerName: the provider name
21
+ consumerVersionNumber: the version number of the most recent consumer version associated with the pact content.
22
+ providerVersionNumber: the provider version number for the verification result
23
+ consumerVersionTags: the list of tag names for the most recent consumer version associated with the pact content, separated by ", "
24
+ providerVersionTags: the list of tag names for the provider version associated with the verification result, separated by ", ".
25
+ consumerLabels: the list of labels for the consumer associated with the pact content, separated by ", ".
26
+ providerLabels: the list of labels for the provider associated with the pact content, separated by ", ".
27
+ pactUrl: the "permalink" URL to the newly published pact (the URL specifying the consumer version URL, rather than the "/latest" format.
28
+ verificationResultUrl: the URL to the relevant verification result.
29
+ githubVerificationStatus: the verification status using the correct keywords for posting to the Github commit status API. See https://developer.github.com/v3/repos/statuses.
30
+ bitbucketVerificationStatus: the verification status using the correct keywords for posting to the Bitbucket commit status API. See https://developer.atlassian.com/server/bitbucket/how-tos/updating-build-status-for-commits/.
31
+
16
32
  errors:
17
33
  validation:
18
34
  blank: "cannot be blank."
@@ -32,7 +32,7 @@ module PactBroker
32
32
  end
33
33
 
34
34
  def log_error e, description = nil
35
- message = "#{e.class} #{e.message} #{e.backtrace.join("\n")}"
35
+ message = "#{e.class} #{e.message}\n#{e.backtrace.join("\n")}"
36
36
  message = "#{description} - #{message}" if description
37
37
  logger.error message
38
38
  end
@@ -37,7 +37,6 @@ module PactBroker
37
37
  "No previous distinct version was found for #{pact.name}"
38
38
  end
39
39
 
40
-
41
40
  # The next pact version after the previous distinct version.
42
41
  # Eg. v1 (previous distinct) -> pactContentA
43
42
  # v2 (next pact) -> pactContentB
@@ -1,13 +1,21 @@
1
1
  require 'sequel'
2
+ require 'pact_broker/repositories/helpers'
3
+ require 'pact_broker/verifications/latest_verification_for_pact_version'
2
4
 
3
5
  module PactBroker
4
6
  module Pacts
5
7
  class PactVersion < Sequel::Model(:pact_versions)
8
+ plugin :timestamps
6
9
  one_to_many :pact_publications, reciprocal: :pact_version
7
- one_to_many :verifications, reciprocal: :verification, order: :id, :class => "PactBroker::Domain::Verification"
10
+ one_to_many :verifications, reciprocal: :verification, order: :id, class: "PactBroker::Domain::Verification"
11
+ one_to_one :latest_verification, class: "PactBroker::Verifications::LatestVerificationForPactVersion", key: :pact_version_id, primary_key: :id
8
12
  associate(:many_to_one, :provider, class: "PactBroker::Domain::Pacticipant", key: :provider_id, primary_key: :id)
9
13
  associate(:many_to_one, :consumer, class: "PactBroker::Domain::Pacticipant", key: :consumer_id, primary_key: :id)
10
14
 
15
+ dataset_module do
16
+ include PactBroker::Repositories::Helpers
17
+ end
18
+
11
19
  def name
12
20
  "Pact between #{consumer_name} and #{provider_name}"
13
21
  end
@@ -34,10 +42,6 @@ module PactBroker
34
42
  .last
35
43
  end
36
44
 
37
- def latest_verification
38
- verifications.last
39
- end
40
-
41
45
  def consumer_versions
42
46
  PactBroker::Domain::Version.where(id: PactBroker::Pacts::PactPublication.select(:consumer_version_id).where(pact_version_id: id)).order(:order)
43
47
  end
@@ -45,9 +49,11 @@ module PactBroker
45
49
  def latest_consumer_version_number
46
50
  latest_consumer_version.number
47
51
  end
48
- end
49
52
 
50
- PactVersion.plugin :timestamps
53
+ def upsert
54
+ self.class.upsert(to_hash, [:consumer_id, :provider_id, :sha])
55
+ end
56
+ end
51
57
  end
52
58
  end
53
59
 
@@ -292,15 +292,13 @@ module PactBroker
292
292
  end
293
293
 
294
294
  def create_pact_version consumer_id, provider_id, sha, json_content
295
- logger.debug("Creating new pact version for sha #{sha}")
296
- # Content.from_json(json_content).with_ids.to_json
297
- pact_version = PactVersion.new(
295
+ PactVersion.new(
298
296
  consumer_id: consumer_id,
299
297
  provider_id: provider_id,
300
298
  sha: sha,
301
- content: json_content
302
- )
303
- pact_version.save
299
+ content: json_content,
300
+ created_at: Sequel.datetime_class.now
301
+ ).upsert
304
302
  end
305
303
 
306
304
  def find_all_database_versions_between(consumer_name, options, base_class = LatestPactPublicationsByConsumerVersion)
@@ -152,10 +152,9 @@ module PactBroker
152
152
  end
153
153
 
154
154
  def merge_consumer_version_info(webhook_options, pact)
155
- webhook_context = webhook_options.fetch(:webhook_context, {}).merge(
156
- consumer_version_tags: pact.consumer_version_tag_names
157
- )
158
- webhook_options.merge(webhook_context: webhook_context)
155
+ execution_configuration = webhook_options[:webhook_execution_configuration]
156
+ .with_webhook_context(consumer_version_tags: pact.consumer_version_tag_names)
157
+ webhook_options.merge(webhook_execution_configuration: execution_configuration)
159
158
  end
160
159
  end
161
160
  end
@@ -51,7 +51,7 @@ module PactBroker
51
51
  where(key).update(row)
52
52
  end
53
53
  end
54
- model.find(row.select{ |key, _| unique_key_names.include?(key)} )
54
+ model.where(row.select{ |key, _| unique_key_names.include?(key)}).single_record
55
55
  end
56
56
  end
57
57
  end
@@ -0,0 +1,13 @@
1
+ module PactBroker
2
+ module StringRefinements
3
+ refine String do
4
+ def not_blank?
5
+ !blank?
6
+ end
7
+
8
+ def blank?
9
+ self.strip.size == 0
10
+ end
11
+ end
12
+ end
13
+ end
@@ -1,7 +1,6 @@
1
1
  require 'pact_broker/domain/tag'
2
2
  require 'pact_broker/repositories/helpers'
3
3
 
4
-
5
4
  module PactBroker
6
5
  module Tags
7
6
  class Repository
@@ -5,4 +5,5 @@
5
5
  %script{type: 'text/javascript', src:'/javascripts/jquery.tablesorter.min.js'}
6
6
  %script{type: 'text/javascript', src:'/javascripts/material-menu.js'}
7
7
  %script{type: 'text/javascript', src:'/javascripts/index.js'}
8
+ %script{type: 'text/javascript', src:'/javascripts/clipboard.js'}
8
9
  %script{type: 'text/javascript', src:'/javascripts/jquery-confirm.min.js'}
@@ -39,8 +39,10 @@
39
39
  %a{:href => index_item.consumer_group_url }
40
40
  = escape_html(index_item.consumer_name)
41
41
  %td.consumer-version-number
42
- %div
42
+ %div.clippable
43
43
  = escape_html(index_item.consumer_version_number)
44
+ %button.clippy.hidden{ title: "Copy to clipboard" }
45
+ %span.glyphicon.glyphicon-copy
44
46
  - if index_item.latest?
45
47
  .tag.label.label-success
46
48
  latest
@@ -56,8 +58,10 @@
56
58
  %a{ href: index_item.provider_group_url }
57
59
  = escape_html(index_item.provider_name)
58
60
  %td.provider-version-number
59
- %div
61
+ %div.clippable
60
62
  = escape_html(index_item.provider_version_number)
63
+ %button.clippy.hidden{ title: "Copy to clipboard" }
64
+ %span.glyphicon.glyphicon-copy
61
65
  - index_item.provider_version_latest_tag_names.each do | tag_name |
62
66
  .tag.label.label-primary
63
67
  = escape_html(tag_name)
@@ -85,6 +89,8 @@
85
89
  });
86
90
 
87
91
  $(document).ready(function(){
92
+ initializeClipper(".clippable");
93
+
88
94
  $("span.pact a").load("/images/doc-text.svg");
89
95
  $("span.pact-matrix a").load("/images/doc-matrix.svg");
90
96
  $('td[data-toggle="tooltip"]').each(function(index, td){
@@ -5,6 +5,7 @@
5
5
  %script{type: 'text/javascript', src:'/javascripts/jquery-3.3.1.min.js'}
6
6
  %script{type: 'text/javascript', src:'/javascripts/jquery.tablesorter.min.js'}
7
7
  %script{type: 'text/javascript', src:'/javascripts/matrix.js'}
8
+ %script{type: 'text/javascript', src:'/javascripts/clipboard.js'}
8
9
  %script{type: 'text/javascript', src:'/js/bootstrap.min.js'}
9
10
 
10
11
  .container
@@ -102,9 +103,11 @@
102
103
  %a{href: line.consumer_name_url}
103
104
  = line.consumer_name
104
105
  %td.consumer-version{'data-sort-value' => line.consumer_version_order}
105
- %div
106
+ %div.clippable
106
107
  %a{href: line.consumer_version_number_url}
107
108
  = line.display_consumer_version_number
109
+ %button.clippy.hidden{ title: "Copy to clipboard" }
110
+ %span.glyphicon.glyphicon-copy
108
111
  - line.latest_consumer_version_tags.each do | tag |
109
112
  .tag-parent{"title": tag.tooltip, "data-toggle": "tooltip", "data-placement": "right"}
110
113
  %a{href: tag.url}
@@ -126,9 +129,11 @@
126
129
  %a{href: line.provider_name_url}
127
130
  = line.provider_name
128
131
  %td.provider-version{'data-sort-value' => line.provider_version_order}
129
- %div
132
+ %div.clippable
130
133
  %a{href: line.provider_version_number_url}
131
134
  = line.display_provider_version_number
135
+ %button.clippy.hidden{ title: "Copy to clipboard" }
136
+ %span.glyphicon.glyphicon-copy
132
137
  - line.latest_provider_version_tags.each do | tag |
133
138
  .tag-parent{"title": tag.tooltip, "data-toggle": "tooltip", "data-placement": "right"}
134
139
  %a{href: tag.url}
@@ -145,3 +150,8 @@
145
150
  = "#{line.verification_status} (number #{line.number})"
146
151
  - else
147
152
  = line.verification_status
153
+
154
+ :javascript
155
+ $(document).ready(function(){
156
+ initializeClipper(".clippable");
157
+ });
@@ -107,7 +107,6 @@ module PactBroker
107
107
  .tag(consumer_version_tag)
108
108
  .provider_version_tag(provider_version_tag)
109
109
 
110
-
111
110
  query.reverse_order(
112
111
  Sequel[:latest_pact_publications_by_consumer_versions][:consumer_version_order],
113
112
  Sequel[:latest_pact_publications_by_consumer_versions][:revision_number],
@@ -2,6 +2,7 @@ require 'pact_broker/repositories'
2
2
  require 'pact_broker/api/decorators/verification_decorator'
3
3
  require 'pact_broker/verifications/summary_for_consumer_version'
4
4
  require 'pact_broker/logging'
5
+ require 'pact_broker/hash_refinements'
5
6
 
6
7
  module PactBroker
7
8
 
@@ -13,26 +14,27 @@ module PactBroker
13
14
  extend PactBroker::Repositories
14
15
  extend PactBroker::Services
15
16
  include PactBroker::Logging
17
+ using PactBroker::HashRefinements
16
18
 
17
19
  def next_number
18
20
  verification_repository.next_number
19
21
  end
20
22
 
21
23
  def create next_verification_number, params, pact, webhook_options
22
- logger.info "Creating verification #{next_verification_number} for pact_id=#{pact.id} from params #{params}"
24
+ logger.info "Creating verification #{next_verification_number} for pact_id=#{pact.id} from params #{params.reject{ |k,_| k == "testResults"}}"
23
25
  verification = PactBroker::Domain::Verification.new
24
26
  provider_version_number = params.fetch('providerApplicationVersion')
25
27
  PactBroker::Api::Decorators::VerificationDecorator.new(verification).from_hash(params)
26
28
  verification.number = next_verification_number
27
29
  verification = verification_repository.create(verification, provider_version_number, pact)
28
- webhook_context = webhook_options[:webhook_context].merge(
29
- provider_version_tags: verification.provider_version_tag_names
30
- )
30
+
31
+ execution_configuration = webhook_options[:webhook_execution_configuration]
32
+ .with_webhook_context(provider_version_tags: verification.provider_version_tag_names)
31
33
 
32
34
  webhook_service.trigger_webhooks(pact,
33
35
  verification,
34
36
  PactBroker::Webhooks::WebhookEvent::VERIFICATION_PUBLISHED,
35
- webhook_options.merge(webhook_context: webhook_context)
37
+ webhook_options.deep_merge(webhook_execution_configuration: execution_configuration)
36
38
  )
37
39
  verification
38
40
  end
@@ -1,3 +1,3 @@
1
1
  module PactBroker
2
- VERSION = '2.34.0'
2
+ VERSION = '2.35.0'
3
3
  end
@@ -5,7 +5,6 @@ module PactBroker
5
5
  module Versions
6
6
  class ParseSemanticVersion
7
7
 
8
-
9
8
  def self.call string_version
10
9
  PactBroker.configuration.semver_formats.each do |semver_format|
11
10
  parsed_version = ::SemVer.parse(string_version, semver_format)
@@ -2,7 +2,6 @@ require 'sequel'
2
2
  require 'pact_broker/db'
3
3
  require 'pact_broker/repositories/helpers'
4
4
 
5
-
6
5
  module PactBroker
7
6
  module Webhooks
8
7
  class Execution < Sequel::Model(
@@ -0,0 +1,45 @@
1
+ require 'pact_broker/hash_refinements'
2
+
3
+ module PactBroker
4
+ module Webhooks
5
+ class ExecutionConfiguration
6
+ using PactBroker::HashRefinements
7
+
8
+ def initialize(params = {})
9
+ @params = params
10
+ end
11
+
12
+ def with_updated_attribute(new_attribute)
13
+ ExecutionConfiguration.new(params.deep_merge(new_attribute))
14
+ end
15
+
16
+ def with_show_response(value)
17
+ with_updated_attribute(logging_options: { show_response: value })
18
+ end
19
+
20
+ def with_success_log_message(value)
21
+ with_updated_attribute(logging_options: { success_log_message: value })
22
+ end
23
+
24
+ def with_failure_log_message(value)
25
+ with_updated_attribute(logging_options: { failure_log_message: value })
26
+ end
27
+
28
+ def with_webhook_context(value)
29
+ with_updated_attribute(webhook_context: value)
30
+ end
31
+
32
+ def [](key)
33
+ params[key]
34
+ end
35
+
36
+ def to_hash
37
+ params
38
+ end
39
+
40
+ private
41
+
42
+ attr_reader :params
43
+ end
44
+ end
45
+ end
@@ -1,6 +1,7 @@
1
1
  require 'sucker_punch'
2
2
  require 'pact_broker/webhooks/service'
3
3
  require 'pact_broker/logging'
4
+ require 'pact_broker/webhooks/execution_configuration'
4
5
 
5
6
  module PactBroker
6
7
  module Webhooks
@@ -46,14 +47,10 @@ module PactBroker
46
47
  end
47
48
 
48
49
  def webhook_options(data)
49
- logging_options = data[:logging_options].merge(
50
- success_log_message: "Successfully executed webhook",
51
- failure_log_message: failure_log_message
52
- )
53
- {
54
- logging_options: logging_options,
55
- webhook_context: data[:webhook_context]
56
- }
50
+ data[:webhook_execution_configuration]
51
+ .with_success_log_message("Successfully executed webhook")
52
+ .with_failure_log_message(failure_log_message)
53
+ .to_hash
57
54
  end
58
55
 
59
56
  def failure_log_message
@@ -1,6 +1,33 @@
1
1
  module PactBroker
2
2
  module Webhooks
3
3
  class PactAndVerificationParameters
4
+ PACT_URL = 'pactbroker.pactUrl'
5
+ VERIFICATION_RESULT_URL = 'pactbroker.verificationResultUrl'
6
+ CONSUMER_VERSION_NUMBER = 'pactbroker.consumerVersionNumber'
7
+ PROVIDER_VERSION_NUMBER = 'pactbroker.providerVersionNumber'
8
+ PROVIDER_VERSION_TAGS = 'pactbroker.providerVersionTags'
9
+ CONSUMER_VERSION_TAGS = 'pactbroker.consumerVersionTags'
10
+ CONSUMER_NAME = 'pactbroker.consumerName'
11
+ PROVIDER_NAME = 'pactbroker.providerName'
12
+ GITHUB_VERIFICATION_STATUS = 'pactbroker.githubVerificationStatus'
13
+ BITBUCKET_VERIFICATION_STATUS = 'pactbroker.bitbucketVerificationStatus'
14
+ CONSUMER_LABELS = 'pactbroker.consumerLabels'
15
+ PROVIDER_LABELS = 'pactbroker.providerLabels'
16
+
17
+ ALL = [
18
+ CONSUMER_NAME,
19
+ PROVIDER_NAME,
20
+ CONSUMER_VERSION_NUMBER,
21
+ PROVIDER_VERSION_NUMBER,
22
+ PROVIDER_VERSION_TAGS,
23
+ CONSUMER_VERSION_TAGS,
24
+ PACT_URL,
25
+ VERIFICATION_RESULT_URL,
26
+ GITHUB_VERIFICATION_STATUS,
27
+ BITBUCKET_VERIFICATION_STATUS,
28
+ CONSUMER_LABELS,
29
+ PROVIDER_LABELS
30
+ ]
4
31
 
5
32
  def initialize(pact, trigger_verification, webhook_context)
6
33
  @pact = pact
@@ -11,18 +38,18 @@ module PactBroker
11
38
 
12
39
  def to_hash
13
40
  @hash ||= {
14
- '${pactbroker.pactUrl}' => pact ? PactBroker::Api::PactBrokerUrls.pact_version_url_with_metadata(pact, base_url) : "",
15
- '${pactbroker.verificationResultUrl}' => verification_url,
16
- '${pactbroker.consumerVersionNumber}' => consumer_version_number,
17
- '${pactbroker.providerVersionNumber}' => verification ? verification.provider_version_number : "",
18
- '${pactbroker.providerVersionTags}' => provider_version_tags,
19
- '${pactbroker.consumerVersionTags}' => consumer_version_tags,
20
- '${pactbroker.consumerName}' => pact ? pact.consumer_name : "",
21
- '${pactbroker.providerName}' => pact ? pact.provider_name : "",
22
- '${pactbroker.githubVerificationStatus}' => github_verification_status,
23
- '${pactbroker.bitbucketVerificationStatus}' => bitbucket_verification_status,
24
- '${pactbroker.consumerLabels}' => pacticipant_labels(pact && pact.consumer),
25
- '${pactbroker.providerLabels}' => pacticipant_labels(pact && pact.provider)
41
+ PACT_URL => pact ? PactBroker::Api::PactBrokerUrls.pact_version_url_with_metadata(pact, base_url) : "",
42
+ VERIFICATION_RESULT_URL => verification_url,
43
+ CONSUMER_VERSION_NUMBER => consumer_version_number,
44
+ PROVIDER_VERSION_NUMBER => verification ? verification.provider_version_number : "",
45
+ PROVIDER_VERSION_TAGS => provider_version_tags,
46
+ CONSUMER_VERSION_TAGS => consumer_version_tags,
47
+ CONSUMER_NAME => pact ? pact.consumer_name : "",
48
+ PROVIDER_NAME => pact ? pact.provider_name : "",
49
+ GITHUB_VERIFICATION_STATUS => github_verification_status,
50
+ BITBUCKET_VERIFICATION_STATUS => bitbucket_verification_status,
51
+ CONSUMER_LABELS => pacticipant_labels(pact && pact.consumer),
52
+ PROVIDER_LABELS => pacticipant_labels(pact && pact.provider)
26
53
  }
27
54
  end
28
55