pact_broker 2.69.0 → 2.74.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test.yml +54 -0
  3. data/CHANGELOG.md +65 -0
  4. data/DEVELOPER_SETUP.md +6 -0
  5. data/Dockerfile +8 -3
  6. data/Gemfile +4 -0
  7. data/ISSUES.md +23 -0
  8. data/config/database.yml +14 -0
  9. data/docker-compose-ci-mysql.yml +37 -0
  10. data/docker-compose-issue-repro.yml +11 -7
  11. data/lib/db.rb +1 -0
  12. data/lib/pact_broker/api/decorators/extended_pact_decorator.rb +9 -1
  13. data/lib/pact_broker/api/decorators/extended_verification_decorator.rb +8 -0
  14. data/lib/pact_broker/api/decorators/matrix_decorator.rb +9 -4
  15. data/lib/pact_broker/api/decorators/tag_decorator.rb +0 -3
  16. data/lib/pact_broker/api/decorators/verifiable_pact_decorator.rb +3 -1
  17. data/lib/pact_broker/api/pact_broker_urls.rb +9 -5
  18. data/lib/pact_broker/api/resources/clean.rb +36 -0
  19. data/lib/pact_broker/api/resources/error_handler.rb +1 -1
  20. data/lib/pact_broker/api/resources/group.rb +5 -1
  21. data/lib/pact_broker/api/resources/metadata_resource_methods.rb +24 -0
  22. data/lib/pact_broker/api/resources/pact.rb +2 -13
  23. data/lib/pact_broker/api/resources/pact_resource_methods.rb +23 -0
  24. data/lib/pact_broker/api/resources/pact_version.rb +3 -0
  25. data/lib/pact_broker/api/resources/tagged_pact_versions.rb +4 -0
  26. data/lib/pact_broker/api/resources/verifications.rb +2 -4
  27. data/lib/pact_broker/app.rb +1 -0
  28. data/lib/pact_broker/configuration.rb +12 -4
  29. data/lib/pact_broker/db/clean.rb +4 -1
  30. data/lib/pact_broker/db/clean_incremental.rb +217 -0
  31. data/lib/pact_broker/db/delete_overwritten_data.rb +55 -27
  32. data/lib/pact_broker/domain/tag.rb +111 -8
  33. data/lib/pact_broker/domain/verification.rb +93 -0
  34. data/lib/pact_broker/domain/version.rb +48 -7
  35. data/lib/pact_broker/logging.rb +7 -0
  36. data/lib/pact_broker/matrix/unresolved_selector.rb +8 -0
  37. data/lib/pact_broker/metrics/service.rb +17 -4
  38. data/lib/pact_broker/pacts/all_pact_publications.rb +9 -3
  39. data/lib/pact_broker/pacts/metadata.rb +53 -8
  40. data/lib/pact_broker/pacts/pact_publication.rb +7 -1
  41. data/lib/pact_broker/pacts/repository.rb +49 -30
  42. data/lib/pact_broker/pacts/selector.rb +22 -0
  43. data/lib/pact_broker/pacts/selectors.rb +4 -0
  44. data/lib/pact_broker/tags/tag_with_latest_flag.rb +2 -0
  45. data/lib/pact_broker/tasks/clean_task.rb +42 -12
  46. data/lib/pact_broker/tasks/delete_overwritten_data_task.rb +23 -7
  47. data/lib/pact_broker/test/http_test_data_builder.rb +91 -17
  48. data/lib/pact_broker/test/test_data_builder.rb +24 -0
  49. data/lib/pact_broker/version.rb +1 -1
  50. data/lib/pact_broker/webhooks/triggered_webhook.rb +6 -0
  51. data/lib/sequel/extensions/statement_timeout.rb +22 -0
  52. data/pact_broker.gemspec +2 -1
  53. data/script/docker-container/test.sh +3 -0
  54. data/script/docker/db-psql.sh +3 -0
  55. data/script/docker/db-reload.sh +11 -0
  56. data/script/docker/db-start.sh +1 -1
  57. data/script/pry.rb +25 -0
  58. data/script/reproduce-issue-starting-up.rb +43 -0
  59. data/script/reproduce-issue.rb +23 -15
  60. data/script/seed.rb +1 -0
  61. data/script/test/run-rake-on-docker-compose-mysql.sh +8 -0
  62. data/spec/features/delete_tagged_pact_versions_spec.rb +2 -2
  63. data/spec/features/get_pact_spec.rb +2 -2
  64. data/spec/features/get_pact_version.rb +26 -3
  65. data/spec/fixtures/approvals/clean_incremental_dry_run.approved.json +100 -0
  66. data/spec/fixtures/approvals/modifiable_resources.approved.json +3 -0
  67. data/spec/lib/pact_broker/api/decorators/extended_pact_decorator_spec.rb +1 -0
  68. data/spec/lib/pact_broker/api/decorators/matrix_decorator_spec.rb +20 -8
  69. data/spec/lib/pact_broker/api/decorators/verifiable_pact_decorator_spec.rb +5 -7
  70. data/spec/lib/pact_broker/api/pact_broker_urls_spec.rb +16 -6
  71. data/spec/lib/pact_broker/api/resources/error_handler_spec.rb +16 -0
  72. data/spec/lib/pact_broker/api/resources/group_spec.rb +9 -7
  73. data/spec/lib/pact_broker/api/resources/pact_spec.rb +20 -9
  74. data/spec/lib/pact_broker/api/resources/tagged_pact_versions_spec.rb +10 -2
  75. data/spec/lib/pact_broker/api/resources/verifications_spec.rb +7 -3
  76. data/spec/lib/pact_broker/db/clean_incremental_spec.rb +119 -0
  77. data/spec/lib/pact_broker/db/delete_overwritten_data_spec.rb +71 -11
  78. data/spec/lib/pact_broker/domain/tag_spec.rb +60 -0
  79. data/spec/lib/pact_broker/domain/verification_spec.rb +62 -0
  80. data/spec/lib/pact_broker/domain/version_spec.rb +23 -0
  81. data/spec/lib/pact_broker/metrics/service_spec.rb +4 -1
  82. data/spec/lib/pact_broker/pacts/metadata_spec.rb +73 -0
  83. data/spec/lib/pact_broker/pacts/pact_publication_spec.rb +3 -1
  84. data/spec/lib/pact_broker/pacts/repository_find_for_verification_fallback_spec.rb +2 -2
  85. data/spec/lib/pact_broker/pacts/repository_find_for_verification_spec.rb +33 -13
  86. data/spec/lib/pact_broker/pacts/repository_find_wip_pact_versions_for_provider_spec.rb +14 -1
  87. data/spec/lib/pact_broker/pacts/repository_spec.rb +54 -7
  88. data/spec/lib/pact_broker/pacts/selected_pact_spec.rb +23 -0
  89. data/spec/migrations/change_migration_strategy_spec.rb +1 -1
  90. metadata +57 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 03c656c61487fd81baf9eb94f73fa12ab27bdf5cea1bd2d670af63199123b6ef
4
- data.tar.gz: '04022874b3eeb6681e79163431ce63c8d6760741dc7ec8db30cc87b8f9257a94'
3
+ metadata.gz: 4a3779dfce4701e31c25e10a37154785df8745aa022869f70bcdd3c080066169
4
+ data.tar.gz: d9c48a07a42949aea37a84ca43930a53d6403abe02a96d1c1de2d58a27d763bc
5
5
  SHA512:
6
- metadata.gz: ce0f9fb3186ab25c419b61665245977abfbaa8d245437699c44de54783bde86d8281b950172532d02a31f6aa33f36046dde7a0636075fabe75f3f074c33016c2
7
- data.tar.gz: f6b8baa8a66b80b50df9223086f8e67dd9233106897b15f5cfa16328e954805de786d4fbe672f3cee5ba831001edd78f5c0a977dfc5d767d4c79aa46a61b1010
6
+ metadata.gz: 2a4a61fe0838766004ab06723b406d51149d748ec449c81139ada966a223b5491d4728fa0cdd52d6e369081af490eb03b4b7036c12c6f2a6b014bf20608c9d68
7
+ data.tar.gz: 569774601622663f53d824d40b0013afd6728f0c603fb9f2f8d66f759603daf7d361d6481003dc83a2a844415d93eae78694a076be1172eb45728d678cd672a2
@@ -0,0 +1,54 @@
1
+ name: Test
2
+
3
+ on: push
4
+
5
+ jobs:
6
+ sqlite:
7
+ runs-on: "ubuntu-latest"
8
+ strategy:
9
+ matrix:
10
+ ruby_version: ["2.7"]
11
+ steps:
12
+ - uses: actions/checkout@v2
13
+ - uses: actions/setup-ruby@v1
14
+ with:
15
+ ruby-version: ${{ matrix.ruby_version }}
16
+ - run: "bundle install"
17
+ - run: "bundle exec rake"
18
+ postgres:
19
+ runs-on: "ubuntu-latest"
20
+ strategy:
21
+ matrix:
22
+ ruby_version: ["2.5", "2.7"]
23
+ services:
24
+ postgres:
25
+ image: postgres
26
+ env:
27
+ POSTGRES_PASSWORD: postgres
28
+ options: >-
29
+ --health-cmd pg_isready
30
+ --health-interval 10s
31
+ --health-timeout 5s
32
+ --health-retries 5
33
+ ports:
34
+ - 5432:5432
35
+ steps:
36
+ - uses: actions/checkout@v2
37
+ - uses: actions/setup-ruby@v1
38
+ with:
39
+ ruby-version: ${{ matrix.ruby_version }}
40
+ - run: "gem install bundler && bundle install"
41
+ env:
42
+ INSTALL_PG: "true"
43
+ - run: "bundle exec rake"
44
+ env:
45
+ DATABASE_ADAPTER: github_actions_postgres
46
+ INSTALL_PG: "true"
47
+ mysql:
48
+ runs-on: "ubuntu-latest"
49
+ strategy:
50
+ matrix:
51
+ ruby_version: ["2.7"]
52
+ steps:
53
+ - uses: actions/checkout@v2
54
+ - run: script/test/run-rake-on-docker-compose-mysql.sh
@@ -1,3 +1,68 @@
1
+ <a name="v2.74.0"></a>
2
+ ### v2.74.0 (2021-01-04)
3
+
4
+ #### Features
5
+
6
+ * include the consumer version selectors in the metadata of the 'pact for verification' URL ([32bbe1c3](/../../commit/32bbe1c3))
7
+
8
+ #### Bug Fixes
9
+
10
+ * **deps**
11
+ * update nokogiri for CVE-2020-26247 ([336ec897](/../../commit/336ec897))
12
+
13
+ <a name="v2.73.0"></a>
14
+ ### v2.73.0 (2020-12-16)
15
+
16
+ #### Features
17
+
18
+ * **wip**
19
+ * permenently enable feature that keeps pacts as WIP when verified via the URL from a webhook triggered by pact publication ([70071373](/../../commit/70071373))
20
+
21
+ * allow error causes to be configured to log at warning level ([3a7bf5ea](/../../commit/3a7bf5ea))
22
+ * add self relations for tags in matrix resource ([727cee99](/../../commit/727cee99))
23
+ * add self relation to tags in extended pact and verification resources ([a560ce6d](/../../commit/a560ce6d))
24
+
25
+ * **metrics**
26
+ * timeout matrix count ([43091b57](/../../commit/43091b57))
27
+
28
+ #### Bug Fixes
29
+
30
+ * url encode tag name in tag URL ([80df832d](/../../commit/80df832d))
31
+
32
+ <a name="v2.72.0"></a>
33
+ ### v2.72.0 (2020-12-02)
34
+
35
+ #### Features
36
+
37
+ * allow overwritten data deletion to be configured with extra options ([fd809737](/../../commit/fd809737))
38
+ * use the consumer version number in the metadata to select the correct consumer version for a pact version resource ([422c87fc](/../../commit/422c87fc))
39
+ * return link to latest pact if more pacts exist when deleting pacts by tag ([b87ea704](/../../commit/b87ea704))
40
+ * update output for clean dry run ([681a5ddd](/../../commit/681a5ddd))
41
+ * update metrics output ([0617e9df](/../../commit/0617e9df))
42
+
43
+ <a name="v2.71.0"></a>
44
+ ### v2.71.0 (2020-11-28)
45
+
46
+ #### Features
47
+
48
+ * allow clean to be performed in dry run mode ([a7a18fde](/../../commit/a7a18fde))
49
+
50
+ <a name="v2.70.0"></a>
51
+ ### v2.70.0 (2020-11-28)
52
+
53
+ #### Features
54
+
55
+ * allow limit to be applied to clean task ([d29e5c62](/../../commit/d29e5c62))
56
+ * optimise the query to load the tags with latest flags ([bc47613f](/../../commit/bc47613f))
57
+ * optimise query to find head tags for a pact ([67309e37](/../../commit/67309e37))
58
+
59
+ * **wip pacts**
60
+ * experimental feature - if no provider versions exist, consider all head pacts wip ([a635cc53](/../../commit/a635cc53))
61
+
62
+ #### Bug Fixes
63
+
64
+ * return empty body when group csv is requested for a pacticipant that does not have any integrations ([fb4e28ce](/../../commit/fb4e28ce))
65
+
1
66
  <a name="v2.69.0"></a>
2
67
  ### v2.69.0 (2020-11-24)
3
68
 
@@ -28,6 +28,12 @@ This allows you to open a shell to a development environment where you can run t
28
28
 
29
29
  Remember to rebuild the image if you change any of the gems or gem versions.
30
30
 
31
+ * Run the server on the docker image
32
+
33
+ ```sh
34
+ docker run --rm -v $(PWD):/home -w /home --entrypoint /bin/sh -p 9292:9292 -it pact_broker:dev /usr/local/bin/start
35
+ ```
36
+
31
37
  ### With native install
32
38
 
33
39
  * You will need to install Ruby 2.5, and preferably a ruby version manager. I recommend using [chruby][chruby] and [ruby-install][ruby-install].
data/Dockerfile CHANGED
@@ -26,6 +26,7 @@ RUN wget https://github.com/jwilder/dockerize/releases/download/$DOCKERIZE_VERSI
26
26
 
27
27
 
28
28
  COPY Gemfile /home/Gemfile
29
+ # COPY Gemfile.lock /home/Gemfile.lock # lock file does not exist on CI
29
30
  COPY pact_broker.gemspec /home/pact_broker.gemspec
30
31
  COPY lib/pact_broker/version.rb /home/lib/pact_broker/version.rb
31
32
  COPY .gitignore /home/.gitignore
@@ -33,9 +34,13 @@ COPY .gitignore /home/.gitignore
33
34
  RUN gem install bundler -v '~>2.0.0' \
34
35
  && bundle install --jobs 3 --retry 3
35
36
 
36
- RUN echo '#!/bin/sh' >> /home/start.sh
37
- RUN echo 'bundle exec rackup -o 0.0.0.0 -p 9292' >> /home/start.sh
38
- RUN chmod +x /home/start.sh
37
+ RUN echo '#!/bin/sh' >> /usr/local/bin/start
38
+ RUN echo 'bundle exec rackup -o 0.0.0.0 -p 9292' >> /usr/local/bin/start
39
+ RUN chmod +x /usr/local/bin/start
40
+
41
+ RUN echo '#!/bin/sh' >> /usr/local/bin/test
42
+ RUN echo 'bundle exec rake' >> /usr/local/bin/test
43
+ RUN chmod +x /usr/local/bin/test
39
44
 
40
45
  RUN echo '#!/bin/sh' >> /home/init-db.sh
41
46
  RUN echo 'bundle exec rake db:prepare:test' >> /home/init-db.sh
data/Gemfile CHANGED
@@ -36,3 +36,7 @@ end
36
36
  if ENV['INSTALL_PG'] == 'true'
37
37
  gem 'pg', '~>1.2'
38
38
  end
39
+
40
+ if ENV['X_PACT_DEVELOPMENT'] == 'true'
41
+ gem 'pact-support', path: '../pact-support'
42
+ end
@@ -0,0 +1,23 @@
1
+ # Issues
2
+
3
+ ## Reproducing an issue
4
+
5
+ In [script/reproduce-issue.rb](script/reproduce-issue.rb) you will find a fluent API that allows you to simulate client libraries interacting with the Pact Broker.
6
+
7
+ You can use it to easily reproduce issues.
8
+
9
+ To use it:
10
+
11
+ * Run the Pact Broker using the latest development code:
12
+
13
+ ```
14
+ docker-compose -f docker-compose-issue-repro.yml up --build pact-broker
15
+ ```
16
+
17
+ * Run the reproduction script.
18
+
19
+ ```
20
+ docker-compose -f docker-compose-issue-repro.yml up repro-issue
21
+ ```
22
+
23
+ You can modify `script/reproduce-issue.rb` and then re-run it with the change applied.
@@ -36,6 +36,20 @@ test:
36
36
  <<: *default
37
37
  adapter: mysql2
38
38
  host: "192.168.0.9"
39
+ github_actions_postgres:
40
+ adapter: postgres
41
+ database: postgres
42
+ username: postgres
43
+ password: postgres
44
+ host: localhost
45
+ port: "5432"
46
+ github_actions_mysql:
47
+ adapter: mysql2
48
+ database: pact_broker
49
+ username: pact_broker
50
+ password: pact_broker
51
+ host: localhost
52
+ port: 3306
39
53
 
40
54
  development:
41
55
  default:
@@ -0,0 +1,37 @@
1
+ version: "3"
2
+
3
+ services:
4
+ mysql:
5
+ image: mysql:5.7.28
6
+ command: --default-authentication-plugin=mysql_native_password
7
+ environment:
8
+ MYSQL_ROOT_PASSWORD: pact_broker
9
+ MYSQL_DATABASE: pact_broker
10
+ MYSQL_USER: pact_broker
11
+ MYSQL_PASSWORD: pact_broker
12
+ ports:
13
+ - "3306:3306"
14
+
15
+ tests:
16
+ build: .
17
+ depends_on:
18
+ - mysql
19
+ environment:
20
+ DATABASE_ADAPTER: docker_compose_mysql
21
+ PACT_BROKER_HIDE_PACTFLOW_MESSAGES: 'true'
22
+ INSTALL_MYSQL: 'true'
23
+ volumes:
24
+ - ./lib:/home/lib
25
+ - ./spec:/home/spec
26
+ - ./db:/home/db
27
+ - ./config.ru:/home/config.ru
28
+ - ./tasks:/home/tasks
29
+ - ./Rakefile:/home/Rakefile
30
+ - ./config:/home/config
31
+ - ./.rspec:/home/.rspec
32
+ - ./.rubocop:/home/.rubocop
33
+ - ./.gitignore:/home/.gitignore
34
+ - ./public:/home/public
35
+ - ./script/docker-container/test.sh:/usr/local/bin/test
36
+ entrypoint: dockerize
37
+ command: --wait tcp://mysql:3306 -timeout 60s test
@@ -2,17 +2,21 @@ version: "3"
2
2
 
3
3
  services:
4
4
  pact-broker:
5
- build:
6
- context: .
7
- dockerfile: issue-reproduction/Dockerfile-pact-broker
5
+ build: .
8
6
  ports:
9
7
  - "9292:9292"
10
- command: bundle exec rackup -p 9292 -o 0.0.0.0
8
+ entrypoint: /usr/local/bin/start
9
+ environment:
10
+ - RACK_ENV=production
11
+ volumes:
12
+ - $PWD:/home
11
13
 
12
14
  repro-issue:
13
- build:
14
- context: .
15
- dockerfile: issue-reproduction/Dockerfile-pact-broker
15
+ build: .
16
16
  depends_on:
17
17
  - pact-broker
18
18
  command: dockerize -wait http://pact-broker:9292 -timeout 30s /home/script/reproduce-issue.rb
19
+ environment:
20
+ - PACT_BROKER_BASE_URL=http://pact-broker:9292
21
+ volumes:
22
+ - $PWD:/home
data/lib/db.rb CHANGED
@@ -33,6 +33,7 @@ module DB
33
33
  con = Sequel.connect(db_credentials.merge(:logger => logger, :pool_class => Sequel::ThreadedConnectionPool, :encoding => 'utf8'))
34
34
  con.extension(:connection_validator)
35
35
  con.extension(:pagination)
36
+ con.extension(:statement_timeout)
36
37
  con.extend_datasets do
37
38
  def any?
38
39
  !empty?
@@ -11,6 +11,14 @@ module PactBroker
11
11
  property :name
12
12
  property :latest, getter: ->(_) { true }
13
13
 
14
+ link :self do | options |
15
+ {
16
+ title: 'Tag',
17
+ name: represented.name,
18
+ href: tag_url(options[:base_url], represented)
19
+ }
20
+ end
21
+
14
22
  link "pb:latest-pact" do | opts |
15
23
  {
16
24
  name: "The latest pact with the tag #{represented.name}",
@@ -33,7 +41,7 @@ module PactBroker
33
41
 
34
42
  def head_tags
35
43
  represented.head_tag_names.collect do | tag_name |
36
- OpenStruct.new(name: tag_name, pact: represented)
44
+ OpenStruct.new(name: tag_name, pact: represented, version: represented.consumer_version)
37
45
  end
38
46
  end
39
47
  end
@@ -7,6 +7,14 @@ module PactBroker
7
7
  class TagDecorator < BaseDecorator
8
8
  property :name
9
9
  property :latest?, as: :latest
10
+
11
+ link :self do | options |
12
+ {
13
+ title: 'Tag',
14
+ name: represented.name,
15
+ href: tag_url(options[:base_url], represented)
16
+ }
17
+ end
10
18
  end
11
19
 
12
20
  collection :provider_version_tags, as: :tags, embedded: true, extend: TagDecorator
@@ -76,7 +76,7 @@ module PactBroker
76
76
  href: version_url(base_url, consumer_version)
77
77
  }
78
78
  },
79
- tags: tags(line.consumer_version_tags)
79
+ tags: tags(line.consumer_version_tags, base_url)
80
80
  },
81
81
  _links: {
82
82
  self: {
@@ -86,11 +86,16 @@ module PactBroker
86
86
  }
87
87
  end
88
88
 
89
- def tags(tags)
89
+ def tags(tags, base_url)
90
90
  tags.collect do | tag |
91
91
  {
92
92
  name: tag.name,
93
- latest: tag.latest?
93
+ latest: tag.latest?,
94
+ _links: {
95
+ self: {
96
+ href: tag_url(base_url, tag)
97
+ }
98
+ }
94
99
  }
95
100
  end
96
101
  end
@@ -114,7 +119,7 @@ module PactBroker
114
119
  href: version_url(base_url, provider_version)
115
120
  }
116
121
  },
117
- tags: tags(line.provider_version_tags)
122
+ tags: tags(line.provider_version_tags, base_url)
118
123
  }
119
124
  end
120
125
 
@@ -3,11 +3,8 @@ require_relative 'pact_pacticipant_decorator'
3
3
  require_relative 'timestamps'
4
4
 
5
5
  module PactBroker
6
-
7
6
  module Api
8
-
9
7
  module Decorators
10
-
11
8
  class TagDecorator < BaseDecorator
12
9
 
13
10
  property :name
@@ -1,11 +1,13 @@
1
1
  require_relative 'base_decorator'
2
2
  require 'pact_broker/api/pact_broker_urls'
3
3
  require 'pact_broker/pacts/build_verifiable_pact_notices'
4
+ require 'pact_broker/pacts/metadata'
4
5
 
5
6
  module PactBroker
6
7
  module Api
7
8
  module Decorators
8
9
  class VerifiablePactDecorator < BaseDecorator
10
+ include PactBroker::Pacts::Metadata
9
11
 
10
12
  property :shortDescription, getter: -> (context) { PactBroker::Pacts::VerifiablePactMessages.new(context[:represented], nil).pact_version_short_description }
11
13
 
@@ -27,7 +29,7 @@ module PactBroker
27
29
  end
28
30
 
29
31
  link :self do | user_options |
30
- metadata = represented.wip ? { wip: true } : nil
32
+ metadata = build_metadata_for_pact_for_verification(represented)
31
33
  {
32
34
  href: pact_version_url_with_metadata(represented, metadata, user_options[:base_url]),
33
35
  name: represented.name
@@ -1,6 +1,8 @@
1
1
  require 'erb'
2
2
  require 'pact_broker/pacts/metadata'
3
3
  require 'pact_broker/logging'
4
+ require 'base64'
5
+ require 'rack'
4
6
 
5
7
  module PactBroker
6
8
  module Api
@@ -75,11 +77,9 @@ module PactBroker
75
77
  end
76
78
 
77
79
  def decode_pact_metadata(metadata)
78
- if metadata
80
+ if metadata && metadata != ''
79
81
  begin
80
- Rack::Utils.parse_nested_query(Base64.strict_decode64(metadata)).each_with_object({}) do | (k, v), new_hash |
81
- new_hash[k.to_sym] = v
82
- end
82
+ Rack::Utils.parse_nested_query(Base64.strict_decode64(metadata))
83
83
  rescue StandardError => e
84
84
  logger.warn("Exception parsing webhook metadata: #{metadata}", e)
85
85
  {}
@@ -116,6 +116,10 @@ module PactBroker
116
116
  "#{base_url}/pacts/provider/#{url_encode(provider_name)}/consumer/#{url_encode(consumer_name)}/versions"
117
117
  end
118
118
 
119
+ def tagged_pact_versions_url consumer_name, provider_name, tag, base_url = ""
120
+ "#{base_url}/pacts/provider/#{url_encode(provider_name)}/consumer/#{url_encode(consumer_name)}/tag/#{url_encode(tag)}"
121
+ end
122
+
119
123
  def integration_url consumer_name, provider_name, base_url = ""
120
124
  "#{base_url}/integrations/provider/#{url_encode(provider_name)}/consumer/#{url_encode(consumer_name)}"
121
125
  end
@@ -197,7 +201,7 @@ module PactBroker
197
201
  end
198
202
 
199
203
  def tag_url base_url, tag
200
- "#{tags_url(base_url, tag.version)}/#{tag.name}"
204
+ "#{tags_url(base_url, tag.version)}/#{url_encode(tag.name)}"
201
205
  end
202
206
 
203
207
  def templated_tag_url_for_pacticipant pacticipant_name, base_url = ""