pact_broker 2.35.0 → 2.36.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +19 -0
  3. data/db/migrations/000029_create_latest_tagged_pact_publications.rb +2 -0
  4. data/lib/pact_broker/api.rb +3 -0
  5. data/lib/pact_broker/api/decorators/extended_pact_decorator.rb +42 -0
  6. data/lib/pact_broker/api/decorators/extended_verification_decorator.rb +16 -0
  7. data/lib/pact_broker/api/decorators/pact_decorator.rb +6 -3
  8. data/lib/pact_broker/api/decorators/verification_decorator.rb +4 -0
  9. data/lib/pact_broker/api/pact_broker_urls.rb +12 -0
  10. data/lib/pact_broker/api/resources/dashboard.rb +1 -3
  11. data/lib/pact_broker/api/resources/index.rb +5 -0
  12. data/lib/pact_broker/api/resources/latest_verification_for_pact.rb +19 -0
  13. data/lib/pact_broker/api/resources/latest_verifications_for_consumer_version.rb +0 -1
  14. data/lib/pact_broker/api/resources/metrics.rb +21 -0
  15. data/lib/pact_broker/api/resources/pact.rb +8 -1
  16. data/lib/pact_broker/api/resources/pact_versions.rb +0 -1
  17. data/lib/pact_broker/api/resources/verification.rb +14 -1
  18. data/lib/pact_broker/domain/pact.rb +1 -2
  19. data/lib/pact_broker/domain/verification.rb +5 -3
  20. data/lib/pact_broker/index/service.rb +16 -1
  21. data/lib/pact_broker/matrix/aggregated_row.rb +14 -1
  22. data/lib/pact_broker/matrix/repository.rb +29 -25
  23. data/lib/pact_broker/matrix/resolved_selector.rb +3 -1
  24. data/lib/pact_broker/matrix/row.rb +6 -2
  25. data/lib/pact_broker/metrics/service.rb +56 -0
  26. data/lib/pact_broker/pacts/all_pact_publications.rb +8 -1
  27. data/lib/pact_broker/pacts/pact_publication.rb +9 -2
  28. data/lib/pact_broker/services.rb +5 -0
  29. data/lib/pact_broker/ui/views/index/show-with-tags.haml +2 -2
  30. data/lib/pact_broker/ui/views/matrix/show.haml +2 -2
  31. data/lib/pact_broker/verifications/repository.rb +4 -0
  32. data/lib/pact_broker/verifications/service.rb +4 -0
  33. data/lib/pact_broker/version.rb +1 -1
  34. data/public/javascripts/clipboard.js +2 -2
  35. data/spec/features/get_latest_verification_for_pact_spec.rb +42 -0
  36. data/spec/features/get_pact_versions_spec.rb +0 -5
  37. data/spec/features/metrics_spec.rb +23 -0
  38. data/spec/lib/pact_broker/api/decorators/extended_pact_decorator_spec.rb +61 -0
  39. data/spec/lib/pact_broker/api/decorators/pact_decorator_spec.rb +2 -1
  40. data/spec/lib/pact_broker/api/decorators/verification_decorator_spec.rb +4 -1
  41. data/spec/lib/pact_broker/api/decorators/verification_summary_decorator_spec.rb +3 -1
  42. data/spec/lib/pact_broker/index/service_spec.rb +29 -4
  43. data/spec/lib/pact_broker/matrix/aggregated_row_spec.rb +23 -2
  44. data/spec/lib/pact_broker/matrix/deployment_status_summary_spec.rb +2 -0
  45. data/spec/lib/pact_broker/matrix/repository_query_limit_spec.rb +44 -0
  46. data/spec/lib/pact_broker/pacts/pact_publication_spec.rb +21 -3
  47. metadata +15 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 16a87ec2e8bd7d3047768e040433544194b306fa
4
- data.tar.gz: 7dda1535ad3341c18acd174f2459cae29be8e287
3
+ metadata.gz: 248fdb1abb2fb57331796c6e974be143889a589a
4
+ data.tar.gz: 3c51b8d3b502ffcdc222a0dc8a6b752fbd0876ae
5
5
  SHA512:
6
- metadata.gz: cf0fa7165f17a13b045d068d78cbe0aebe5cf860055d271a00dc369d56eff478c3946c8a22451f323eb762bee75069c6359c208c6178dfd82c0561a5c03444bd
7
- data.tar.gz: 27f0ffd8fceaa7f907fe3e256c4e0f63947ffc4343cb01982e4d1eb5fe2d63b4c0097d602653026cc8deec4349b49e6c7bea9776fa45fc7e67bf80388df94f0b
6
+ metadata.gz: 99770d645322dbd544ab387a283245c50f24e358e15a5afe2a15b9cb453ef7235815f3cf1d3533d443bc785551fca1e94179862e2b47d3270face9879e9d2a61
7
+ data.tar.gz: 0ddb143e53ffeaea209268239e64095222b6fcf19047fc0d464ad33dfaaaee02385a37e6a41cb5a97c4ad147f9f729a55d5ed0df5484fd88f7a47391eaef0e7b
@@ -1,3 +1,22 @@
1
+ <a name="v2.36.0"></a>
2
+ ### v2.36.0 (2019-08-30)
3
+
4
+
5
+ #### Features
6
+
7
+ * add resource to get latest verification for a pact ([f02a1ca0](/../../commit/f02a1ca0))
8
+ * add /metrics endpoint ([9bcbc1bd](/../../commit/9bcbc1bd))
9
+ * add tags to verification resource ([830632a2](/../../commit/830632a2))
10
+ * add content type to return pact with extra metadata (eg tags) ([76668639](/../../commit/76668639))
11
+ * remove use of 'stale' for dashboard resource ([e173f5cf](/../../commit/e173f5cf))
12
+
13
+
14
+ #### Bug Fixes
15
+
16
+ * pact broker client issue 53 (#299) ([aa27cef3](/../../commit/aa27cef3))
17
+ * version column resize when clipboard icon appears (#292) ([5aa668e9](/../../commit/5aa668e9))
18
+
19
+
1
20
  <a name="v2.35.0"></a>
2
21
  ### v2.35.0 (2019-08-08)
3
22
 
@@ -1,5 +1,7 @@
1
1
  Sequel.migration do
2
2
  up do
3
+ # The pact for the latest consumer version (ordered by consumer version order) *that has a pact* for each tag
4
+ # eg. For each tag, find all the consumer versions that have pacts, order them by consumer version order, then get the pact for the latest consumer version.
3
5
  create_or_replace_view(:latest_tagged_pact_consumer_version_orders,
4
6
  "select provider_id, consumer_id, t.name as tag_name, max(consumer_version_order) as latest_consumer_version_order
5
7
  from latest_pact_publications_by_consumer_versions ap
@@ -26,6 +26,8 @@ module PactBroker
26
26
  # Verifications
27
27
  add ['pacts', 'provider', :provider_name, 'consumer', :consumer_name, 'pact-version', :pact_version_sha, 'verification-results'], Api::Resources::Verifications, {resource_name: "verification_results"}
28
28
  add ['pacts', 'provider', :provider_name, 'consumer', :consumer_name, 'pact-version', :pact_version_sha, 'metadata', :metadata, 'verification-results'], Api::Resources::Verifications, {resource_name: "verification_results"}
29
+ add ['pacts', 'provider', :provider_name, 'consumer', :consumer_name, 'version', :consumer_version_number, 'verification-results', 'latest'], Api::Resources::LatestVerificationForPact, {resource_name: "latest_verification_results_for_pact_publication"}
30
+ add ['pacts', 'provider', :provider_name, 'consumer', :consumer_name, 'pact-version', :pact_version_sha, 'verification-results', 'latest'], Api::Resources::LatestVerificationForPact, {resource_name: "latest_verification_results_for_pact_version"}
29
31
  add ['pacts', 'provider', :provider_name, 'consumer', :consumer_name, 'pact-version', :pact_version_sha, 'verification-results', :verification_number], Api::Resources::Verification, {resource_name: "verification_result"}
30
32
  add ['pacts', 'provider', :provider_name, 'consumer', :consumer_name, 'pact-version', :pact_version_sha, 'verification-results', :verification_number, 'triggered-webhooks'], Api::Resources::VerificationTriggeredWebhooks, {resource_name: "verification_result_triggered_webhooks"}
31
33
  add ['verification-results', 'consumer', :consumer_name, 'version', :consumer_version_number,'latest'], Api::Resources::LatestVerificationsForConsumerVersion, {resource_name: "verification_results_for_consumer_version"}
@@ -91,6 +93,7 @@ module PactBroker
91
93
 
92
94
  add ['integrations'], Api::Resources::Integrations, {resource_name: "integrations"}
93
95
  add ['integrations', 'provider', :provider_name, 'consumer', :consumer_name], Api::Resources::Integration, {resource_name: "integration"}
96
+ add ['metrics'], Api::Resources::Metrics, {resource_name: 'metrics'}
94
97
  add [], Api::Resources::Index, {resource_name: "index"}
95
98
  end
96
99
  end
@@ -0,0 +1,42 @@
1
+ require 'pact_broker/api/decorators/pact_decorator'
2
+
3
+ module PactBroker
4
+ module Api
5
+ module Decorators
6
+ # Make a different content type for adding extra information for the UI, as
7
+ # some pact parsing tools blow up when there are unexpected keys :|
8
+
9
+ class ExtendedPactDecorator < PactDecorator
10
+ class TagDecorator < BaseDecorator
11
+ property :name
12
+ property :latest, getter: ->(_) { true }
13
+
14
+ link "pb:latest-pact" do | opts |
15
+ {
16
+ name: "The latest pact with the tag #{represented.name}",
17
+ href: latest_tagged_pact_url(represented.pact, represented.name, opts[:base_url])
18
+ }
19
+ end
20
+ end
21
+
22
+ property :content_hash, as: :contract
23
+ collection :head_tags, exec_context: :decorator, as: :tags, embedded: true, extend: TagDecorator
24
+
25
+ # TODO rather than remove the contract keys that we added in the super class,
26
+ # it would be better to inherit from a shared super class
27
+ def to_hash(options = {})
28
+ keys_to_remove = represented.content_hash.keys
29
+ super.each_with_object({}) do | (key, value), new_hash |
30
+ new_hash[key] = value unless keys_to_remove.include?(key)
31
+ end
32
+ end
33
+
34
+ def head_tags
35
+ represented.head_tag_names.collect do | tag_name |
36
+ OpenStruct.new(name: tag_name, pact: represented)
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,16 @@
1
+ require 'pact_broker/api/decorators/verification_decorator'
2
+
3
+ module PactBroker
4
+ module Api
5
+ module Decorators
6
+ class ExtendedVerificationDecorator < VerificationDecorator
7
+ class TagDecorator < BaseDecorator
8
+ property :name
9
+ property :latest?, as: :latest
10
+ end
11
+
12
+ collection :provider_version_tags, as: :tags, embedded: true, extend: TagDecorator
13
+ end
14
+ end
15
+ end
16
+ end
@@ -3,11 +3,8 @@ require 'pact_broker/json'
3
3
  require 'pact_broker/api/decorators/timestamps'
4
4
 
5
5
  module PactBroker
6
-
7
6
  module Api
8
-
9
7
  module Decorators
10
-
11
8
  class PactDecorator < BaseDecorator
12
9
 
13
10
  include Timestamps
@@ -149,6 +146,12 @@ module PactBroker
149
146
  }
150
147
  end
151
148
 
149
+ link :'pb:latest-verification-results' do | options |
150
+ {
151
+ href: latest_verification_for_pact_url(represented, options.fetch(:base_url))
152
+ }
153
+ end
154
+
152
155
  link :'pb:triggered-webhooks' do | options |
153
156
  {
154
157
  title: "Webhooks triggered by the publication of this pact",
@@ -4,6 +4,10 @@ module PactBroker
4
4
  module Api
5
5
  module Decorators
6
6
  class VerificationDecorator < BaseDecorator
7
+ class TagDecorator < BaseDecorator
8
+ property :name
9
+ property :latest?, as: :latest
10
+ end
7
11
 
8
12
  property :provider_name, as: :providerName, writeable: false
9
13
  property :provider_version_number, as: :providerApplicationVersion, writeable: false
@@ -90,6 +90,10 @@ module PactBroker
90
90
  "#{pactigration_base_url(base_url, pact)}/latest-untagged"
91
91
  end
92
92
 
93
+ def latest_tagged_pact_url pact, tag_name, base_url
94
+ "#{latest_pact_url(base_url, pact)}/#{url_encode(tag_name)}"
95
+ end
96
+
93
97
  def latest_pacts_url base_url
94
98
  "#{base_url}/pacts/latest"
95
99
  end
@@ -153,6 +157,14 @@ module PactBroker
153
157
  "#{base_url}/verification-results/consumer/#{url_encode(version.pacticipant.name)}/version/#{version.number}/latest"
154
158
  end
155
159
 
160
+ def latest_verification_for_pact_url pact, base_url
161
+ verification_url_from_params(
162
+ provider_name: pact.provider_name,
163
+ consumer_name: pact.consumer_name,
164
+ pact_version_sha: pact.pact_version_sha,
165
+ verification_number: 'latest')
166
+ end
167
+
156
168
  def verification_triggered_webhooks_url verification, base_url = ''
157
169
  "#{verification_url(verification, base_url)}/triggered-webhooks"
158
170
  end
@@ -5,9 +5,7 @@ require 'pact_broker/api/decorators/dashboard_text_decorator'
5
5
  module PactBroker
6
6
  module Api
7
7
  module Resources
8
-
9
8
  class Dashboard < BaseResource
10
-
11
9
  def content_types_provided
12
10
  [
13
11
  ["application/hal+json", :to_json],
@@ -30,7 +28,7 @@ module PactBroker
30
28
  private
31
29
 
32
30
  def index_items
33
- index_service.find_index_items(identifier_from_path.merge(tags: true))
31
+ index_service.find_index_items(identifier_from_path.merge(tags: true, dashboard: true))
34
32
  end
35
33
  end
36
34
  end
@@ -106,6 +106,11 @@ module PactBroker
106
106
  title: "Get, create or delete a tag for a pacticipant version",
107
107
  templated: true
108
108
  },
109
+ 'pb:metrics' =>
110
+ {
111
+ href: base_url + '/metrics',
112
+ title: "Get Pact Broker metrics",
113
+ },
109
114
  'beta:pending-provider-pacts' =>
110
115
  {
111
116
  href: base_url + '/pacts/provider/{provider}/pending',
@@ -0,0 +1,19 @@
1
+ require 'pact_broker/api/resources/verification'
2
+
3
+ module PactBroker
4
+ module Api
5
+ module Resources
6
+ class LatestVerificationForPact < Verification
7
+ private
8
+
9
+ def pact
10
+ @pact ||= pact_service.find_pact(pact_params)
11
+ end
12
+
13
+ def verification
14
+ @verification ||= pact && verification_service.find_latest_for_pact(pact)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -7,7 +7,6 @@ require 'pact_broker/api/decorators/verification_summary_decorator'
7
7
  module PactBroker
8
8
  module Api
9
9
  module Resources
10
-
11
10
  class LatestVerificationsForConsumerVersion < BaseResource
12
11
 
13
12
  def allowed_methods
@@ -0,0 +1,21 @@
1
+ require 'pact_broker/api/resources/base_resource'
2
+
3
+ module PactBroker
4
+ module Api
5
+ module Resources
6
+ class Metrics < BaseResource
7
+ def content_types_provided
8
+ [["application/hal+json", :to_json]]
9
+ end
10
+
11
+ def allowed_methods
12
+ ["GET", "OPTIONS"]
13
+ end
14
+
15
+ def to_json
16
+ metrics_service.metrics.to_json
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -2,6 +2,7 @@ require 'cgi'
2
2
  require 'pact_broker/api/resources/base_resource'
3
3
  require 'pact_broker/api/resources/pacticipant_resource_methods'
4
4
  require 'pact_broker/api/decorators/pact_decorator'
5
+ require 'pact_broker/api/decorators/extended_pact_decorator'
5
6
  require 'pact_broker/json'
6
7
  require 'pact_broker/pacts/pact_params'
7
8
  require 'pact_broker/api/contracts/put_pact_params_contract'
@@ -26,7 +27,9 @@ module PactBroker
26
27
  def content_types_provided
27
28
  [["application/hal+json", :to_json],
28
29
  ["application/json", :to_json],
29
- ["text/html", :to_html]]
30
+ ["text/html", :to_html],
31
+ ["application/vnd.pactbrokerextended.v1+json", :to_extended_json]
32
+ ]
30
33
  end
31
34
 
32
35
  def content_types_accepted
@@ -78,6 +81,10 @@ module PactBroker
78
81
  PactBroker::Api::Decorators::PactDecorator.new(pact).to_json(user_options: decorator_context(metadata: identifier_from_path[:metadata]))
79
82
  end
80
83
 
84
+ def to_extended_json
85
+ PactBroker::Api::Decorators::ExtendedPactDecorator.new(pact).to_json(user_options: decorator_context(metadata: identifier_from_path[:metadata]))
86
+ end
87
+
81
88
  def to_html
82
89
  PactBroker.configuration.html_pact_renderer.call(
83
90
  pact, {
@@ -5,7 +5,6 @@ require 'pact_broker/api/decorators/pact_versions_decorator'
5
5
  module PactBroker
6
6
  module Api
7
7
  module Resources
8
-
9
8
  class PactVersions < BaseResource
10
9
 
11
10
  def content_types_provided
@@ -3,13 +3,18 @@ require 'pact_broker/configuration'
3
3
  require 'pact_broker/domain/verification'
4
4
  require 'pact_broker/api/contracts/verification_contract'
5
5
  require 'pact_broker/api/decorators/verification_decorator'
6
+ require 'pact_broker/api/decorators/extended_verification_decorator'
6
7
 
7
8
  module PactBroker
8
9
  module Api
9
10
  module Resources
10
11
  class Verification < BaseResource
11
12
  def content_types_provided
12
- [["application/hal+json", :to_json], ["application/json", :to_json]]
13
+ [
14
+ ["application/hal+json", :to_json],
15
+ ["application/json", :to_json],
16
+ ["application/vnd.pactbrokerextended.v1+json", :to_extended_json]
17
+ ]
13
18
  end
14
19
 
15
20
  # Remember to update latest_verification_id_for_pact_version_and_provider_version
@@ -26,6 +31,10 @@ module PactBroker
26
31
  decorator_for(verification).to_json(user_options: {base_url: base_url})
27
32
  end
28
33
 
34
+ def to_extended_json
35
+ extended_decorator_for(verification).to_json(user_options: {base_url: base_url})
36
+ end
37
+
29
38
  private
30
39
 
31
40
  def verification
@@ -35,6 +44,10 @@ module PactBroker
35
44
  def decorator_for model
36
45
  PactBroker::Api::Decorators::VerificationDecorator.new(model)
37
46
  end
47
+
48
+ def extended_decorator_for model
49
+ PactBroker::Api::Decorators::ExtendedVerificationDecorator.new(model)
50
+ end
38
51
  end
39
52
  end
40
53
  end
@@ -6,7 +6,7 @@ module PactBroker
6
6
  module Domain
7
7
  class Pact
8
8
 
9
- attr_accessor :id, :provider, :consumer_version, :consumer, :created_at, :json_content, :consumer_version_number, :revision_number, :pact_version_sha, :latest_verification
9
+ attr_accessor :id, :provider, :consumer_version, :consumer, :created_at, :json_content, :consumer_version_number, :revision_number, :pact_version_sha, :latest_verification, :head_tag_names
10
10
 
11
11
  def initialize attributes
12
12
  attributes.each_pair do | key, value |
@@ -54,6 +54,5 @@ module PactBroker
54
54
  id
55
55
  end
56
56
  end
57
-
58
57
  end
59
58
  end
@@ -1,9 +1,10 @@
1
- require 'pact_broker/db'
2
- require 'pact_broker/repositories/helpers'
3
1
  require 'json'
2
+ require 'sequel'
3
+ require 'pact_broker/repositories/helpers'
4
+ require 'pact_broker/tags/tag_with_latest_flag'
4
5
 
5
- module PactBroker
6
6
 
7
+ module PactBroker
7
8
  module Domain
8
9
  class Verification < Sequel::Model
9
10
 
@@ -12,6 +13,7 @@ module PactBroker
12
13
  associate(:many_to_one, :provider_version, class: "PactBroker::Domain::Version", key: :provider_version_id, primary_key: :id)
13
14
  associate(:many_to_one, :provider, class: "PactBroker::Domain::Pacticipant", key: :provider_id, primary_key: :id)
14
15
  associate(:many_to_one, :consumer, class: "PactBroker::Domain::Pacticipant", key: :consumer_id, primary_key: :id)
16
+ associate(:one_to_many, :provider_version_tags, :class => "PactBroker::Tags::TagWithLatestFlag", primary_key: :provider_version_id, key: :version_id)
15
17
  plugin :serialization, :json, :test_results
16
18
 
17
19
  def before_create
@@ -35,14 +35,29 @@ module PactBroker
35
35
  end
36
36
  rows = rows.all.group_by(&:pact_publication_id).values.collect{ | rows| Matrix::AggregatedRow.new(rows) }
37
37
 
38
+
39
+
38
40
  rows.sort.collect do | row |
41
+ # The concept of "stale" (the pact used to be verified but then it changed and we haven't got
42
+ # a new verification result yet) only really make sense if we're trying to summarise
43
+ # the latest state of an integration. Once we start showing multiple pacts for each
44
+ # integration (ie. the latest for each tag) then each pact version is either verified,
45
+ # or it's not verified.
46
+ # For backwards compatiblity with the existing UI, don't change the 'stale' concept for the OSS
47
+ # UI - just ensure we don't use it for the new dashboard endpoint with the consumer/provider specified.
48
+ latest_verification = if options[:dashboard]
49
+ row.latest_verification_for_pact_version
50
+ else
51
+ row.latest_verification_for_pseudo_branch
52
+ end
53
+
39
54
  # TODO simplify. Do we really need 3 layers of abstraction?
40
55
  PactBroker::Domain::IndexItem.create(
41
56
  row.consumer,
42
57
  row.provider,
43
58
  row.pact,
44
59
  row.overall_latest?,
45
- row.latest_verification,
60
+ latest_verification,
46
61
  row.webhooks,
47
62
  row.latest_triggered_webhooks,
48
63
  options[:tags] ? row.consumer_head_tag_names : [],
@@ -24,7 +24,12 @@ module PactBroker
24
24
 
25
25
  # If this comes back nil, it won't be "cached", but it's a reasonably
26
26
  # quick query, so it's probably ok.
27
- def latest_verification
27
+ # The collection of pacts that belong to the same tag can be considered
28
+ # a pseudo branch. Find the latest verification for each pseudo branch
29
+ # and return the most recent. If this pact is the most recent overall,
30
+ # and there were no verifications found for any of the tags, then
31
+ # return the most recent verification
32
+ def latest_verification_for_pseudo_branch
28
33
  @latest_verification ||= begin
29
34
  verification = matrix_rows.collect do | row|
30
35
  row.verification || latest_verification_for_consumer_version_tag(row)
@@ -38,6 +43,14 @@ module PactBroker
38
43
  end
39
44
  end
40
45
 
46
+ def latest_verification_for_pact_version
47
+ @latest_verificaton_for_pact_version ||= begin
48
+ matrix_rows.collect do | row|
49
+ row.verification
50
+ end.compact.sort{ |v1, v2| v1.id <=> v2.id }.last
51
+ end
52
+ end
53
+
41
54
  # The list of tag names for which this pact publication is the most recent with that tag
42
55
  # There could, however, be a later consumer version that does't have a pact (perhaps because it was deleted)
43
56
  # that has the same tag.