From 35ba4d5d7acc45be5db27e5521e53b3f5dfeca21 Mon Sep 17 00:00:00 2001 From: Yousaf Nabi Date: Fri, 15 Nov 2024 16:30:45 +0000 Subject: [PATCH] feat: add branch-pact-versions & latest-branch-pact-version # Branch pact versions Allowed methods: `GET` Path: `/pacts/provider/{provider}/consumer/{consumer}/branch/{branch}` Lists all the pact versions with the specified consumer, provider and consumer version branch. # Latest Branch pact versions Allowed methods: `GET` Path: `/pacts/provider/{provider}/consumer/{consumer}/branch/{branch}/latest` Returns the latest pact version with the specified consumer, provider and consumer version branch. --- lib/pact_broker/api.rb | 6 ++-- lib/pact_broker/api/resources/index.rb | 12 ++++++++ .../latest_provider_pacts_for_branch.rb | 8 +++-- .../api/resources/pact_versions_for_branch.rb | 10 ++++++- .../provider_pacts_for_consumer_branch.rb | 8 +++-- .../views/index/branch-pact-versions.markdown | 7 +++++ .../index/latest-branch-pact-version.markdown | 7 +++++ ...act_publication_selector_dataset_module.rb | 8 +++++ lib/pact_broker/pacts/repository.rb | 30 +++++++++++++++++++ lib/pact_broker/pacts/service.rb | 16 ++++++++-- .../latest_provider_pacts_for_branch_spec.rb | 4 +-- 11 files changed, 105 insertions(+), 11 deletions(-) create mode 100644 lib/pact_broker/doc/views/index/branch-pact-versions.markdown create mode 100644 lib/pact_broker/doc/views/index/latest-branch-pact-version.markdown diff --git a/lib/pact_broker/api.rb b/lib/pact_broker/api.rb index 9f6b76f1b..b9b68ba88 100644 --- a/lib/pact_broker/api.rb +++ b/lib/pact_broker/api.rb @@ -43,7 +43,8 @@ def self.build_api(application_context = PactBroker::ApplicationContext.default_ add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "version", :consumer_version_number, "diff", "previous-distinct"], Api::Resources::PactContentDiff, {resource_name: "previous_distinct_pact_version_diff"} add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "version", :consumer_version_number, "diff", "version", :comparison_consumer_version], Api::Resources::PactContentDiff, {resource_name: "pact_version_diff_by_consumer_version"} add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "pact-version", :pact_version_sha, "diff", "pact-version", :comparison_pact_version_sha], Api::Resources::PactContentDiff, {resource_name: "pact_version_diff_by_pact_version_sha"} - add ["pacts", "provider", :provider_name, "branch", :branch], Api::Resources::ProviderPactsForConsumerBranch, {resource_name: "branch_provider_pact_publications"} + add ["pacts", "provider", :provider_name, "branch", :branch_name], Api::Resources::ProviderPactsForConsumerBranch, {resource_name: "branch_provider_pact_publications"} + add ["pacts", "provider", :provider_name, "branch"], Api::Resources::ProviderPactsForConsumerBranch, {resource_name: "main_branch_provider_pact_publications"} # Verifications add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "pact-version", :pact_version_sha, "verification-results"], Api::Resources::Verifications, {resource_name: "verification_results"} @@ -70,8 +71,9 @@ def self.build_api(application_context = PactBroker::ApplicationContext.default_ add ["pacts", "provider", :provider_name, "tag", :tag], Api::Resources::ProviderPacts, {resource_name: "tagged_provider_pact_publications"} add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "latest-untagged"], Api::Resources::LatestPact, {resource_name: "latest_untagged_pact_publication", tag: :untagged} add ["pacts", "provider", :provider_name, "latest"], Api::Resources::LatestProviderPacts, {resource_name: "latest_provider_pact_publications"} + add ["pacts", "provider", :provider_name, "latest", "branch", :branch_name], Api::Resources::LatestProviderPactsForBranch, {resource_name: "latest_branch_provider_pact_publications"} + add ["pacts", "provider", :provider_name, "latest", "branch"], Api::Resources::LatestProviderPactsForBranch, {resource_name: "latest_main_branch_provider_pact_publications"} add ["pacts", "provider", :provider_name, "latest", :tag], Api::Resources::LatestProviderPacts, {resource_name: "latest_tagged_provider_pact_publications"} - add ["pacts", "provider", :provider_name, "latest", "branch", :branch], Api::Resources::LatestProviderPactsForBranch, {resource_name: "latest_branch_provider_pact_publications"} add ["pacts", "latest"], Api::Resources::LatestPacts, {resource_name: "latest_pacts"} # Pacts for verification diff --git a/lib/pact_broker/api/resources/index.rb b/lib/pact_broker/api/resources/index.rb index b02aaf731..f0be159ff 100644 --- a/lib/pact_broker/api/resources/index.rb +++ b/lib/pact_broker/api/resources/index.rb @@ -49,6 +49,18 @@ def links title: "All versions of a pact for a given consumer, provider and consumer version tag", templated: false }, + "pb:latest-branch-pact-version" => + { + href: base_url + "/pacts/provider/{provider}/consumer/{consumer}/branch/{branch}/latest", + title: "Latest version of a pact for a given consumer, provider and consumer version branch", + templated: false + }, + "pb:branch-pact-versions" => + { + href: base_url + "/pacts/provider/{provider}/consumer/{consumer}/branch/{branch}", + title: "All versions of a pact for a given consumer, provider and consumer version branch", + templated: false + }, "pb:pacticipants" => { href: base_url + "/pacticipants", diff --git a/lib/pact_broker/api/resources/latest_provider_pacts_for_branch.rb b/lib/pact_broker/api/resources/latest_provider_pacts_for_branch.rb index 0ff91a16b..b81ffe6db 100644 --- a/lib/pact_broker/api/resources/latest_provider_pacts_for_branch.rb +++ b/lib/pact_broker/api/resources/latest_provider_pacts_for_branch.rb @@ -9,11 +9,15 @@ class LatestProviderPactsForBranch < ProviderPacts private def pacts - pact_service.find_latest_pacts_for_provider_for_branch(provider_name, branch: identifier_from_path[:branch]) + pact_service.find_latest_pacts_for_provider_by_consumer_branch( + provider_name, + branch_name: identifier_from_path[:branch_name], + main_branch: identifier_from_path[:branch_name] ? false : true + ) end def resource_title - suffix = identifier_from_path[:branch] ? " with consumer version branch '#{identifier_from_path[:branch]}'" : "" + suffix = identifier_from_path[:branch_name] ? " with consumer version branch '#{identifier_from_path[:branch_name]}'" : "" "Latest pact versions for the provider #{identifier_from_path[:provider_name]}#{suffix}" end end diff --git a/lib/pact_broker/api/resources/pact_versions_for_branch.rb b/lib/pact_broker/api/resources/pact_versions_for_branch.rb index 1b69dcd5e..f11c50382 100644 --- a/lib/pact_broker/api/resources/pact_versions_for_branch.rb +++ b/lib/pact_broker/api/resources/pact_versions_for_branch.rb @@ -14,13 +14,21 @@ def content_types_provided end def allowed_methods - ["DELETE", "OPTIONS"] + ["GET", "DELETE", "OPTIONS"] end def resource_exists? consumer && provider end + def to_json + decorator_class(:pact_versions_decorator).new(pacts).to_json(**decorator_options(identifier_from_path)) + end + + def pacts + @pacts ||= pact_service.find_pacts_for_provider_and_consumer_by_consumer_branch provider_name, consumer_name, branch_name: identifier_from_path[:branch_name] + end + def delete_resource pact_service.delete_all_pact_publications_between consumer_name, and: provider_name, branch_name: identifier_from_path[:branch_name] set_post_deletion_response diff --git a/lib/pact_broker/api/resources/provider_pacts_for_consumer_branch.rb b/lib/pact_broker/api/resources/provider_pacts_for_consumer_branch.rb index 1ee86e588..19e4255a9 100644 --- a/lib/pact_broker/api/resources/provider_pacts_for_consumer_branch.rb +++ b/lib/pact_broker/api/resources/provider_pacts_for_consumer_branch.rb @@ -30,11 +30,15 @@ def to_json private def pacts - pact_service.find_pact_versions_for_provider provider_name, branch: identifier_from_path[:branch] + pact_service.find_pacts_for_provider_by_consumer_branch( + provider_name, + branch_name: identifier_from_path[:branch_name], + main_branch: identifier_from_path[:branch_name] ? false : true + ) end def resource_title - suffix = identifier_from_path[:branch] ? " with consumer version branch '#{identifier_from_path[:branch]}'" : "" + suffix = identifier_from_path[:branch_name] ? " with consumer version branch '#{identifier_from_path[:branch_name]}'" : "" "All pact versions for the provider #{identifier_from_path[:provider_name]}#{suffix}" end end diff --git a/lib/pact_broker/doc/views/index/branch-pact-versions.markdown b/lib/pact_broker/doc/views/index/branch-pact-versions.markdown new file mode 100644 index 000000000..bf0288b6e --- /dev/null +++ b/lib/pact_broker/doc/views/index/branch-pact-versions.markdown @@ -0,0 +1,7 @@ +# Branch pact versions + + Allowed methods: `GET` + + Path: `/pacts/provider/{provider}/consumer/{consumer}/branch/{branch}` + + Lists all the pact versions with the specified consumer, provider and consumer version branch. \ No newline at end of file diff --git a/lib/pact_broker/doc/views/index/latest-branch-pact-version.markdown b/lib/pact_broker/doc/views/index/latest-branch-pact-version.markdown new file mode 100644 index 000000000..6dc3b029d --- /dev/null +++ b/lib/pact_broker/doc/views/index/latest-branch-pact-version.markdown @@ -0,0 +1,7 @@ +# Latest Branch pact versions + + Allowed methods: `GET` + + Path: `/pacts/provider/{provider}/consumer/{consumer}/branch/{branch}/latest` + + Returns the latest pact version with the specified consumer, provider and consumer version branch. \ No newline at end of file diff --git a/lib/pact_broker/pacts/pact_publication_selector_dataset_module.rb b/lib/pact_broker/pacts/pact_publication_selector_dataset_module.rb index 017821090..5f023a115 100644 --- a/lib/pact_broker/pacts/pact_publication_selector_dataset_module.rb +++ b/lib/pact_broker/pacts/pact_publication_selector_dataset_module.rb @@ -44,6 +44,14 @@ def latest_for_main_branches .remove_overridden_revisions_from_complete_query end + def for_main_branches + consumers_join = { Sequel[:pact_publications][:consumer_id] => Sequel[:consumers][:id] } + query = self + query + .join(:pacticipants, consumers_join, { table_alias: :consumers }) + .remove_overridden_revisions_from_complete_query + end + def for_currently_deployed_versions(environment_name) deployed_versions_join = { Sequel[:pact_publications][:consumer_version_id] => Sequel[:deployed_versions][:version_id] diff --git a/lib/pact_broker/pacts/repository.rb b/lib/pact_broker/pacts/repository.rb index f1e05291d..0bf40927a 100644 --- a/lib/pact_broker/pacts/repository.rb +++ b/lib/pact_broker/pacts/repository.rb @@ -151,6 +151,36 @@ def find_latest_pacts_for_provider provider_name, tag = nil query.all.sort_by{ | p| p.consumer_name.downcase }.collect(&:to_head_pact) end + def find_pacts_by_consumer_branch(provider_name, options = {}) + consumer_name = options[:consumer] + latest = options.fetch(:latest, true) + branch = options[:branch_name] + main_branch = options.fetch(:main_branch, false) + + query = scope_for(PactPublication) + .eager_for_domain_with_content + .for_provider_name(provider_name) + + if consumer_name + query = query.for_consumer_name(consumer_name) + end + + if main_branch + if latest + query = query.latest_for_main_branches + else + query = query.for_main_branches + end + else + if latest + query = query.latest_for_consumer_branch(branch) + else + query = query.for_branch_name(branch) + end + end + query.all.sort_by{ | p| p.consumer_name.downcase }.collect(&:to_head_pact) + end + def find_for_verification(provider_name, consumer_version_selectors) PactsForVerificationRepository.new.find(provider_name, consumer_version_selectors) end diff --git a/lib/pact_broker/pacts/service.rb b/lib/pact_broker/pacts/service.rb index b476e57e7..0f4d393b1 100644 --- a/lib/pact_broker/pacts/service.rb +++ b/lib/pact_broker/pacts/service.rb @@ -95,8 +95,20 @@ def find_latest_pacts_for_provider provider_name, options = {} pact_repository.find_latest_pacts_for_provider provider_name, options[:tag] end - def find_latest_pacts_for_provider_for_branch provider_name, options = {} - pact_repository.find_latest_pacts_for_provider provider_name, options[:branch] + def find_latest_pacts_for_provider_by_consumer_branch provider_name, options = {} + options[:latest] = true + pact_repository.find_pacts_by_consumer_branch provider_name, options + end + + def find_pacts_for_provider_by_consumer_branch provider_name, options = {} + options[:latest] = false + pact_repository.find_pacts_by_consumer_branch provider_name, options + end + + def find_pacts_for_provider_and_consumer_by_consumer_branch provider_name, consumer, options = {} + options[:latest] = false + options[:consumer] = consumer + pact_repository.find_pacts_by_consumer_branch provider_name, options end def find_pact_versions_for_provider provider_name, options = {} diff --git a/spec/lib/pact_broker/api/resources/latest_provider_pacts_for_branch_spec.rb b/spec/lib/pact_broker/api/resources/latest_provider_pacts_for_branch_spec.rb index 6ac17c258..d3c013ea5 100644 --- a/spec/lib/pact_broker/api/resources/latest_provider_pacts_for_branch_spec.rb +++ b/spec/lib/pact_broker/api/resources/latest_provider_pacts_for_branch_spec.rb @@ -5,7 +5,7 @@ module Api module Resources describe LatestProviderPactsForBranch do before do - allow(PactBroker::Pacts::Service).to receive(:find_latest_pacts_for_provider_for_branch).and_return(pacts) + allow(PactBroker::Pacts::Service).to receive(:find_latest_pacts_for_provider_by_consumer_branch).and_return(pacts) allow(PactBroker::Api::Decorators::ProviderPactsDecorator).to receive(:new).and_return(decorator) allow_any_instance_of(LatestProviderPactsForBranch).to receive(:resource_exists?).and_return(provider) end @@ -19,7 +19,7 @@ module Resources context "with a branch" do it "finds the pacts with a branch" do - expect(PactBroker::Pacts::Service).to receive(:find_latest_pacts_for_provider_for_branch).with("Bar", branch: "prod") + expect(PactBroker::Pacts::Service).to receive(:find_latest_pacts_for_provider_by_consumer_branch).with("Bar", branch_name: "prod", main_branch: false) subject end