pact_broker 2.93.3 → 2.95.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +42 -0
  3. data/README.md +7 -8
  4. data/db/migrations/20220303_increase_consumer_version_selector_hashes_column_size.rb +14 -0
  5. data/db/migrations/migration_helper.rb +1 -1
  6. data/lib/db.rb +1 -1
  7. data/lib/pact_broker/api/authorization/resource_access_policy.rb +1 -5
  8. data/lib/pact_broker/api/decorators/format_date_time.rb +9 -1
  9. data/lib/pact_broker/api/decorators/pacticipant_decorator.rb +8 -0
  10. data/lib/pact_broker/api/pact_broker_urls.rb +4 -0
  11. data/lib/pact_broker/api/paths.rb +5 -2
  12. data/lib/pact_broker/api/resources/badge.rb +2 -25
  13. data/lib/pact_broker/api/resources/badge_methods.rb +57 -0
  14. data/lib/pact_broker/api/resources/can_i_deploy_pacticipant_version_by_branch_to_environment.rb +67 -0
  15. data/lib/pact_broker/api/resources/can_i_deploy_pacticipant_version_by_branch_to_environment_badge.rb +29 -0
  16. data/lib/pact_broker/api/resources/can_i_deploy_pacticipant_version_by_tag_to_tag.rb +48 -0
  17. data/lib/pact_broker/api/resources/can_i_deploy_pacticipant_version_by_tag_to_tag_badge.rb +25 -0
  18. data/lib/pact_broker/api.rb +7 -3
  19. data/lib/pact_broker/config/runtime_configuration_database_methods.rb +1 -1
  20. data/lib/pact_broker/date_helper.rb +0 -4
  21. data/lib/pact_broker/domain/pact.rb +1 -1
  22. data/lib/pact_broker/domain/version.rb +7 -0
  23. data/lib/pact_broker/locale/en.yml +3 -0
  24. data/lib/pact_broker/matrix/quick_row.rb +11 -9
  25. data/lib/pact_broker/matrix/repository.rb +6 -5
  26. data/lib/pact_broker/matrix/unresolved_selector.rb +1 -0
  27. data/lib/pact_broker/pacticipants/find_potential_duplicate_pacticipant_names.rb +1 -4
  28. data/lib/pact_broker/pacts/pacts_for_verification_repository.rb +19 -3
  29. data/lib/pact_broker/pacts/selector.rb +4 -4
  30. data/lib/pact_broker/pacts/verifiable_pact.rb +5 -1
  31. data/lib/pact_broker/repositories/helpers.rb +1 -1
  32. data/lib/pact_broker/string_refinements.rb +9 -0
  33. data/lib/pact_broker/ui/controllers/base_controller.rb +8 -0
  34. data/lib/pact_broker/ui/controllers/can_i_deploy.rb +1 -1
  35. data/lib/pact_broker/ui/controllers/matrix.rb +1 -1
  36. data/lib/pact_broker/ui/views/dashboard/show.haml +30 -12
  37. data/lib/pact_broker/ui/views/matrix/show.haml +8 -8
  38. data/lib/pact_broker/version.rb +1 -1
  39. data/lib/pact_broker/versions/branch.rb +4 -0
  40. data/lib/pact_broker/versions/branch_service.rb +10 -0
  41. data/lib/pact_broker/versions/repository.rb +8 -0
  42. data/lib/pact_broker/versions/service.rb +4 -0
  43. data/lib/sequel/plugins/upsert.rb +1 -1
  44. data/lib/webmachine/describe_routes.rb +24 -2
  45. data/vendor/hal-browser/js/hal/views/embedded_resource.js +1 -1
  46. metadata +12 -9
  47. data/lib/pact_broker/api/resources/can_i_deploy_badge.rb +0 -85
  48. data/lib/pact_broker/api/resources/can_i_deploy_pacticipant_version.rb +0 -45
  49. data/public/bootstrap.zip +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 945a04d666baecd644bffd53da2de97fad0af2cc6c1170ed7dabaa657ef71184
4
- data.tar.gz: 1eec76fd7c899f5547e3cd6c937589c0976c98642ee2d33be753cb4739e2ab61
3
+ metadata.gz: e077e361037618a0d58670de46b25753d8755cb1e21ef58e9f73a8fe5705cd7f
4
+ data.tar.gz: 0e64d6fee6eb4cf36f69dea5bf94c432c088c93984ca51783e68f20b7b2e3130
5
5
  SHA512:
6
- metadata.gz: 5877ebb9cf131b6c8897c39c639e279daa5d785e252184f2cffbbd5376e18ae9936f11bcb879e08745ec63f00f5c4d65b4bc77ef1f93d64c5193c3b86810534c
7
- data.tar.gz: 2ed197a1ee3e6050688ed6074149210b7a8188fa3e60b68c12155f4b26eb3fe5def95ae4e13bc994f42a802b93540738240b59119b51b59bd2bfee3f9d030940
6
+ metadata.gz: 8c7bbae3ff3736576977f15aaef79a3d6635667de76b994a83c8c4613ce7fa9999808af70838014f7b5d7c26e7ffbda5da5e5813b1394dd6c4557fe597c9a11f
7
+ data.tar.gz: 4783820b31a355a9c2bf9a36151cc0730dba2a1424a1c68b8da39ac1f658cec3334b18c406b58d1b211cb0a5f3cc72b14a619066ca9d0c2daca828720f144d08
data/CHANGELOG.md CHANGED
@@ -1,3 +1,45 @@
1
+ <a name="v2.95.0"></a>
2
+ ### v2.95.0 (2022-03-16)
3
+
4
+ #### Features
5
+
6
+ * add relation for can-i-deploy branch to environment badge ([6ece8e93](/../../commit/6ece8e93))
7
+ * add badge url for 'can I deploy latest version of branch to envionment' endpoint ([086b8c10](/../../commit/086b8c10))
8
+
9
+ #### Bug Fixes
10
+
11
+ * **pacts for verification**
12
+ * do not de-duplicate pacts with the same content but different consumers ([ae3bb541](/../../commit/ae3bb541))
13
+
14
+ <a name="v2.94.0"></a>
15
+ ### v2.94.0 (2022-02-22)
16
+
17
+ #### Features
18
+
19
+ * add can-i-deploy endpoint for checking if the latest version for a branch can be deployed to a particular environment ([34b145e8](/../../commit/34b145e8))
20
+ * truncate tags, branches and versions in UI when they are super long (#513) ([94bbf915](/../../commit/94bbf915))
21
+
22
+ * **integration dashboard**
23
+ * add copy buttons next to the branch, tag and environment labels ([5b86ac88](/../../commit/5b86ac88))
24
+
25
+ #### Bug Fixes
26
+
27
+ * Improve Matrix request performance (#537) ([123f8629](/../../commit/123f8629))
28
+ * Eagerly load pact publication fields (#536) ([c3f6993b](/../../commit/c3f6993b))
29
+
30
+ * **hal-browser**
31
+ * properties accordion should be collapsed by default (#544) ([19466121](/../../commit/19466121))
32
+
33
+ <a name="v2.93.4"></a>
34
+ ### v2.93.4 (2022-02-21)
35
+
36
+ #### Bug Fixes
37
+
38
+ * **matrix page**
39
+ * set correct base URL for links when a path is specified in the base URL ([8305456b](/../../commit/8305456b))
40
+
41
+ * handle DateTimes that come back from Sqlite as Strings ([1312a049](/../../commit/1312a049))
42
+
1
43
  <a name="v2.93.3"></a>
2
44
  ### v2.93.3 (2022-02-02)
3
45
 
data/README.md CHANGED
@@ -140,15 +140,14 @@ You can use the [Pact Broker Docker image][docker] or [Terraform on AWS][terrafo
140
140
  #### Rolling your own
141
141
 
142
142
  * Are you sure you don't just want to use the [Pact Broker Docker image][docker]? No Docker at your company yet? Ah well, keep reading.
143
- * Create a PostgreSQL (recommended) or MySQL (not _as_ recommended because of @bethesque's personal prejudices, but still fully supported) database.
144
- * To ensure you're on a supported version of the database that you choose, check the [travis.yml][travisyml] file to see which versions we're currently running our tests against.
145
- * If you're using PostgreSQL (did we mention this was _recommended!_) you'll find the database creation script in the [example/config.ru](https://github.com/pact-foundation/pact_broker/blob/master/example/config.ru).
146
- * Install ruby 2.4 or later and the latest version of bundler (if you've come this far, I'm assuming you know how to do both of these. Did I mention there was a [Docker][docker] image?)
143
+ * Create a PostgreSQL database.
144
+ * To ensure you're on a supported version of the database that you choose, check the [travis.yml][travisyml] file to see which versions we're currently running our tests against.
145
+ * MySQL was supported for the native Ruby application until around 2021, but the official `pactfoundation/pact-broker` Docker image does not support it. New features will not be optimised for MySQL, and some new features may not even be supported on it (eg. the database clean feature).
146
+ * You'll find a sample database creation script in the [example/config.ru](https://github.com/pact-foundation/pact_broker/blob/master/example/config.ru).
147
+ * Install ruby 2.7 or later and the latest version of bundler (if you've come this far, I'm assuming you know how to do both of these. Did I mention there was a [Docker][docker] image?)
147
148
  * Copy the [pact\_broker](https://github.com/DiUS/pact_broker-docker/tree/master/pact_broker) directory from the Pact Broker Docker project. This will have the recommended settings for database connections, logging, basic auth etc. Note that the Docker image uses Phusion Passenger as the web application server in front of the Pact Broker Ruby application, which is the recommended set up.
148
- * Modify the config.ru and Gemfile as desired (eg. choose database driver gem, set your database credentials. Use the "pg" gem if using Postgres and the "mysql2" gem if using MySQL)
149
- * example Sequel configuration for postgres `{adapter: "postgres", database: "pact_broker", username: 'pact_broker', password: 'pact_broker', :encoding => 'utf8'}`
150
- * example Sequel configuration for mysql `{adapter: "mysql2", database: "pact_broker", username: 'pact_broker', password: 'pact_broker', :encoding => 'utf8'}`
151
- `
149
+ * Modify the config.ru and Gemfile as desired (eg. choose database driver gem, set your database credentials. Use the "pg" gem for Postgres)
150
+ * example Sequel configuration for postgres `{ adapter: "postgres", database: "pact_broker", username: 'pact_broker', password: 'pact_broker', :encoding => 'utf8' }`
152
151
  * Please ensure you use `encoding: 'utf8'` in your Sequel options to avoid encoding issues.
153
152
  * For production usage, use a web application server like [Phusion Passenger](https://www.phusionpassenger.com) or [Nginx](http://nginx.org/) to serve the Pact Broker application. You'll need to read up on the documentation for these yourself as it is beyond the scope of this documentation. See the [wiki][reverse-proxy-docs] for instructions on using a reverse proxy with SSL.
154
153
  * Ensure the environment variable `RACK_ENV` is set to `production`.
@@ -0,0 +1,14 @@
1
+ require_relative "migration_helper"
2
+ include PactBroker::MigrationHelper
3
+
4
+ Sequel.migration do
5
+ up do
6
+ if mysql?
7
+ run("ALTER TABLE verifications CHANGE consumer_version_selector_hashes consumer_version_selector_hashes mediumtext")
8
+ end
9
+ end
10
+
11
+ down do
12
+
13
+ end
14
+ end
@@ -23,7 +23,7 @@ module PactBroker
23
23
  end
24
24
 
25
25
  def postgres?
26
- adapter == "postgres"
26
+ adapter =~ /postgres/
27
27
  end
28
28
 
29
29
  def adapter
data/lib/db.rb CHANGED
@@ -71,7 +71,7 @@ module DB
71
71
  end
72
72
 
73
73
  def self.postgres?
74
- !!(PACT_BROKER_DB.adapter_scheme.to_s == "postgres")
74
+ !!(PACT_BROKER_DB.adapter_scheme.to_s =~ /postgres/)
75
75
  end
76
76
 
77
77
  PACT_BROKER_DB ||= connection_for_env ENV.fetch("RACK_ENV")
@@ -38,11 +38,7 @@ module PactBroker
38
38
  ]
39
39
 
40
40
  if enable_public_badge_access
41
- rules.concat([
42
- [PUBLIC, READ_METHODS, PACT_BADGE_PATH],
43
- [PUBLIC, READ_METHODS, MATRIX_BADGE_PATH],
44
- [PUBLIC, READ_METHODS, CAN_I_DEPLOY_BADGE_PATH]
45
- ])
41
+ rules.concat(BADGE_PATHS.collect { | badge_path | [PUBLIC, READ_METHODS, badge_path] })
46
42
  end
47
43
 
48
44
  if allow_public_access_to_heartbeat
@@ -2,8 +2,16 @@ module PactBroker
2
2
  module Api
3
3
  module Decorators
4
4
  module FormatDateTime
5
+ # Keep this in sync with Sequel.datetime_class.
6
+ # Needs to be upgraded from DateTime to Time as Time is deprecated
7
+ DATE_TIME_CLASS = DateTime
8
+
5
9
  def self.call(date_time)
6
- date_time.to_time.utc.to_datetime.xmlschema if date_time
10
+ if date_time.is_a?(String)
11
+ Sequel.string_to_datetime(date_time).to_time.utc.to_datetime.xmlschema
12
+ elsif date_time
13
+ date_time.to_time.utc.to_datetime.xmlschema if date_time
14
+ end
7
15
  end
8
16
 
9
17
  def format_date_time(date_time)
@@ -90,6 +90,14 @@ module PactBroker
90
90
  }
91
91
  end
92
92
 
93
+ link :'pb:can-i-deploy-branch-to-environment-badge' do | options |
94
+ {
95
+ title: "Can I Deploy #{represented.name} from branch to environment badge",
96
+ href: templated_can_i_deploy_branch_to_environment_badge_url(represented.name, options[:base_url]),
97
+ templated: true
98
+ }
99
+ end
100
+
93
101
  curies do | options |
94
102
  [{
95
103
  name: :pb,
@@ -255,6 +255,10 @@ module PactBroker
255
255
  templated_can_i_deploy_url(pacticipant_name, base_url) + "/badge"
256
256
  end
257
257
 
258
+ def templated_can_i_deploy_branch_to_environment_badge_url pacticipant_name, base_url = ""
259
+ pacticipant_url_from_params({ pacticipant_name: pacticipant_name }, base_url) + "/branches/{branch}/latest-version/can-i-deploy/to-environment/{environment}/badge"
260
+ end
261
+
258
262
  def label_url label, base_url
259
263
  "#{labels_url(label.pacticipant, base_url)}/#{url_encode(label.name)}"
260
264
  end
@@ -3,9 +3,12 @@ module PactBroker
3
3
  module Paths
4
4
  PACT_BADGE_PATH = %r{^/pacts/provider/[^/]+/consumer/.*/badge(?:\.[A-Za-z]+)?$}.freeze
5
5
  MATRIX_BADGE_PATH = %r{^/matrix/provider/[^/]+/latest/[^/]+/consumer/[^/]+/latest/[^/]+/badge(?:\.[A-Za-z]+)?$}.freeze
6
- CAN_I_DEPLOY_BADGE_PATH = %r{^/pacticipants/[^/]+/latest-version/[^/]+/can-i-deploy/to/[^/]+/badge(?:\.[A-Za-z]+)?$}.freeze
6
+ CAN_I_DEPLOY_TAG_BADGE_PATH = %r{^/pacticipants/[^/]+/latest-version/[^/]+/can-i-deploy/to/[^/]+/badge(?:\.[A-Za-z]+)?$}.freeze
7
+ CAN_I_DEPLOY_BRANCH_ENV_BADGE_PATH = %r{^/pacticipants/[^/]+/branches/[^/]+/latest-version/can-i-deploy/to-environment/[^/]+/badge(?:\.[A-Za-z]+)?$}.freeze
7
8
  VERIFICATION_RESULTS = %r{^/pacts/provider/[^/]+/consumer/[^/]+/pact-version/[^/]+/verification-results/[^/]+}
8
9
 
10
+ BADGE_PATHS = [PACT_BADGE_PATH, MATRIX_BADGE_PATH, CAN_I_DEPLOY_TAG_BADGE_PATH, CAN_I_DEPLOY_BRANCH_ENV_BADGE_PATH]
11
+
9
12
  extend self
10
13
 
11
14
  def is_verification_results_path?(path)
@@ -14,7 +17,7 @@ module PactBroker
14
17
 
15
18
  def is_badge_path?(path)
16
19
  # Optimise by checking include? first - regexp slow
17
- path.include?("/badge") && (path =~ PACT_BADGE_PATH || path =~ MATRIX_BADGE_PATH || path =~ CAN_I_DEPLOY_BADGE_PATH)
20
+ path.include?("/badge") && BADGE_PATHS.any?{ | regex | path =~ regex }
18
21
  end
19
22
  end
20
23
  end
@@ -1,37 +1,22 @@
1
1
  require "pact_broker/api/resources/base_resource"
2
2
  require "pact_broker/verifications/pseudo_branch_status"
3
3
  require "pact_broker/configuration"
4
+ require "pact_broker/api/resources/badge_methods"
4
5
 
5
6
  module PactBroker
6
7
  module Api
7
8
  module Resources
8
9
  class Badge < BaseResource
9
-
10
- def allowed_methods
11
- ["GET", "OPTIONS"]
12
- end
13
-
14
- def content_types_provided
15
- [["image/svg+xml", :to_svg]]
16
- end
10
+ include BadgeMethods
17
11
 
18
12
  def resource_exists?
19
13
  !badge_service.can_provide_badge_using_redirect?
20
14
  end
21
15
 
22
- # Only called if resource_exists? returns false
23
- def previously_existed?
24
- true
25
- end
26
-
27
16
  def is_authorized?(authorization_header)
28
17
  super || PactBroker.configuration.enable_public_badge_access
29
18
  end
30
19
 
31
- def forbidden?
32
- false
33
- end
34
-
35
20
  def to_svg
36
21
  response.headers["Cache-Control"] = "no-cache"
37
22
  comment + badge_service.pact_verification_badge(pact, label, initials, pseudo_branch_verification_status, tags)
@@ -42,10 +27,6 @@ module PactBroker
42
27
  badge_service.pact_verification_badge_url(pact, label, initials, pseudo_branch_verification_status, tags)
43
28
  end
44
29
 
45
- def policy_name
46
- :'badges::badge'
47
- end
48
-
49
30
  private
50
31
 
51
32
  def pact
@@ -61,10 +42,6 @@ module PactBroker
61
42
  @pseudo_branch_verification_status ||= PactBroker::Verifications::PseudoBranchStatus.new(pact, latest_verification).to_sym
62
43
  end
63
44
 
64
- def label
65
- request.query["label"]
66
- end
67
-
68
45
  def initials
69
46
  request.query["initials"] == "true"
70
47
  end
@@ -0,0 +1,57 @@
1
+ module PactBroker
2
+ module Api
3
+ module Resources
4
+ module BadgeMethods
5
+ def allowed_methods
6
+ ["GET", "OPTIONS"]
7
+ end
8
+
9
+ def content_types_provided
10
+ [["image/svg+xml", :to_svg]]
11
+ end
12
+
13
+ def resource_exists?
14
+ false
15
+ end
16
+
17
+ # Only called if resource_exists? returns false
18
+ def previously_existed?
19
+ true
20
+ end
21
+
22
+ def forbidden?
23
+ false
24
+ end
25
+
26
+ def is_authorized?(authorization_header)
27
+ super || PactBroker.configuration.enable_public_badge_access
28
+ end
29
+
30
+ def policy_name
31
+ :'badges::badge'
32
+ end
33
+
34
+ def moved_temporarily?
35
+ response.headers["Cache-Control"] = "no-cache"
36
+ begin
37
+ badge_url
38
+ rescue StandardError => e
39
+ # Want to render a badge, even if there's an error
40
+ badge_service.error_badge_url("error", ErrorResponseBodyGenerator.display_message(e, "reference: #{PactBroker::Errors.generate_error_reference}"))
41
+ end
42
+ end
43
+
44
+ def badge_url
45
+ raise NotImplementedError
46
+ end
47
+
48
+ private
49
+
50
+ def label
51
+ lab = request.query["label"]
52
+ lab && !lab.empty? ? lab : nil
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,67 @@
1
+ require "pact_broker/api/resources/matrix"
2
+ require "pact_broker/matrix/can_i_deploy_query_schema"
3
+ require "pact_broker/matrix/parse_can_i_deploy_query"
4
+ require "pact_broker/api/decorators/matrix_decorator"
5
+ require "pact_broker/api/decorators/matrix_text_decorator"
6
+
7
+ module PactBroker
8
+ module Api
9
+ module Resources
10
+ class CanIDeployPacticipantVersionByBranchToEnvironment < BaseResource
11
+ def allowed_methods
12
+ ["GET", "OPTIONS"]
13
+ end
14
+
15
+ def content_types_provided
16
+ [
17
+ ["application/hal+json", :to_json],
18
+ ["text/plain", :to_text]
19
+ ]
20
+ end
21
+
22
+ def resource_exists?
23
+ !!(version && environment)
24
+ end
25
+
26
+ def policy_name
27
+ :'versions::version'
28
+ end
29
+
30
+ private
31
+
32
+ def selectors
33
+ @selectors ||= [
34
+ PactBroker::Matrix::UnresolvedSelector.new(
35
+ pacticipant_name: pacticipant_name,
36
+ latest: true,
37
+ branch: identifier_from_path[:branch_name]
38
+ )
39
+ ]
40
+ end
41
+
42
+ def options
43
+ @options ||= {
44
+ latestby: "cvp",
45
+ environment_name: identifier_from_path[:environment_name]
46
+ }
47
+ end
48
+
49
+ def to_json
50
+ decorator_class(:matrix_decorator).new(results).to_json(decorator_options)
51
+ end
52
+
53
+ def results
54
+ @results ||= matrix_service.can_i_deploy(selectors, options)
55
+ end
56
+
57
+ def version
58
+ @version ||= version_service.find_latest_by_pacticipant_name_and_branch_name(identifier_from_path[:pacticipant_name], identifier_from_path[:branch_name])
59
+ end
60
+
61
+ def environment
62
+ @environment ||= environment_service.find_by_name(identifier_from_path[:environment_name])
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,29 @@
1
+ require "pact_broker/api/resources/can_i_deploy_pacticipant_version_by_branch_to_environment"
2
+
3
+ module PactBroker
4
+ module Api
5
+ module Resources
6
+ class CanIDeployPacticipantVersionByBranchToEnvironmentBadge < CanIDeployPacticipantVersionByBranchToEnvironment
7
+ include BadgeMethods
8
+
9
+ private
10
+
11
+ def badge_url
12
+ if pacticipant && version && environment
13
+ badge_service.can_i_deploy_badge_url(identifier_from_path[:branch_name], identifier_from_path[:environment_name], label, results.deployable?)
14
+ elsif pacticipant.nil?
15
+ badge_service.error_badge_url("pacticipant", "not found")
16
+ elsif version.nil?
17
+ if branch_service.find_branch(identifier_from_path.slice(:pacticipant_name, :branch_name)).nil?
18
+ badge_service.error_badge_url("branch", "not found")
19
+ else
20
+ badge_service.error_badge_url("version", "not found")
21
+ end
22
+ else
23
+ badge_service.error_badge_url("environment", "not found")
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,48 @@
1
+ require "pact_broker/api/resources/matrix"
2
+ require "pact_broker/matrix/can_i_deploy_query_schema"
3
+ require "pact_broker/matrix/parse_can_i_deploy_query"
4
+
5
+ module PactBroker
6
+ module Api
7
+ module Resources
8
+ class CanIDeployPacticipantVersionByTagToTag < Matrix
9
+ def resource_exists?
10
+ !!version
11
+ end
12
+
13
+ def policy_name
14
+ :'versions::version'
15
+ end
16
+
17
+ def malformed_request?
18
+ false
19
+ end
20
+
21
+ private
22
+
23
+ def selectors
24
+ @selectors ||= [
25
+ PactBroker::Matrix::UnresolvedSelector.new(
26
+ pacticipant_name: pacticipant_name,
27
+ latest: true,
28
+ tag: identifier_from_path[:tag],
29
+ )
30
+ ]
31
+
32
+ end
33
+
34
+ def options
35
+ @options ||= {
36
+ latestby: "cvp",
37
+ latest: true,
38
+ tag: identifier_from_path[:to]
39
+ }
40
+ end
41
+
42
+ def version
43
+ @version ||= version_service.find_by_pacticipant_name_and_latest_tag(identifier_from_path[:pacticipant_name], identifier_from_path[:tag])
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,25 @@
1
+ require "pact_broker/matrix/can_i_deploy_query_schema"
2
+ require "pact_broker/matrix/parse_can_i_deploy_query"
3
+ require "pact_broker/api/resources/badge_methods"
4
+
5
+ module PactBroker
6
+ module Api
7
+ module Resources
8
+ class CanIDeployPacticipantVersionByTagToTagBadge < CanIDeployPacticipantVersionByTagToTag
9
+ include BadgeMethods
10
+
11
+ def badge_url
12
+ if pacticipant
13
+ if version
14
+ badge_service.can_i_deploy_badge_url(identifier_from_path[:tag], identifier_from_path[:to], label, results.deployable?)
15
+ else
16
+ badge_service.error_badge_url("version", "not found")
17
+ end
18
+ else
19
+ badge_service.error_badge_url("pacticipant", "not found")
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -81,15 +81,19 @@ module PactBroker
81
81
  add ["pacticipants"], Api::Resources::Pacticipants, {resource_name: "pacticipants"}
82
82
  add ["pacticipants", "label", :label_name], PactBroker::Api::Resources::PacticipantsForLabel, {resource_name: "pacticipants_for_label"}
83
83
  add ["pacticipants", :pacticipant_name], Api::Resources::Pacticipant, {resource_name: "pacticipant"}
84
+ add ["pacticipants", :pacticipant_name, "labels", :label_name], Api::Resources::Label, {resource_name: "pacticipant_label"}
85
+
86
+ # Versions
84
87
  add ["pacticipants", :pacticipant_name, "versions"], Api::Resources::Versions, {resource_name: "pacticipant_versions"}
85
88
  add ["pacticipants", :pacticipant_name, "versions", :pacticipant_version_number], Api::Resources::Version, {resource_name: "pacticipant_version"}
86
89
  add ["pacticipants", :pacticipant_name, "latest-version", :tag], Api::Resources::LatestVersion, {resource_name: "latest_tagged_pacticipant_version"}
87
- add ["pacticipants", :pacticipant_name, "latest-version", :tag, "can-i-deploy", "to", :to], Api::Resources::CanIDeployPacticipantVersion, { resource_name: "can_i_deploy_latest_tagged_version" }
88
- add ["pacticipants", :pacticipant_name, "latest-version", :tag, "can-i-deploy", "to", :to, "badge"], Api::Resources::CanIDeployBadge, { resource_name: "can_i_deploy_badge" }
90
+ add ["pacticipants", :pacticipant_name, "latest-version", :tag, "can-i-deploy", "to", :to], Api::Resources::CanIDeployPacticipantVersionByTagToTag, { resource_name: "can_i_deploy_latest_tagged_version_to_tag" }
91
+ add ["pacticipants", :pacticipant_name, "latest-version", :tag, "can-i-deploy", "to", :to, "badge"], Api::Resources::CanIDeployPacticipantVersionByTagToTagBadge, { resource_name: "can_i_deploy_latest_tagged_version_to_tag_badge" }
89
92
  add ["pacticipants", :pacticipant_name, "latest-version"], Api::Resources::LatestVersion, {resource_name: "latest_pacticipant_version"}
90
93
  add ["pacticipants", :pacticipant_name, "versions", :pacticipant_version_number, "tags", :tag_name], Api::Resources::Tag, {resource_name: "pacticipant_version_tag"}
91
- add ["pacticipants", :pacticipant_name, "labels", :label_name], Api::Resources::Label, {resource_name: "pacticipant_label"}
92
94
  add ["pacticipants", :pacticipant_name, "branches", :branch_name, "versions", :version_number], Api::Resources::BranchVersion, { resource_name: "branch_version" }
95
+ add ["pacticipants", :pacticipant_name, "branches", :branch_name, "latest-version", "can-i-deploy", "to-environment", :environment_name], Api::Resources::CanIDeployPacticipantVersionByBranchToEnvironment, { resource_name: "can_i_deploy_latest_branch_version_to_environment" }
96
+ add ["pacticipants", :pacticipant_name, "branches", :branch_name, "latest-version", "can-i-deploy", "to-environment", :environment_name, "badge"], Api::Resources::CanIDeployPacticipantVersionByBranchToEnvironmentBadge, { resource_name: "can_i_deploy_latest_branch_version_to_environment_badge" }
93
97
 
94
98
  # Webhooks
95
99
  add ["webhooks", "provider", :provider_name, "consumer", :consumer_name ], Api::Resources::PacticipantWebhooks, {resource_name: "pacticipant_webhooks"}
@@ -72,7 +72,7 @@ module PactBroker
72
72
  end
73
73
 
74
74
  def postgres?
75
- database_credentials[:adapter] == "postgres"
75
+ database_credentials[:adapter] =~ /postgres/
76
76
  end
77
77
  private :postgres?
78
78
 
@@ -4,7 +4,6 @@ module PactBroker
4
4
  extend self
5
5
 
6
6
  # Ripped from actionview/lib/action_view/helpers/date_helper.rb
7
-
8
7
  def local_date_in_words datetime
9
8
  datetime.to_time.localtime.to_datetime.strftime("%a %d %b %Y, %l:%M%P %:z").gsub(" ", " ")
10
9
  end
@@ -31,9 +30,6 @@ module PactBroker
31
30
  distance_in_minutes = ((to_time - from_time)/60.0).round
32
31
  distance_in_seconds = (to_time - from_time).round
33
32
 
34
- # require 'pry'; pry(binding);
35
-
36
- # locale = I18n.with_options :locale => options[:locale], :scope => options[:scope]
37
33
  locale = Locale.new(:locale => options[:locale], :scope => options[:scope])
38
34
  case distance_in_minutes
39
35
  when 0..1
@@ -41,7 +41,7 @@ module PactBroker
41
41
  end
42
42
 
43
43
  def consumer
44
- consumer_version.pacticipant
44
+ @consumer || consumer_version.pacticipant
45
45
  end
46
46
 
47
47
  def consumer_version_tag_names
@@ -241,6 +241,13 @@ module PactBroker
241
241
  end
242
242
  # rubocop: enable Metrics/CyclomaticComplexity
243
243
 
244
+ def pacticipants_set
245
+ from_self(alias: :v)
246
+ .select_group(Sequel[:v][:pacticipant_id])
247
+ .collect(&:pacticipant_id)
248
+ .to_set
249
+ end
250
+
244
251
  # private
245
252
 
246
253
  def calculate_max_version_order_and_join_back_to_versions(query, selector)
@@ -124,6 +124,9 @@ en:
124
124
  datetime:
125
125
  distance_in_words:
126
126
  half_a_minute: "half a minute"
127
+ less_than_x_minutes:
128
+ one: "less than 1 minute"
129
+ other: "less than %{count} minutes"
127
130
  less_than_x_seconds:
128
131
  one: "less than 1 second"
129
132
  other: "less than %{count} seconds"
@@ -124,15 +124,17 @@ module PactBroker
124
124
  end
125
125
 
126
126
  def eager_all_the_things
127
- eager(:consumer)
128
- .eager(:provider)
129
- .eager(consumer_version: [{ current_deployed_versions: :environment }, { current_supported_released_versions: :environment }, { branch_versions: :branch_head }])
130
- .eager(provider_version: [{ current_deployed_versions: :environment }, { current_supported_released_versions: :environment }, { branch_versions: :branch_head }])
131
- .eager(:verification)
132
- .eager(:pact_publication)
133
- .eager(:pact_version)
134
- .eager(:consumer_version_tags)
135
- .eager(:provider_version_tags)
127
+ eager(
128
+ :consumer,
129
+ :provider,
130
+ :verification,
131
+ :pact_publication,
132
+ :pact_version,
133
+ consumer_version: { current_deployed_versions: :environment, current_supported_released_versions: :environment, branch_versions: [:branch_head, :version, branch: :pacticipant] },
134
+ provider_version: { current_deployed_versions: :environment, current_supported_released_versions: :environment, branch_versions: [:branch_head, :version, branch: :pacticipant] },
135
+ consumer_version_tags: { version: :pacticipant },
136
+ provider_version_tags: { version: :pacticipant }
137
+ )
136
138
  end
137
139
 
138
140
  def default_scope
@@ -127,20 +127,19 @@ module PactBroker
127
127
  def integrations_where_specified_selector_is_provider(resolved_specified_selectors, options)
128
128
  integrations_involving_specified_providers = PactBroker::Integrations::Integration
129
129
  .where(provider_id: resolved_specified_selectors.collect(&:pacticipant_id))
130
- .eager(:consumer)
130
+ .eager(:consumer, :provider)
131
131
  .all
132
132
 
133
133
  destination_selector = PactBroker::Matrix::UnresolvedSelector.new(options.slice(:latest, :tag, :branch, :environment_name).compact)
134
+ required = PactBroker::Domain::Version.for_selector(destination_selector).pacticipants_set
134
135
 
135
136
  integrations_involving_specified_providers.collect do | integration |
136
- required = PactBroker::Domain::Version.where(pacticipant: integration.consumer).for_selector(destination_selector).any?
137
-
138
137
  Integration.from_hash(
139
138
  consumer_id: integration.consumer.id,
140
139
  consumer_name: integration.consumer.name,
141
140
  provider_id: integration.provider.id,
142
141
  provider_name: integration.provider.name,
143
- required: required
142
+ required: required.member?(integration.consumer.id)
144
143
  )
145
144
  end
146
145
  end
@@ -221,8 +220,10 @@ module PactBroker
221
220
 
222
221
  # Find the version number for selectors with the latest and/or tag specified
223
222
  def resolve_versions_and_add_ids(unresolved_selectors, selector_type, resolved_ignore_selectors = [])
223
+ names = unresolved_selectors.collect(&:pacticipant_name)
224
+ pacticipants = PactBroker::Domain::Pacticipant.where(name: names).to_a.group_by(&:name).transform_values(&:first)
224
225
  unresolved_selectors.collect do | unresolved_selector |
225
- pacticipant = PactBroker::Domain::Pacticipant.find(name: unresolved_selector.pacticipant_name)
226
+ pacticipant = pacticipants[unresolved_selector.pacticipant_name]
226
227
  if pacticipant
227
228
  versions = find_versions_for_selector(unresolved_selector)
228
229
  build_resolved_selectors(pacticipant, versions, unresolved_selector, selector_type, resolved_ignore_selectors)