pact_broker 2.63.0 → 2.68.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (101) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +62 -0
  3. data/Gemfile +1 -0
  4. data/db/ddl_statements/latest_triggered_webhooks.rb +66 -0
  5. data/db/migrations/20180119_update_latest_triggered_webhooks.rb +5 -39
  6. data/db/migrations/20200930_update_latest_triggered_webhooks.rb +15 -0
  7. data/db/migrations/20201006_add_wip_to_verification.rb +5 -0
  8. data/db/migrations/20201023_create_verification_number_sequence.rb +20 -0
  9. data/db/migrations/20201024_create_version_order_sequence.rb +20 -0
  10. data/db/migrations/migration_helper.rb +10 -2
  11. data/lib/db.rb +7 -1
  12. data/lib/pact_broker/api.rb +1 -0
  13. data/lib/pact_broker/api/decorators/decorator_context.rb +2 -2
  14. data/lib/pact_broker/api/decorators/pagination_links.rb +34 -0
  15. data/lib/pact_broker/api/decorators/verifiable_pact_decorator.rb +4 -2
  16. data/lib/pact_broker/api/decorators/versions_decorator.rb +5 -1
  17. data/lib/pact_broker/api/pact_broker_urls.rb +23 -7
  18. data/lib/pact_broker/api/paths.rb +4 -3
  19. data/lib/pact_broker/api/resources/can_i_deploy.rb +14 -0
  20. data/lib/pact_broker/api/resources/can_i_deploy_badge.rb +1 -1
  21. data/lib/pact_broker/api/resources/can_i_deploy_pacticipant_version.rb +40 -0
  22. data/lib/pact_broker/api/resources/group.rb +0 -1
  23. data/lib/pact_broker/api/resources/index.rb +5 -0
  24. data/lib/pact_broker/api/resources/label.rb +0 -1
  25. data/lib/pact_broker/api/resources/latest_pact.rb +1 -1
  26. data/lib/pact_broker/api/resources/pact.rb +8 -0
  27. data/lib/pact_broker/api/resources/pact_versions.rb +4 -0
  28. data/lib/pact_broker/api/resources/pact_webhooks.rb +1 -1
  29. data/lib/pact_broker/api/resources/provider_pacts_for_verification.rb +10 -1
  30. data/lib/pact_broker/api/resources/tag.rb +0 -1
  31. data/lib/pact_broker/api/resources/tagged_pact_versions.rb +4 -0
  32. data/lib/pact_broker/api/resources/verification.rb +4 -0
  33. data/lib/pact_broker/api/resources/verifications.rb +14 -2
  34. data/lib/pact_broker/api/resources/versions.rb +12 -1
  35. data/lib/pact_broker/app.rb +2 -2
  36. data/lib/pact_broker/badges/service.rb +3 -3
  37. data/lib/pact_broker/db/clean.rb +100 -43
  38. data/lib/pact_broker/doc/views/integrations.markdown +5 -1
  39. data/lib/pact_broker/doc/views/pacticipant/versions.markdown +9 -0
  40. data/lib/pact_broker/domain/pacticipant.rb +4 -0
  41. data/lib/pact_broker/domain/tag.rb +2 -0
  42. data/lib/pact_broker/domain/version.rb +1 -0
  43. data/lib/pact_broker/feature_toggle.rb +8 -4
  44. data/lib/pact_broker/groups/service.rb +0 -3
  45. data/lib/pact_broker/locale/en.yml +1 -0
  46. data/lib/pact_broker/matrix/aggregated_row.rb +1 -0
  47. data/lib/pact_broker/matrix/deployment_status_summary.rb +1 -1
  48. data/lib/pact_broker/matrix/query_results_with_deployment_status_summary.rb +1 -0
  49. data/lib/pact_broker/matrix/service.rb +3 -0
  50. data/lib/pact_broker/pacticipants/repository.rb +6 -5
  51. data/lib/pact_broker/pacticipants/service.rb +5 -18
  52. data/lib/pact_broker/pacts/all_pact_publications.rb +1 -0
  53. data/lib/pact_broker/pacts/latest_tagged_pact_publications.rb +15 -1
  54. data/lib/pact_broker/pacts/pact_publication.rb +1 -0
  55. data/lib/pact_broker/pacts/repository.rb +1 -0
  56. data/lib/pact_broker/pacts/verifiable_pact_messages.rb +7 -3
  57. data/lib/pact_broker/tags/repository.rb +2 -5
  58. data/lib/pact_broker/test/test_data_builder.rb +23 -3
  59. data/lib/pact_broker/ui/app.rb +6 -0
  60. data/lib/pact_broker/ui/controllers/can_i_deploy.rb +42 -0
  61. data/lib/pact_broker/ui/controllers/matrix.rb +3 -34
  62. data/lib/pact_broker/ui/helpers/matrix_helper.rb +40 -0
  63. data/lib/pact_broker/ui/views/matrix/show.haml +9 -1
  64. data/lib/pact_broker/verifications/repository.rb +16 -9
  65. data/lib/pact_broker/verifications/sequence.rb +21 -16
  66. data/lib/pact_broker/verifications/service.rb +2 -1
  67. data/lib/pact_broker/version.rb +1 -1
  68. data/lib/pact_broker/versions/sequence.rb +21 -17
  69. data/lib/pact_broker/webhooks/pact_and_verification_parameters.rb +1 -1
  70. data/spec/features/create_webhook_spec.rb +18 -0
  71. data/spec/features/get_versions_spec.rb +8 -0
  72. data/spec/features/wip_pacts_spec.rb +258 -33
  73. data/spec/fixtures/approvals/modifiable_resources.approved.json +74 -0
  74. data/spec/lib/pact_broker/api/decorators/relationships_csv_decorator_spec.rb +0 -3
  75. data/spec/lib/pact_broker/api/decorators/verifiable_pact_decorator_spec.rb +7 -2
  76. data/spec/lib/pact_broker/api/decorators/versions_decorator_spec.rb +14 -9
  77. data/spec/lib/pact_broker/api/pact_broker_urls_spec.rb +6 -5
  78. data/spec/lib/pact_broker/api/resources/can_i_deploy_badge_spec.rb +2 -2
  79. data/spec/lib/pact_broker/api/resources/can_i_deploy_pacticipant_version_spec.rb +31 -0
  80. data/spec/lib/pact_broker/api/resources/can_i_deploy_spec.rb +51 -0
  81. data/spec/lib/pact_broker/api/resources/default_base_resource_approval_spec.rb +59 -0
  82. data/spec/lib/pact_broker/api/resources/default_base_resource_spec.rb +17 -6
  83. data/spec/lib/pact_broker/api/resources/latest_pact_spec.rb +2 -2
  84. data/spec/lib/pact_broker/api/resources/verifications_spec.rb +17 -3
  85. data/spec/lib/pact_broker/badges/service_spec.rb +6 -0
  86. data/spec/lib/pact_broker/db/clean_spec.rb +72 -4
  87. data/spec/lib/pact_broker/db/delete_overwritten_data_spec.rb +1 -1
  88. data/spec/lib/pact_broker/feature_toggle_spec.rb +9 -1
  89. data/spec/lib/pact_broker/matrix/integration_spec.rb +1 -1
  90. data/spec/lib/pact_broker/pacticipants/repository_spec.rb +8 -1
  91. data/spec/lib/pact_broker/pacts/latest_tagged_pact_publications_spec.rb +99 -0
  92. data/spec/lib/pact_broker/pacts/repository_find_wip_pact_versions_for_provider_spec.rb +24 -2
  93. data/spec/lib/pact_broker/pacts/verifiable_pact_messages_spec.rb +12 -0
  94. data/spec/lib/pact_broker/ui/controllers/can_i_deploy_spec.rb +26 -0
  95. data/spec/lib/pact_broker/verifications/sequence_spec.rb +48 -22
  96. data/spec/lib/pact_broker/verifications/service_spec.rb +4 -2
  97. data/spec/lib/pact_broker/webhooks/render_spec.rb +1 -1
  98. data/spec/lib/pact_broker/webhooks/repository_spec.rb +20 -0
  99. data/spec/spec_helper.rb +5 -0
  100. data/tasks/database.rb +8 -0
  101. metadata +24 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 61338a93bd65ffa3ec70f4fdfd9b509a0d5c0608dce8cea3f779e3ac22151412
4
- data.tar.gz: 99819023ba051657020d314fe6d3005a04660d70467a57c5b5369a08a5525e2a
3
+ metadata.gz: '09772ac584dd72c870b97fcaf82485425a5c506f7ab0b8a30bc0ce23eb071484'
4
+ data.tar.gz: 34ae1ca468c7ebbecfb49570b9374be0db7792da67476ae46d73667c9323615c
5
5
  SHA512:
6
- metadata.gz: 7da446c51346413782377eb409c2d3159fcb322147d675324126243bfb8b115ff042d210b3cf25ee46ebe73093611e4de85db03f243c5ffb06299239d6aff637
7
- data.tar.gz: 6b191f39b782bf811d58e15d149fa5e786227e6a86d93c0f8888a6134b992d6f60ad58ff2b2b6cf84ba612b72368cf569471b9214b85f7ce173e18872e89ddec
6
+ metadata.gz: d9d3de22aee4d8d8f106c26fa2eec1148c5f5535d9b2fc34f33c26cb9ef67fa193eddf833865a041479fd4a67bb8be59fb06bb17f79117416575612c37301299
7
+ data.tar.gz: 73f0a9e7b14e74a9d685ff1039cf1650bf76f9b47ee863acf71a90dd81449684183c35797889c6682e95239c4f9f9bfd57de4050aef60d6a6521fd0a8a274189
@@ -1,3 +1,65 @@
1
+ <a name="v2.68.0"></a>
2
+ ### v2.68.0 (2020-10-23)
3
+
4
+ #### Features
5
+
6
+ * use a sequence for the version order on postgres ([da497a76](/../../commit/da497a76))
7
+ * only cascade apps for 404s (not 405s) ([4e1b3083](/../../commit/4e1b3083))
8
+ * use a sequence for the verification number on postgres ([b8f029ee](/../../commit/b8f029ee))
9
+ * optimise query to find latest verification for pact ([db17ef5a](/../../commit/db17ef5a))
10
+
11
+ <a name="v2.67.0"></a>
12
+ ### v2.67.0 (2020-10-16)
13
+
14
+ #### Features
15
+
16
+ * **wip pacts**
17
+ * if a pact was successfully verified because it was included as a WIP pact, keep it as WIP ([16cae55d](/../../commit/16cae55d))
18
+ * add 'wip' column to verification results ([34f98592](/../../commit/34f98592))
19
+
20
+ #### Bug Fixes
21
+
22
+ * typo when rendering created webhook for old webhooks path ([1e6a06a0](/../../commit/1e6a06a0))
23
+ * include can-i-deploy badge in is_badge_path? logic ([31ea5f34](/../../commit/31ea5f34))
24
+
25
+ * **pacts for verification**
26
+ * gracefully log empty request body ([0e48d13a](/../../commit/0e48d13a))
27
+
28
+ * **can-i-deploy**
29
+ * gracefully handle pacticipant not found ([f6903b23](/../../commit/f6903b23))
30
+
31
+ <a name="v2.66.0"></a>
32
+ ### v2.66.0 (2020-10-01)
33
+
34
+ #### Features
35
+
36
+ * paginate pacticipant versions ([f489ba7b](/../../commit/f489ba7b))
37
+
38
+ * **webhooks**
39
+ * add event name to group by clause when selecting latest triggered webhooks ([134f12c8](/../../commit/134f12c8))
40
+
41
+ #### Bug Fixes
42
+
43
+ * maintain latest and tag params when submitting page after following link from can-i-deploy debug logs ([6e2f1a85](/../../commit/6e2f1a85))
44
+
45
+ <a name="v2.65.0"></a>
46
+ ### v2.65.0 (2020-09-25)
47
+
48
+ #### Features
49
+
50
+ * **pacts for verification**
51
+ * allow API to be disabled by setting PACT_BROKER_FEATURES=disable_pacts_for_verification ([bab116b3](/../../commit/bab116b3))
52
+ * update wording for inclusion notice when selector has a consumer specified ([61370d1f](/../../commit/61370d1f))
53
+
54
+ <a name="v2.64.0"></a>
55
+ ### v2.64.0 (2020-09-25)
56
+
57
+ #### Features
58
+
59
+ * add API endpoint for can-i-deploy for latest tagged pacticipant version ([88fdc60a](/../../commit/88fdc60a))
60
+ * render matrix UI page for can-i-deploy endpoint ([463e9cfd](/../../commit/463e9cfd))
61
+ * change text on can-i-deploy badge ([f9e183e9](/../../commit/f9e183e9))
62
+
1
63
  <a name="v2.63.0"></a>
2
64
  ### v2.63.0 (2020-09-25)
3
65
 
data/Gemfile CHANGED
@@ -25,6 +25,7 @@ group :test do
25
25
  gem 'timecop', '~> 0.9'
26
26
  gem 'faraday', '~>0.15'
27
27
  gem 'docker-api', '~>1.34'
28
+ gem 'approvals', '>=0.0.1', '<1.0.0'
28
29
  end
29
30
 
30
31
  if ENV['INSTALL_MYSQL'] == "true"
@@ -0,0 +1,66 @@
1
+ # These views find the latest triggered webhook for each webhook/consumer/provider
2
+ # by finding the latest execution date for each webhook
3
+ # then taking the row with the max ID in case there there are two
4
+ # triggered webhooks for the same UUID and same creation date
5
+ # Not sure if this is strictly necessary to do the extra step, but better to be
6
+ # safe than sorry.
7
+ # I probably could just take the max ID for each webhook/consumer/provider, but
8
+ # something in my head says that
9
+ # relying on the primary key for order is not a good idea, even though
10
+ # according to the SQL it should be fine.
11
+ def latest_triggered_webhook_creation_dates_v2
12
+ "select webhook_uuid, consumer_id, provider_id, max(created_at) as latest_triggered_webhook_created_at
13
+ from triggered_webhooks
14
+ group by webhook_uuid, consumer_id, provider_id"
15
+ end
16
+
17
+ # Ignore ltwcd.latest_triggered_webhook_created_at, it's there because postgres doesn't allow you to modify
18
+ # the names and types of columns in a view
19
+ def latest_triggered_webhook_ids_v2
20
+ "select tw.webhook_uuid, tw.consumer_id, tw.provider_id, ltwcd.latest_triggered_webhook_created_at, max(tw.id) as latest_triggered_webhook_id
21
+ from latest_triggered_webhook_creation_dates ltwcd
22
+ inner join triggered_webhooks tw
23
+ on tw.consumer_id = ltwcd.consumer_id
24
+ and tw.provider_id = ltwcd.provider_id
25
+ and tw.webhook_uuid = ltwcd.webhook_uuid
26
+ and tw.created_at = ltwcd.latest_triggered_webhook_created_at
27
+ group by tw.webhook_uuid, tw.consumer_id, tw.provider_id, ltwcd.latest_triggered_webhook_created_at"
28
+ end
29
+
30
+ def latest_triggered_webhooks_v2
31
+ "select tw.*
32
+ from triggered_webhooks tw
33
+ inner join latest_triggered_webhook_ids ltwi
34
+ on tw.consumer_id = ltwi.consumer_id
35
+ and tw.provider_id = ltwi.provider_id
36
+ and tw.webhook_uuid = ltwi.webhook_uuid
37
+ and tw.id = ltwi.latest_triggered_webhook_id"
38
+ end
39
+
40
+ # use explicit columns - can't drop event_name in 20200922_add_event_to_triggered_webhook.rb
41
+ # if tw.* is used because you can't remove columns from a view in postgres
42
+ def latest_triggered_webhooks_v3_rollback(is_postgres)
43
+ if is_postgres
44
+ "select tw.id, tw.trigger_uuid, tw.trigger_type, tw.pact_publication_id, tw.webhook_id, tw.webhook_uuid, tw.consumer_id, tw.provider_id, tw.status, tw.created_at, tw.updated_at, tw.verification_id, ''::text as event_name
45
+ from triggered_webhooks tw
46
+ inner join latest_triggered_webhook_ids ltwi
47
+ on tw.consumer_id = ltwi.consumer_id
48
+ and tw.provider_id = ltwi.provider_id
49
+ and tw.webhook_uuid = ltwi.webhook_uuid
50
+ and tw.id = ltwi.latest_triggered_webhook_id"
51
+ else
52
+ latest_triggered_webhooks_v2
53
+ end
54
+ end
55
+
56
+ ##### v3
57
+
58
+ # screw dates, just use IDs.
59
+ def latest_triggered_webhooks_v3
60
+ "select tw.id, tw.trigger_uuid, tw.trigger_type, tw.pact_publication_id, tw.webhook_id, tw.webhook_uuid, tw.consumer_id, tw.provider_id, tw.status, tw.created_at, tw.updated_at, tw.verification_id, tw.event_name
61
+ from triggered_webhooks tw
62
+ inner join (select max(id) as max_id
63
+ from triggered_webhooks
64
+ group by webhook_uuid, consumer_id, provider_id, event_name) latest_ids
65
+ on latest_ids.max_id = tw.id"
66
+ end
@@ -1,44 +1,10 @@
1
+ require_relative '../ddl_statements/latest_triggered_webhooks'
2
+
1
3
  Sequel.migration do
2
4
  up do
3
- # These views find the latest triggered webhook for each webhook/consumer/provider
4
- # by finding the latest execution date for each webhook
5
- # then taking the row with the max ID in case there there are two
6
- # triggered webhooks for the same UUID and same creation date
7
- # Not sure if this is strictly necessary to do the extra step, but better to be
8
- # safe than sorry.
9
- # I probably could just take the max ID for each webhook/consumer/provider, but
10
- # something in my head says that
11
- # relying on the primary key for order is not a good idea, even though
12
- # according to the SQL it should be fine.
13
-
14
- create_or_replace_view(:latest_triggered_webhook_creation_dates,
15
- "select webhook_uuid, consumer_id, provider_id, max(created_at) as latest_triggered_webhook_created_at
16
- from triggered_webhooks
17
- group by webhook_uuid, consumer_id, provider_id"
18
- )
19
-
20
- # Ignore ltwcd.latest_triggered_webhook_created_at, it's there because postgres doesn't allow you to modify
21
- # the names and types of columns in a view
22
- create_or_replace_view(:latest_triggered_webhook_ids,
23
- "select tw.webhook_uuid, tw.consumer_id, tw.provider_id, ltwcd.latest_triggered_webhook_created_at, max(tw.id) as latest_triggered_webhook_id
24
- from latest_triggered_webhook_creation_dates ltwcd
25
- inner join triggered_webhooks tw
26
- on tw.consumer_id = ltwcd.consumer_id
27
- and tw.provider_id = ltwcd.provider_id
28
- and tw.webhook_uuid = ltwcd.webhook_uuid
29
- and tw.created_at = ltwcd.latest_triggered_webhook_created_at
30
- group by tw.webhook_uuid, tw.consumer_id, tw.provider_id, ltwcd.latest_triggered_webhook_created_at"
31
- )
32
-
33
- create_or_replace_view(:latest_triggered_webhooks,
34
- "select tw.*
35
- from triggered_webhooks tw
36
- inner join latest_triggered_webhook_ids ltwi
37
- on tw.consumer_id = ltwi.consumer_id
38
- and tw.provider_id = ltwi.provider_id
39
- and tw.webhook_uuid = ltwi.webhook_uuid
40
- and tw.id = ltwi.latest_triggered_webhook_id"
41
- )
5
+ create_or_replace_view(:latest_triggered_webhook_creation_dates, latest_triggered_webhook_creation_dates_v2)
6
+ create_or_replace_view(:latest_triggered_webhook_ids, latest_triggered_webhook_ids_v2)
7
+ create_or_replace_view(:latest_triggered_webhooks, latest_triggered_webhooks_v2)
42
8
  end
43
9
 
44
10
  down do
@@ -0,0 +1,15 @@
1
+ require_relative '../ddl_statements/latest_triggered_webhooks'
2
+ require_relative 'migration_helper'
3
+
4
+ Sequel.migration do
5
+ up do
6
+ # TODO
7
+ # drop_view(:latest_triggered_webhook_ids)
8
+ # drop_view(:latest_triggered_webhook_creation_dates)
9
+ create_or_replace_view(:latest_triggered_webhooks, latest_triggered_webhooks_v3)
10
+ end
11
+
12
+ down do
13
+ create_or_replace_view(:latest_triggered_webhooks, latest_triggered_webhooks_v3_rollback(PactBroker::MigrationHelper.postgres?))
14
+ end
15
+ end
@@ -0,0 +1,5 @@
1
+ Sequel.migration do
2
+ change do
3
+ add_column(:verifications, :wip, TrueClass, default: false, null: false)
4
+ end
5
+ end
@@ -0,0 +1,20 @@
1
+ require_relative 'migration_helper'
2
+
3
+ Sequel.migration do
4
+ up do
5
+ if PactBroker::MigrationHelper.postgres?
6
+ row = from(:verification_sequence_number).select(:value).limit(1).first
7
+ start = row ? row[:value] + 100 : 1
8
+ run("CREATE SEQUENCE verification_number_sequence START WITH #{start}")
9
+ end
10
+ end
11
+
12
+ down do
13
+ if PactBroker::MigrationHelper.postgres?
14
+ nextval = execute("SELECT nextval('verification_number_sequence') as val") { |v| v.first["val"].to_i }
15
+ # Add a safety margin!
16
+ from(:verification_sequence_number).update(value: nextval + 100)
17
+ run("DROP SEQUENCE verification_number_sequence")
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ require_relative 'migration_helper'
2
+
3
+ Sequel.migration do
4
+ up do
5
+ if PactBroker::MigrationHelper.postgres?
6
+ row = from(:version_sequence_number).select(:value).limit(1).first
7
+ start = row ? row[:value] + 100 : 1
8
+ run("CREATE SEQUENCE version_order_sequence START WITH #{start}")
9
+ end
10
+ end
11
+
12
+ down do
13
+ if PactBroker::MigrationHelper.postgres?
14
+ nextval = execute("SELECT nextval('version_order_sequence') as val") { |v| v.first["val"].to_i }
15
+ # Add a safety margin!
16
+ from(:version_sequence_number).update(value: nextval + 100)
17
+ run("DROP SEQUENCE version_order_sequence")
18
+ end
19
+ end
20
+ end
@@ -4,7 +4,7 @@ module PactBroker
4
4
  extend self
5
5
 
6
6
  def large_text_type
7
- if adapter == 'postgres'
7
+ if postgres?
8
8
  :text
9
9
  else
10
10
  # Assume mysql
@@ -13,11 +13,19 @@ module PactBroker
13
13
  end
14
14
 
15
15
  def with_mysql
16
- if adapter =~ /mysql/
16
+ if mysql?
17
17
  yield
18
18
  end
19
19
  end
20
20
 
21
+ def mysql?
22
+ adapter =~ /mysql/
23
+ end
24
+
25
+ def postgres?
26
+ adapter == 'postgres'
27
+ end
28
+
21
29
  def adapter
22
30
  Sequel::Model.db.adapter_scheme.to_s
23
31
  end
data/lib/db.rb CHANGED
@@ -27,7 +27,9 @@ module DB
27
27
  def self.connect db_credentials
28
28
  # Keep this conifiguration in sync with lib/pact_broker/app.rb#configure_database_connection
29
29
  Sequel.datetime_class = DateTime
30
- # logger = Logger.new($stdout)
30
+ if ENV['DEBUG'] == 'true'
31
+ logger = Logger.new($stdout)
32
+ end
31
33
  con = Sequel.connect(db_credentials.merge(:logger => logger, :pool_class => Sequel::ThreadedConnectionPool, :encoding => 'utf8'))
32
34
  con.extension(:connection_validator)
33
35
  con.extension(:pagination)
@@ -58,6 +60,10 @@ module DB
58
60
  !!(PACT_BROKER_DB.adapter_scheme.to_s =~ /mysql/)
59
61
  end
60
62
 
63
+ def self.postgres?
64
+ !!(PACT_BROKER_DB.adapter_scheme.to_s == "postgres")
65
+ end
66
+
61
67
  PACT_BROKER_DB ||= connection_for_env ENV.fetch('RACK_ENV')
62
68
 
63
69
  def self.health_check
@@ -71,6 +71,7 @@ module PactBroker
71
71
  add ['pacticipants', :pacticipant_name, 'versions'], Api::Resources::Versions, {resource_name: "pacticipant_versions"}
72
72
  add ['pacticipants', :pacticipant_name, 'versions', :pacticipant_version_number], Api::Resources::Version, {resource_name: "pacticipant_version"}
73
73
  add ['pacticipants', :pacticipant_name, 'latest-version', :tag], Api::Resources::Version, {resource_name: "latest_tagged_pacticipant_version"}
74
+ add ['pacticipants', :pacticipant_name, 'latest-version', :tag, 'can-i-deploy', 'to', :to], Api::Resources::CanIDeployPacticipantVersion, { resource_name: "can_i_deploy_latest_tagged_version" }
74
75
  add ['pacticipants', :pacticipant_name, 'latest-version', :tag, 'can-i-deploy', 'to', :to, 'badge'], Api::Resources::CanIDeployBadge, { resource_name: "can_i_deploy_badge" }
75
76
  add ['pacticipants', :pacticipant_name, 'latest-version'], Api::Resources::Version, {resource_name: "latest_pacticipant_version"}
76
77
  add ['pacticipants', :pacticipant_name, 'versions', :pacticipant_version_number, 'tags', :tag_name], Api::Resources::Tag, {resource_name: "pacticipant_version_tag"}
@@ -2,14 +2,14 @@ module PactBroker
2
2
  module Api
3
3
  module Decorators
4
4
  class DecoratorContext < Hash
5
-
6
- attr_reader :base_url, :resource_url, :resource_title, :env
5
+ attr_reader :base_url, :resource_url, :resource_title, :env, :query_string
7
6
 
8
7
  def initialize base_url, resource_url, env, options = {}
9
8
  @base_url = self[:base_url] = base_url
10
9
  @resource_url = self[:resource_url] = resource_url
11
10
  @resource_title = self[:resource_title] = options[:resource_title]
12
11
  @env = self[:env] = env
12
+ @query_string = self[:query_string] = (env['QUERY_STRING'] && !env['QUERY_STRING'].empty? ? env['QUERY_STRING'] : nil)
13
13
  merge!(options)
14
14
  end
15
15
 
@@ -0,0 +1,34 @@
1
+ require 'roar/decorator'
2
+ require 'roar/json/hal'
3
+
4
+ module PactBroker
5
+ module Api
6
+ module Decorators
7
+ module PaginationLinks
8
+ include Roar::JSON::HAL
9
+ include Roar::JSON::HAL::Links
10
+
11
+ link :next do | context |
12
+ if represented.respond_to?(:current_page) &&
13
+ represented.respond_to?(:page_count) &&
14
+ represented.current_page < represented.page_count
15
+ {
16
+ href: context[:resource_url] + "?pageSize=#{represented.page_size}&pageNumber=#{represented.current_page + 1}",
17
+ title: "Next page"
18
+ }
19
+
20
+ end
21
+ end
22
+
23
+ link :previous do | context |
24
+ if represented.respond_to?(:first_page?) && !represented.first_page?
25
+ {
26
+ href: context[:resource_url] + "?pageSize=#{represented.page_size}&pageNumber=#{represented.current_page - 1}",
27
+ title: "Previous page"
28
+ }
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -20,14 +20,16 @@ module PactBroker
20
20
  getter: -> (context) { context[:decorator].notices(context[:options][:user_options]) }
21
21
 
22
22
  def notices(user_options)
23
- pact_url = pact_version_url(represented, user_options[:base_url])
23
+ metadata = represented.wip ? { wip: true } : nil
24
+ pact_url = pact_version_url_with_metadata(represented, metadata, user_options[:base_url])
24
25
  PactBroker::Pacts::BuildVerifiablePactNotices.call(represented, pact_url, user_options)
25
26
  end
26
27
  end
27
28
 
28
29
  link :self do | user_options |
30
+ metadata = represented.wip ? { wip: true } : nil
29
31
  {
30
- href: pact_version_url(represented, user_options[:base_url]),
32
+ href: pact_version_url_with_metadata(represented, metadata, user_options[:base_url]),
31
33
  name: represented.name
32
34
  }
33
35
  end
@@ -1,5 +1,6 @@
1
1
  require_relative 'base_decorator'
2
2
  require_relative 'version_decorator'
3
+ require_relative 'pagination_links'
3
4
 
4
5
  module PactBroker
5
6
  module Api
@@ -9,12 +10,15 @@ module PactBroker
9
10
  collection :entries, as: :versions, embedded: true, :extend => PactBroker::Api::Decorators::VersionDecorator
10
11
 
11
12
  link :self do | context |
13
+ href = append_query_if_present(context[:resource_url], context[:query_string])
12
14
  {
13
- href: context[:resource_url],
15
+ href: href,
14
16
  title: "All application versions of #{context[:pacticipant_name]}"
15
17
  }
16
18
  end
17
19
 
20
+ include PaginationLinks
21
+
18
22
  link :'pb:pacticipant' do | context |
19
23
  {
20
24
  href: pacticipant_url(context[:base_url], OpenStruct.new(name: context[:pacticipant_name])),
@@ -58,19 +58,23 @@ module PactBroker
58
58
  "#{pactigration_base_url(base_url, pact)}/pact-version/#{pact.pact_version_sha}"
59
59
  end
60
60
 
61
- def pact_version_url_with_metadata pact, base_url = ''
62
- "#{pactigration_base_url(base_url, pact)}/pact-version/#{pact.pact_version_sha}/metadata/#{build_webhook_metadata(pact)}"
61
+ def pact_version_url_with_metadata pact, metadata, base_url = ''
62
+ if metadata && metadata.any?
63
+ "#{pact_version_url(pact, base_url)}/metadata/#{encode_metadata(metadata)}"
64
+ else
65
+ pact_version_url(pact, base_url)
66
+ end
63
67
  end
64
68
 
65
- def build_webhook_metadata(pact)
66
- encode_webhook_metadata(build_metadata_for_webhook_triggered_by_pact_publication(pact))
69
+ def pact_version_url_with_webhook_metadata pact, base_url = ''
70
+ pact_version_url_with_metadata(pact, build_metadata_for_webhook_triggered_by_pact_publication(pact), base_url)
67
71
  end
68
72
 
69
- def encode_webhook_metadata(metadata)
73
+ def encode_metadata(metadata)
70
74
  Base64.strict_encode64(Rack::Utils.build_nested_query(metadata))
71
75
  end
72
76
 
73
- def decode_webhook_metadata(metadata)
77
+ def decode_pact_metadata(metadata)
74
78
  if metadata
75
79
  begin
76
80
  Rack::Utils.parse_nested_query(Base64.strict_decode64(metadata)).each_with_object({}) do | (k, v), new_hash |
@@ -204,8 +208,12 @@ module PactBroker
204
208
  pacticipant_url_from_params({ pacticipant_name: pacticipant_name }, base_url) + "/labels/{label}"
205
209
  end
206
210
 
211
+ def templated_can_i_deploy_url pacticipant_name, base_url = ""
212
+ pacticipant_url_from_params({ pacticipant_name: pacticipant_name }, base_url) + "/latest-version/{tag}/can-i-deploy/to/{environmentTag}"
213
+ end
214
+
207
215
  def templated_can_i_deploy_badge_url pacticipant_name, base_url = ""
208
- pacticipant_url_from_params({ pacticipant_name: pacticipant_name }, base_url) + "/latest-version/{tag}/can-i-deploy/to/{environmentTag}/badge"
216
+ templated_can_i_deploy_url(pacticipant_name, base_url) + "/badge"
209
217
  end
210
218
 
211
219
  def label_url label, base_url
@@ -303,6 +311,14 @@ module PactBroker
303
311
  ERB::Util.url_encode param
304
312
  end
305
313
 
314
+ def append_query_if_present(url, query)
315
+ if query && query.size > 0
316
+ url + "?#{query}"
317
+ else
318
+ url
319
+ end
320
+ end
321
+
306
322
  private
307
323
 
308
324
  def representable_pact pact