pact_broker 2.35.0 → 2.36.0

Sign up to get free protection for your applications and to get access to all the features.
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.