From 58d173db3f5614da802745146a286e940055de11 Mon Sep 17 00:00:00 2001 From: Beth Skurrie Date: Mon, 10 May 2021 11:33:21 +1000 Subject: [PATCH] feat: support deployments and releases as separate concepts (#426) Also allow multiple versions of an application to be deployed to the same environment, differentiated by a "target". --- ...te_currently_deployed_version_ids_table.rb | 13 +++ ...5_add_target_column_to_deployed_version.rb | 21 ++++ ...20210419_create_released_versions_table.rb | 17 +++ lib/pact_broker/api.rb | 2 + .../decorators/deployed_version_decorator.rb | 3 +- .../decorators/released_version_decorator.rb | 14 +++ .../api/decorators/version_decorator.rb | 10 ++ lib/pact_broker/api/pact_broker_urls.rb | 8 ++ ...ed_versions_for_version_and_environment.rb | 33 ++---- lib/pact_broker/api/resources/environments.rb | 2 +- .../api/resources/released_version.rb | 52 +++++++++ ...ed_versions_for_version_and_environment.rb | 94 +++++++++++++++ .../currently_deployed_version_id.rb | 14 +++ .../deployments/deployed_version.rb | 45 +++++++- .../deployments/deployed_version_service.rb | 33 ++++-- .../deployments/released_version.rb | 51 ++++++++ .../deployments/released_version_service.rb | 34 ++++++ .../pacts/pact_publication_dataset_module.rb | 11 +- lib/pact_broker/services.rb | 9 ++ lib/pact_broker/test/test_data_builder.rb | 28 +++-- ...ntly_deployed_versions_for_version_spec.rb | 27 +++++ spec/features/record_deployment_spec.rb | 58 +++++++--- spec/features/record_release_spec.rb | 58 ++++++++++ .../modifiable_resources.approved.json | 3 + .../default_base_resource_approval_spec.rb | 4 +- .../resources/default_base_resource_spec.rb | 3 +- .../api/resources/released_version_spec.rb | 61 ++++++++++ .../deployments/deployed_version_spec.rb | 109 ++++++++++++++++++ spec/lib/pact_broker/domain/version_spec.rb | 16 +-- .../matrix/integration_environment_spec.rb | 8 +- ...sitory_find_for_currently_deployed_spec.rb | 4 +- 31 files changed, 766 insertions(+), 79 deletions(-) create mode 100644 db/migrations/20210414_create_currently_deployed_version_ids_table.rb create mode 100644 db/migrations/20210415_add_target_column_to_deployed_version.rb create mode 100644 db/migrations/20210419_create_released_versions_table.rb create mode 100644 lib/pact_broker/api/decorators/released_version_decorator.rb create mode 100644 lib/pact_broker/api/resources/released_version.rb create mode 100644 lib/pact_broker/api/resources/released_versions_for_version_and_environment.rb create mode 100644 lib/pact_broker/deployments/currently_deployed_version_id.rb create mode 100644 lib/pact_broker/deployments/released_version.rb create mode 100644 lib/pact_broker/deployments/released_version_service.rb create mode 100644 spec/features/get_currently_deployed_versions_for_version_spec.rb create mode 100644 spec/features/record_release_spec.rb create mode 100644 spec/lib/pact_broker/api/resources/released_version_spec.rb create mode 100644 spec/lib/pact_broker/deployments/deployed_version_spec.rb diff --git a/db/migrations/20210414_create_currently_deployed_version_ids_table.rb b/db/migrations/20210414_create_currently_deployed_version_ids_table.rb new file mode 100644 index 000000000..997afe5a0 --- /dev/null +++ b/db/migrations/20210414_create_currently_deployed_version_ids_table.rb @@ -0,0 +1,13 @@ +Sequel.migration do + change do + create_table(:currently_deployed_version_ids, charset: 'utf8') do + primary_key :id + String :target_for_index, null: false + foreign_key :pacticipant_id, :pacticipants, null: false, on_delete: :cascade + foreign_key :environment_id, :environments, null: false, on_delete: :cascade + foreign_key :version_id, :versions, null: false, on_delete: :cascade + foreign_key :deployed_version_id, null: false, on_delete: :cascade + index [:pacticipant_id, :environment_id, :target_for_index], unique: true, name: "currently_deployed_version_pacticipant_environment_target_index" + end + end +end diff --git a/db/migrations/20210415_add_target_column_to_deployed_version.rb b/db/migrations/20210415_add_target_column_to_deployed_version.rb new file mode 100644 index 000000000..42916db7a --- /dev/null +++ b/db/migrations/20210415_add_target_column_to_deployed_version.rb @@ -0,0 +1,21 @@ +Sequel.migration do + up do + alter_table(:deployed_versions) do + add_column(:target, String) + add_column(:target_for_index, String, default: "", null: false) + set_column_allow_null(:replaced_previous_deployed_version) + set_column_allow_null(:currently_deployed) + drop_index [:pacticipant_id, :currently_deployed], name: "deployed_versions_pacticipant_id_currently_deployed_index" + end + end + + down do + alter_table(:deployed_versions) do + drop_column(:target) + drop_column(:target_for_index) + set_column_not_null(:replaced_previous_deployed_version) + set_column_not_null(:currently_deployed) + add_index [:pacticipant_id, :currently_deployed], name: "deployed_versions_pacticipant_id_currently_deployed_index" + end + end +end diff --git a/db/migrations/20210419_create_released_versions_table.rb b/db/migrations/20210419_create_released_versions_table.rb new file mode 100644 index 000000000..47a34025f --- /dev/null +++ b/db/migrations/20210419_create_released_versions_table.rb @@ -0,0 +1,17 @@ +Sequel.migration do + change do + create_table(:released_versions, charset: 'utf8') do + primary_key :id + String :uuid, null: false + foreign_key :version_id, :versions, null: false + Integer :pacticipant_id, null: false + foreign_key :environment_id, :environments, null: false + DateTime :created_at + DateTime :updated_at + DateTime :support_ended_at + index [:uuid], unique: true, name: "released_versions_uuid_index" + index [:version_id, :environment_id], unique: true, name: "released_versions_version_id_environment_id_index" + index [:support_ended_at], name: "released_version_support_ended_at_index" + end + end +end diff --git a/lib/pact_broker/api.rb b/lib/pact_broker/api.rb index d12ffcb7a..055ed2986 100644 --- a/lib/pact_broker/api.rb +++ b/lib/pact_broker/api.rb @@ -122,6 +122,8 @@ def self.build_api(application_context = PactBroker::ApplicationContext.default_ add ['environments'], Api::Resources::Environments, { resource_name: "environments" } add ['environments', :environment_uuid], Api::Resources::Environment, { resource_name: "environment" } add ['pacticipants', :pacticipant_name, 'versions', :pacticipant_version_number, 'deployed-versions', 'environment', :environment_uuid], Api::Resources::DeployedVersionsForVersionAndEnvironment, { resource_name: "deployed_versions_for_version_and_environment" } + add ['pacticipants', :pacticipant_name, 'versions', :pacticipant_version_number, 'released-versions', 'environment', :environment_uuid], Api::Resources::ReleasedVersionsForVersionAndEnvironment, { resource_name: "released_versions_for_version_and_environment" } + add ['released-versions', :uuid], Api::Resources::ReleasedVersion, { resource_name: "released_version" } end add ['integrations'], Api::Resources::Integrations, {resource_name: "integrations"} diff --git a/lib/pact_broker/api/decorators/deployed_version_decorator.rb b/lib/pact_broker/api/decorators/deployed_version_decorator.rb index 417a424df..e8b36a69f 100644 --- a/lib/pact_broker/api/decorators/deployed_version_decorator.rb +++ b/lib/pact_broker/api/decorators/deployed_version_decorator.rb @@ -6,10 +6,11 @@ module PactBroker module Api module Decorators class DeployedVersionDecorator < BaseDecorator + property :uuid property :version, :extend => EmbeddedVersionDecorator, writeable: false, embedded: true property :environment, :extend => EnvironmentDecorator, writeable: false, embedded: true property :currently_deployed, camelize: true - property :replaced_previous_deployed_version, camelize: true + property :target, camelize: true include Timestamps property :undeployedAt, getter: lambda { |_| undeployed_at ? FormatDateTime.call(undeployed_at) : nil }, writeable: false end diff --git a/lib/pact_broker/api/decorators/released_version_decorator.rb b/lib/pact_broker/api/decorators/released_version_decorator.rb new file mode 100644 index 000000000..e82a4d12c --- /dev/null +++ b/lib/pact_broker/api/decorators/released_version_decorator.rb @@ -0,0 +1,14 @@ +require 'pact_broker/api/decorators/base_decorator' + +module PactBroker + module Api + module Decorators + class ReleasedVersionDecorator < BaseDecorator + property :uuid + property :currently_supported, camelize: true + + include Timestamps + end + end + end +end diff --git a/lib/pact_broker/api/decorators/version_decorator.rb b/lib/pact_broker/api/decorators/version_decorator.rb index b5540bb8b..d9ec2e682 100644 --- a/lib/pact_broker/api/decorators/version_decorator.rb +++ b/lib/pact_broker/api/decorators/version_decorator.rb @@ -65,6 +65,16 @@ class VersionDecorator < BaseDecorator end end + links :'pb:record-release' do | context | + context.fetch(:environments, []).collect do | environment | + { + title: "Record release to #{environment.display_name}", + name: environment.name, + href: released_versions_for_version_and_environment_url(represented, environment, context.fetch(:base_url)) + } + end + end + curies do | options | [{ name: :pb, diff --git a/lib/pact_broker/api/pact_broker_urls.rb b/lib/pact_broker/api/pact_broker_urls.rb index 106ee3d55..6bb2053c4 100644 --- a/lib/pact_broker/api/pact_broker_urls.rb +++ b/lib/pact_broker/api/pact_broker_urls.rb @@ -318,10 +318,18 @@ def deployed_versions_for_version_and_environment_url(version, environment, base "#{version_url(base_url, version)}/deployed-versions/environment/#{environment.uuid}" end + def released_versions_for_version_and_environment_url(version, environment, base_url = '') + "#{version_url(base_url, version)}/released-versions/environment/#{environment.uuid}" + end + def deployed_version_url(deployed_version, base_url = '') "/deployed-versions/#{deployed_version.uuid}" end + def released_version_url(released_version, base_url = '') + "/released-versions/#{released_version.uuid}" + end + def hal_browser_url target_url, base_url = '' "#{base_url}/hal-browser/browser.html#" + target_url end diff --git a/lib/pact_broker/api/resources/deployed_versions_for_version_and_environment.rb b/lib/pact_broker/api/resources/deployed_versions_for_version_and_environment.rb index 9ea4aa20a..75aad8e07 100644 --- a/lib/pact_broker/api/resources/deployed_versions_for_version_and_environment.rb +++ b/lib/pact_broker/api/resources/deployed_versions_for_version_and_environment.rb @@ -5,6 +5,11 @@ module PactBroker module Api module Resources class DeployedVersionsForVersionAndEnvironment < BaseResource + def initialize + super + @existing_deployed_version = version && environment && deployed_version_service.find_currently_deployed_version_for_version_and_environment_and_target(version, environment, target) + end + def content_types_accepted [["application/json", :from_json]] end @@ -25,20 +30,12 @@ def post_is_create? true end - def malformed_request? - if request.post? - malformed_post_request? - else - false - end - end - def create_path - deployed_version_url(OpenStruct.new(uuid: deployed_version_uuid), base_url) + deployed_version_url(existing_deployed_version || OpenStruct.new(uuid: deployed_version_uuid), base_url) end def from_json - @deployed_version = deployed_version_service.create(deployed_version_uuid, version, environment, replaced_previous_deployed_version) + @deployed_version = existing_deployed_version || deployed_version_service.create(deployed_version_uuid, version, environment, target) response.body = decorator_class(:deployed_version_decorator).new(deployed_version).to_json(decorator_options) end @@ -52,7 +49,7 @@ def policy_name private - attr_reader :deployed_version + attr_reader :deployed_version, :existing_deployed_version def version @version ||= version_service.find_by_pacticipant_name_and_number(identifier_from_path) @@ -74,22 +71,14 @@ def deployed_version_uuid @deployed_version_uuid ||= deployed_version_service.next_uuid end - def replaced_previous_deployed_version - params(default: {})[:replacedPreviousDeployedVersion] + # TODO disallow an empty string because that is used as a NULL indicator in the database + def target + params(default: {})[:target]&.to_s end def title "Deployed versions for #{pacticipant_name} version #{pacticipant_version_number}" end - - def malformed_post_request? - if ![true, false].include?(replaced_previous_deployed_version) - set_json_validation_error_messages({ replacedPreviousDeployedVersion: ["must be one of true, false"] }) - true - else - false - end - end end end end diff --git a/lib/pact_broker/api/resources/environments.rb b/lib/pact_broker/api/resources/environments.rb index 55669e239..3fa85409e 100644 --- a/lib/pact_broker/api/resources/environments.rb +++ b/lib/pact_broker/api/resources/environments.rb @@ -43,7 +43,7 @@ def from_json end def policy_name - :'deployments::environment' + :'deployments::environments' end def to_json diff --git a/lib/pact_broker/api/resources/released_version.rb b/lib/pact_broker/api/resources/released_version.rb new file mode 100644 index 000000000..9b236c34f --- /dev/null +++ b/lib/pact_broker/api/resources/released_version.rb @@ -0,0 +1,52 @@ +require 'pact_broker/api/resources/base_resource' +require 'pact_broker/api/decorators/released_version_decorator' + +module PactBroker + module Api + module Resources + class ReleasedVersion < BaseResource + def content_types_provided + [["application/hal+json", :to_json]] + end + + def allowed_methods + ["GET", "OPTIONS"] + end + + def resource_exists? + !!released_version + end + + def to_json + decorator_class(:released_version_decorator).new(released_version).to_json(decorator_options) + end + + def policy_name + :'versions::versions' + end + + # For PF + def policy_record_context + # Not sure whether the context should be empty or the pacticipant should be nil + if released_version + { pacticipant: released_version.pacticipant } + else + {} + end + end + + private + + attr_reader :released_version + + def released_version + @released_version ||= released_version_service.find_by_uuid(uuid) + end + + def uuid + identifier_from_path[:uuid] + end + end + end + end +end diff --git a/lib/pact_broker/api/resources/released_versions_for_version_and_environment.rb b/lib/pact_broker/api/resources/released_versions_for_version_and_environment.rb new file mode 100644 index 000000000..ce37e7acf --- /dev/null +++ b/lib/pact_broker/api/resources/released_versions_for_version_and_environment.rb @@ -0,0 +1,94 @@ +require 'pact_broker/api/resources/base_resource' +require 'pact_broker/api/decorators/versions_decorator' + +module PactBroker + module Api + module Resources + class ReleasedVersionsForVersionAndEnvironment < BaseResource + def initialize + super + @existing_released_version = version && environment && released_version_service.find_released_version_for_version_and_environment(version, environment) + end + + def content_types_accepted + [["application/json", :from_json]] + end + + def content_types_provided + [["application/hal+json", :to_json]] + end + + def allowed_methods + ["GET", "POST", "OPTIONS"] + end + + def resource_exists? + !!version && !!environment + end + + def post_is_create? + true + end + + def create_path + released_version_url(existing_released_version || OpenStruct.new(uuid: next_released_version_uuid), base_url) + end + + def from_json + @released_version = existing_released_version || released_version_service.create(next_released_version_uuid, version, environment) + response.body = decorator_class(:released_version_decorator).new(released_version).to_json(decorator_options) + true + end + + def to_json + decorator_class(:released_versions_decorator).new(released_versions).to_json(decorator_options(title: title)) + end + + def policy_name + :'versions::versions' + end + + def finish_request + if request.post? && existing_released_version + response.code = 200 + end + super + end + + private + + attr_reader :released_version, :existing_released_version + + def version + @version ||= version_service.find_by_pacticipant_name_and_number(identifier_from_path) + end + + def environment + @environment ||= environment_service.find(environment_uuid) + end + + def released_versions + @released_versions ||= begin + if existing_released_version + [existing_released_version] + else + [] + end + end + end + + def environment_uuid + identifier_from_path[:environment_uuid] + end + + def next_released_version_uuid + @released_version_uuid ||= released_version_service.next_uuid + end + + def title + "Released versions for #{pacticipant.display_name} version #{pacticipant_version_number} in #{environment.display_name}" + end + end + end + end +end diff --git a/lib/pact_broker/deployments/currently_deployed_version_id.rb b/lib/pact_broker/deployments/currently_deployed_version_id.rb new file mode 100644 index 000000000..97bdfc37d --- /dev/null +++ b/lib/pact_broker/deployments/currently_deployed_version_id.rb @@ -0,0 +1,14 @@ +require 'sequel' +require 'pact_broker/repositories/helpers' + +module PactBroker + module Deployments + class CurrentlyDeployedVersionId < Sequel::Model + plugin :upsert, identifying_columns: [:pacticipant_id, :environment_id, :target_for_index] + + dataset_module do + include PactBroker::Repositories::Helpers + end + end + end +end diff --git a/lib/pact_broker/deployments/deployed_version.rb b/lib/pact_broker/deployments/deployed_version.rb index 8178133ef..dfb62e810 100644 --- a/lib/pact_broker/deployments/deployed_version.rb +++ b/lib/pact_broker/deployments/deployed_version.rb @@ -1,12 +1,17 @@ require 'pact_broker/repositories/helpers' +require 'pact_broker/deployments/currently_deployed_version_id' module PactBroker module Deployments - class DeployedVersion < Sequel::Model + DEPLOYED_VERSION_COLUMNS = [:id, :uuid, :version_id, :pacticipant_id, :environment_id, :target, :target_for_index, :created_at, :updated_at, :undeployed_at] + DEPLOYED_VERSION_DATASET = Sequel::Model.db[:deployed_versions].select(*DEPLOYED_VERSION_COLUMNS) + class DeployedVersion < Sequel::Model(DEPLOYED_VERSION_DATASET) many_to_one :version, :class => "PactBroker::Domain::Version", :key => :version_id, :primary_key => :id many_to_one :environment, :class => "PactBroker::Deployments::Environment", :key => :environment_id, :primary_key => :id + one_to_one :currently_deployed_version_id, :class => "PactBroker::Deployments::CurrentlyDeployedVersionId", key: :deployed_version_id, primary_key: :id plugin :timestamps, update_on_create: true + plugin :insert_ignore, identifying_columns: [:pacticipant_id, :version_id, :environment_id, :target_for_index] dataset_module do include PactBroker::Repositories::Helpers @@ -20,7 +25,19 @@ def last_deployed_version(pacticipant, environment) end def currently_deployed - where(currently_deployed: true) + where(id: CurrentlyDeployedVersionId.select(:deployed_version_id)) + end + + def undeployed + exclude(undeployed_at: nil) + end + + def for_version_and_environment_and_target(version, environment, target) + for_version_and_environment(version, environment).for_target(target) + end + + def for_target(target) + where(target: target) end def for_environment_name(environment_name) @@ -42,10 +59,30 @@ def for_environment(environment) def order_by_date_desc order(Sequel.desc(:created_at), Sequel.desc(:id)) end + + def record_undeployed + update(undeployed_at: Sequel.datetime_class.now) + end + end + + def before_validation + super + self.target_for_index = target.nil? ? "" : target + end + + def after_create + super + CurrentlyDeployedVersionId.new( + pacticipant_id: pacticipant_id, + environment_id: environment_id, + version_id: version_id, + target_for_index: target_for_index, + deployed_version_id: id + ).upsert end - def record_undeployed - update(currently_deployed: false, undeployed_at: Sequel.datetime_class.now) + def currently_deployed + !!currently_deployed_version_id end def version_number diff --git a/lib/pact_broker/deployments/deployed_version_service.rb b/lib/pact_broker/deployments/deployed_version_service.rb index c855c4d6b..276c27850 100644 --- a/lib/pact_broker/deployments/deployed_version_service.rb +++ b/lib/pact_broker/deployments/deployed_version_service.rb @@ -7,17 +7,14 @@ def self.next_uuid SecureRandom.uuid end - def self.create(uuid, version, environment, replaced_previous_deployed_version) - if replaced_previous_deployed_version - record_previous_version_undeployed(version.pacticipant, environment) - end + def self.create(uuid, version, environment, target) + record_previous_version_undeployed(version.pacticipant, environment, target) DeployedVersion.create( uuid: uuid, version: version, pacticipant_id: version.pacticipant_id, environment: environment, - currently_deployed: true, - replaced_previous_deployed_version: replaced_previous_deployed_version + target: target ) end @@ -28,6 +25,13 @@ def self.find_deployed_versions_for_version_and_environment(version, environment .all end + def self.find_currently_deployed_version_for_version_and_environment_and_target(version, environment, target) + DeployedVersion + .currently_deployed + .for_version_and_environment_and_target(version, environment, target) + .single_record + end + def self.find_deployed_versions_for_environment(environment) DeployedVersion .for_environment(environment) @@ -44,8 +48,21 @@ def self.find_currently_deployed_versions_for_pacticipant(pacticipant) .all end - def self.record_previous_version_undeployed(pacticipant, environment) - DeployedVersion.last_deployed_version(pacticipant, environment)&.record_undeployed + def self.record_version_undeployed(deployed_version) + deployed_version.currently_deployed_version_id.delete + # CurrentlyDeployedVersionId.where(pacticipant_id: pacticipant.id, environment_id: environment.id, target: target).delete + record_previous_version_undeployed(deployed_version.version.pacticipant, deployed_version.environment, deployed_version.target) + end + + # private + + def self.record_previous_version_undeployed(pacticipant, environment, target) + DeployedVersion.where( + undeployed_at: nil, + pacticipant_id: pacticipant.id, + environment_id: environment.id, + target: target + ).record_undeployed end end end diff --git a/lib/pact_broker/deployments/released_version.rb b/lib/pact_broker/deployments/released_version.rb new file mode 100644 index 000000000..7045e0bb3 --- /dev/null +++ b/lib/pact_broker/deployments/released_version.rb @@ -0,0 +1,51 @@ +require 'sequel' +require 'pact_broker/repositories/helpers' + +module PactBroker + module Deployments + class ReleasedVersion < Sequel::Model + many_to_one :pacticipant, :class => "PactBroker::Domain::Pacticipant", :key => :pacticipant_id, :primary_key => :id + many_to_one :version, :class => "PactBroker::Domain::Version", :key => :version_id, :primary_key => :id + many_to_one :environment, :class => "PactBroker::Deployments::Environment", :key => :environment_id, :primary_key => :id + + plugin :timestamps, update_on_create: true + plugin :insert_ignore, identifying_columns: [:version_id, :environment_id] + + dataset_module do + include PactBroker::Repositories::Helpers + + def currently_supported + where(support_ended_at: nil) + end + + def for_environment_name(environment_name) + where(environment_id: db[:environments].select(:id).where(name: environment_name)) + end + + def for_pacticipant_name(pacticipant_name) + where(pacticipant_id: db[:pacticipants].select(:id).where(name_like(:name, pacticipant_name))) + end + + def for_version_and_environment(version, environment) + where(version_id: version.id, environment_id: environment.id) + end + + def for_environment(environment) + where(environment_id: environment.id) + end + + def order_by_date_desc + order(Sequel.desc(:created_at), Sequel.desc(:id)) + end + + def record_support_ended + update(support_ended_at: Sequel.datetime_class.now) + end + end + + def currently_supported + support_ended_at == nil + end + end + end +end diff --git a/lib/pact_broker/deployments/released_version_service.rb b/lib/pact_broker/deployments/released_version_service.rb new file mode 100644 index 000000000..e81330339 --- /dev/null +++ b/lib/pact_broker/deployments/released_version_service.rb @@ -0,0 +1,34 @@ +require 'pact_broker/deployments/released_version' + +module PactBroker + module Deployments + class ReleasedVersionService + def self.next_uuid + SecureRandom.uuid + end + + def self.find_by_uuid(uuid) + ReleasedVersion.where(uuid: uuid).single_record + end + + def self.create(uuid, version, environment) + ReleasedVersion.new( + uuid: uuid, + version: version, + pacticipant_id: version.pacticipant_id, + environment: environment + ).insert_ignore + end + + def self.find_released_version_for_version_and_environment(version, environment) + ReleasedVersion + .for_version_and_environment(version, environment) + .single_record + end + + def self.record_version_support_ended(released_version) + released_version.record_support_ended + end + end + end +end diff --git a/lib/pact_broker/pacts/pact_publication_dataset_module.rb b/lib/pact_broker/pacts/pact_publication_dataset_module.rb index faa4b2061..33b36c0c8 100644 --- a/lib/pact_broker/pacts/pact_publication_dataset_module.rb +++ b/lib/pact_broker/pacts/pact_publication_dataset_module.rb @@ -151,12 +151,11 @@ def latest_for_consumer_tag(tag_name) end def for_currently_deployed_versions(environment_name) - deployed_versions_join = { - Sequel[:pact_publications][:consumer_version_id] => Sequel[:deployed_versions][:version_id], - Sequel[:deployed_versions][:currently_deployed] => true + currently_deployed_versions_join = { + Sequel[:pact_publications][:consumer_version_id] => Sequel[:currently_deployed_version_ids][:version_id] } environments_join = { - Sequel[:deployed_versions][:environment_id] => Sequel[:environments][:id], + Sequel[:currently_deployed_version_ids][:environment_id] => Sequel[:environments][:id], Sequel[:environments][:name] => environment_name }.compact @@ -164,7 +163,9 @@ def for_currently_deployed_versions(environment_name) if no_columns_selected? query = query.select_all_qualified.select_append(Sequel[:environments][:name].as(:environment_name)) end - query.join(:deployed_versions, deployed_versions_join).join(:environments, environments_join) + query + .join(:currently_deployed_version_ids, currently_deployed_versions_join) + .join(:environments, environments_join) end def successfully_verified_by_provider_branch(provider_id, provider_version_branch) diff --git a/lib/pact_broker/services.rb b/lib/pact_broker/services.rb index f0a47e4f5..3795f4f20 100644 --- a/lib/pact_broker/services.rb +++ b/lib/pact_broker/services.rb @@ -81,6 +81,10 @@ def deployed_version_service get(:deployed_version_service) end + def released_version_service + get(:released_version_service) + end + def contract_service get(:contract_service) end @@ -171,6 +175,11 @@ def register_default_services PactBroker::Deployments::DeployedVersionService end + register_service(:released_version_service) do + require 'pact_broker/deployments/released_version_service' + PactBroker::Deployments::ReleasedVersionService + end + register_service(:contract_service) do require 'pact_broker/contracts/service' PactBroker::Contracts::Service diff --git a/lib/pact_broker/test/test_data_builder.rb b/lib/pact_broker/test/test_data_builder.rb index 2fa1dba2b..6f789236e 100644 --- a/lib/pact_broker/test/test_data_builder.rb +++ b/lib/pact_broker/test/test_data_builder.rb @@ -28,6 +28,7 @@ require 'pact_broker/matrix/row' require 'pact_broker/deployments/environment_service' require 'pact_broker/deployments/deployed_version_service' +require 'pact_broker/deployments/released_version_service' require 'ostruct' module PactBroker @@ -52,6 +53,7 @@ class TestDataBuilder attr_reader :triggered_webhook attr_reader :environment attr_reader :deployed_version + attr_reader :released_version def initialize(params = {}) @now = DateTime.now @@ -401,13 +403,18 @@ def create_environment(name, params = {}) self end - def create_deployed_version_for_consumer_version(uuid: SecureRandom.uuid, currently_deployed: true, environment_name: environment&.name, created_at: nil) - create_deployed_version(uuid: uuid, currently_deployed: currently_deployed, version: consumer_version, environment_name: environment_name, created_at: created_at) + def create_deployed_version_for_consumer_version(uuid: SecureRandom.uuid, currently_deployed: true, environment_name: environment&.name, target: nil, created_at: nil) + create_deployed_version(uuid: uuid, currently_deployed: currently_deployed, version: consumer_version, environment_name: environment_name, target: target, created_at: created_at) self end - def create_deployed_version_for_provider_version(uuid: SecureRandom.uuid, currently_deployed: true, environment_name: environment&.name, created_at: nil) - create_deployed_version(uuid: uuid, currently_deployed: currently_deployed, version: provider_version, environment_name: environment_name, created_at: created_at) + def create_released_version_for_consumer_version(uuid: SecureRandom.uuid, currently_supported: true, environment_name: environment&.name, created_at: nil) + create_released_version(uuid: uuid, currently_supported: currently_supported, version: consumer_version, environment_name: environment_name, created_at: created_at) + self + end + + def create_deployed_version_for_provider_version(uuid: SecureRandom.uuid, currently_deployed: true, environment_name: environment&.name, target: nil, created_at: nil) + create_deployed_version(uuid: uuid, currently_deployed: currently_deployed, version: provider_version, environment_name: environment_name, target: target, created_at: created_at) self end @@ -524,13 +531,20 @@ def random_json_content(consumer_name, provider_name) private - def create_deployed_version(uuid: , currently_deployed: , version:, environment_name: , created_at: nil) + def create_deployed_version(uuid: , currently_deployed: , version:, environment_name: , target: nil, created_at: nil) env = find_environment(environment_name) - @deployed_version = PactBroker::Deployments::DeployedVersionService.create(uuid, version, env, false) - @deployed_version.update(currently_deployed: false) unless currently_deployed + @deployed_version = PactBroker::Deployments::DeployedVersionService.create(uuid, version, env, target) + PactBroker::Deployments::DeployedVersionService.record_version_undeployed(deployed_version) unless currently_deployed set_created_at_if_set(created_at, :deployed_versions, id: deployed_version.id) end + def create_released_version(uuid: , currently_supported: true, version:, environment_name: , created_at: nil) + env = find_environment(environment_name) + @released_version = PactBroker::Deployments::ReleasedVersionService.create(uuid, version, env) + PactBroker::Deployments::ReleasedVersionService.record_version_support_ended(released_version) unless currently_supported + set_created_at_if_set(created_at, :released_versions, id: released_version.id) + end + def pact_version_id PactBroker::Pacts::PactPublication.find(id: @pact.id).pact_version_id end diff --git a/spec/features/get_currently_deployed_versions_for_version_spec.rb b/spec/features/get_currently_deployed_versions_for_version_spec.rb new file mode 100644 index 000000000..02e25cc67 --- /dev/null +++ b/spec/features/get_currently_deployed_versions_for_version_spec.rb @@ -0,0 +1,27 @@ +RSpec.describe "Get currently deployed versions for version" do + let!(:version) { td.create_consumer("Foo").create_consumer_version("1").and_return(:consumer_version) } + let!(:test_environment) { td.create_environment("test").and_return(:environment) } + let!(:prod_environment) { td.create_environment("prod").and_return(:environment) } + let!(:deployed_version) do + td.create_deployed_version_for_consumer_version(environment_name: "test", created_at: DateTime.now - 2) + .create_deployed_version_for_consumer_version(environment_name: "prod", created_at: DateTime.now - 1) + end + + let(:path) do + PactBroker::Api::PactBrokerUrls.deployed_versions_for_version_and_environment_url( + version, + test_environment + ) + end + + let(:response_body_hash) { JSON.parse(subject.body, symbolize_names: true) } + + subject { get(path, nil, { "HTTP_ACCEPT" => "application/hal+json" }) } + + it "returns a list of deployed versions" do + expect(response_body_hash[:_embedded][:deployedVersions]).to be_a(Array) + expect(response_body_hash[:_embedded][:deployedVersions].size).to eq 1 + expect(response_body_hash[:_links][:self][:title]).to eq "Deployed versions for Foo version 1" + expect(response_body_hash[:_links][:self][:href]).to end_with(path) + end +end diff --git a/spec/features/record_deployment_spec.rb b/spec/features/record_deployment_spec.rb index 329861454..08769b2df 100644 --- a/spec/features/record_deployment_spec.rb +++ b/spec/features/record_deployment_spec.rb @@ -1,5 +1,5 @@ # -# pact-broker record-deployment --pacticipant Foo --version 1 --environment test --replace-previous-deployed-version +# pact-broker record-deployment --pacticipant Foo --version 1 --environment test --target instance1 # describe "Record deployment" do @@ -8,18 +8,19 @@ .create_consumer("Foo") .create_consumer_version("1") .create_deployed_version_for_consumer_version + .create_consumer_version("2") end let(:headers) { {"CONTENT_TYPE" => "application/json"} } let(:response_body) { JSON.parse(subject.body, symbolize_names: true) } - let(:version_path) { "/pacticipants/Foo/versions/1" } + let(:version_path) { "/pacticipants/Foo/versions/2" } let(:version_response) { get(version_path, nil, { "HTTP_ACCEPT" => "application/hal+json" } ) } - let(:replaced_previous) { true } + let(:target) { nil } let(:path) do JSON.parse(version_response.body)["_links"]["pb:record-deployment"] .find{ |relation| relation["name"] == "test" } .fetch("href") end - let(:request_body) { { replacedPreviousDeployedVersion: replaced_previous }.to_json } + let(:request_body) { { target: target }.to_json } subject { post(path, request_body, headers) } @@ -31,35 +32,62 @@ it "returns the newly created deployment" do expect(response_body[:currentlyDeployed]).to be true + expect(response_body).to_not have_key(:target) + end + + it "creates a new deployed version" do + expect { subject }.to change { PactBroker::Deployments::DeployedVersion.count }.by(1) end it "marks the previous deployment as not currently deployed" do - expect { subject }.to change { PactBroker::Deployments::DeployedVersion.currently_deployed.collect(&:uuid) } + expect { subject }.to change { PactBroker::Deployments::DeployedVersion.undeployed.count }.by(1) end it "does not change the overall count of currently deployed versions" do expect { subject }.to_not change { PactBroker::Deployments::DeployedVersion.currently_deployed.count } end - context "with an empty body" do - let(:request_body) { nil } + context "when the version is already currently deployed to the environment and target" do + before do + td.create_deployed_version_for_consumer_version(uuid: "1234") + end - it { is_expected.to be_a_json_error_response("must be one of true, false") } + it "does not mark anything as undeployed" do + expect { subject }.to_not change { PactBroker::Deployments::DeployedVersion.undeployed.collect(&:uuid) } + end - it "does not change the overall count of currently deployed versions" do - expect { subject }.to_not change { PactBroker::Deployments::DeployedVersion.currently_deployed.count } + it "returns the existing deployed version" do + expect(response_body[:uuid]).to eq "1234" end end - context "when the deployment does not replace the previous deployed version" do - let(:replaced_previous) { false } + context "when the version was previously deployed to the environment and target but isn't any more" do + before do + td.create_deployed_version_for_consumer_version(uuid: "1234") + .create_consumer_version("3") + .create_deployed_version_for_consumer_version(uuid: "5678") + end - it "leaves the previous deployed version as currently deployed" do - expect { subject }.to change { PactBroker::Deployments::DeployedVersion.currently_deployed.count }.by(1) + it "creates a new deployed version" do + expect { subject }.to change { PactBroker::Deployments::DeployedVersion.count }.by(1) end + end - it "increases the overall count of currently deployed versions" do + context "with an empty body" do + let(:request_body) { nil } + + it { is_expected.to be_a_hal_json_created_response } + end + + context "when the deployment is to a different target" do + let(:target) { "foo" } + + it "creates a new deployed version" do expect { subject }.to change { PactBroker::Deployments::DeployedVersion.currently_deployed.count }.by(1) end + + it "sets the target" do + expect(response_body).to have_key(:target) + end end end diff --git a/spec/features/record_release_spec.rb b/spec/features/record_release_spec.rb new file mode 100644 index 000000000..56cac02ae --- /dev/null +++ b/spec/features/record_release_spec.rb @@ -0,0 +1,58 @@ +# +# pact-broker record-release --pacticipant Foo --version 1 --environment production +# + +describe "Record release" do + before do + td.create_environment("production", uuid: "1234") + .create_consumer("Foo") + .create_consumer_version("1") + end + let(:headers) { {"CONTENT_TYPE" => "application/json"} } + let(:response_body) { JSON.parse(subject.body, symbolize_names: true) } + let(:version_path) { "/pacticipants/Foo/versions/1" } + let(:version_response) { get(version_path, nil, { "HTTP_ACCEPT" => "application/hal+json" } ) } + let(:target) { nil } + let(:path) do + JSON.parse(version_response.body)["_links"]["pb:record-release"] + .find{ |relation| relation["name"] == "production" } + .fetch("href") + end + + subject { post(path, nil, headers) } + + it { is_expected.to be_a_hal_json_created_response } + + it "returns the Location header" do + expect(subject.headers["Location"]).to start_with "http://example.org/released-versions/" + end + + it "returns the newly created release" do + expect(response_body[:currentlySupported]).to be true + end + + it "creates a new released version" do + expect { subject }.to change { PactBroker::Deployments::ReleasedVersion.count }.by(1) + end + + context "when the version is already released" do + before do + td.create_released_version_for_consumer_version(uuid: "1234") + end + + it "does not change the overall count of released versions" do + expect { subject }.to_not change { PactBroker::Deployments::ReleasedVersion.count } + end + + it "returns the existing released version" do + expect(response_body[:uuid]).to eq "1234" + end + + it { is_expected.to be_a_hal_json_success_response } + end + + it "creates a released version resource" do + get(subject.headers["Location"]) + expect(last_response.status).to eq 200 + end +end diff --git a/spec/fixtures/approvals/modifiable_resources.approved.json b/spec/fixtures/approvals/modifiable_resources.approved.json index 33989d462..596712ec0 100644 --- a/spec/fixtures/approvals/modifiable_resources.approved.json +++ b/spec/fixtures/approvals/modifiable_resources.approved.json @@ -58,6 +58,9 @@ { "resource_class_name": "PactBroker::Api::Resources::PublishContracts" }, + { + "resource_class_name": "PactBroker::Api::Resources::ReleasedVersionsForVersionAndEnvironment" + }, { "resource_class_name": "PactBroker::Api::Resources::Tag" }, diff --git a/spec/lib/pact_broker/api/resources/default_base_resource_approval_spec.rb b/spec/lib/pact_broker/api/resources/default_base_resource_approval_spec.rb index 4cbc86c0d..9884ed940 100644 --- a/spec/lib/pact_broker/api/resources/default_base_resource_approval_spec.rb +++ b/spec/lib/pact_broker/api/resources/default_base_resource_approval_spec.rb @@ -14,7 +14,9 @@ module Resources it "specifies which pacticipant is the one relevant to the policy" do data = pact_broker_resource_classes.collect do | resource_class | - request = double('request', uri: URI("http://example.org")).as_null_object + application_context = PactBroker::ApplicationContext.default_application_context + path_info = { pacticipant_name: "Foo", pacticipant_version_number: "1", application_context: application_context } + request = double('request', uri: URI("http://example.org"), path_info: path_info).as_null_object response = double('response') resource = resource_class.new(request, response) modifiable = resource.allowed_methods.any?{ | method | %w{PATCH POST PUT DELETE}.include?(method) } diff --git a/spec/lib/pact_broker/api/resources/default_base_resource_spec.rb b/spec/lib/pact_broker/api/resources/default_base_resource_spec.rb index 76d911ec0..e44b74fe9 100644 --- a/spec/lib/pact_broker/api/resources/default_base_resource_spec.rb +++ b/spec/lib/pact_broker/api/resources/default_base_resource_spec.rb @@ -181,6 +181,7 @@ module Resources ALL_RESOURCES = ObjectSpace.each_object(::Class) .select { |klass| klass < DefaultBaseResource } .select { |klass| !klass.name.end_with?("BaseResource") } + .sort_by(&:name) ALL_RESOURCES.each do | resource_class | describe resource_class do @@ -191,7 +192,7 @@ module Resources end let(:application_context) { PactBroker::ApplicationContext.default_application_context(before_resource: before_resource, after_resource: after_resource) } let(:request) { double('request', uri: URI("http://example.org"), path_info: path_info).as_null_object } - let(:path_info) { {} } + let(:path_info) { { pacticipant_name: "foo", pacticipant_version_number: "1" } } let(:response) { double('response').as_null_object } let(:resource) { resource_class.new(request, response) } let(:before_resource) { double('before_resource', call: nil) } diff --git a/spec/lib/pact_broker/api/resources/released_version_spec.rb b/spec/lib/pact_broker/api/resources/released_version_spec.rb new file mode 100644 index 000000000..63ea39897 --- /dev/null +++ b/spec/lib/pact_broker/api/resources/released_version_spec.rb @@ -0,0 +1,61 @@ +require 'pact_broker/api/resources/released_version' + +module PactBroker + module Api + module Resources + describe ReleasedVersion do + before do + allow_any_instance_of(described_class).to receive(:released_version_service).and_return(released_version_service) + allow(released_version_service).to receive(:find_by_uuid).and_return(released_version) + allow(PactBroker::Api::Decorators::ReleasedVersionDecorator).to receive(:new).and_return(decorator) + end + + let(:released_version) { instance_double("PactBroker::Deployments::ReleasedVersion") } + let(:parsed_released_version) { double("parsed released_version") } + let(:released_version_service) { class_double("PactBroker::Deployments::ReleasedVersionService").as_stubbed_const } + let(:path) { "/released-versions/#{uuid}" } + let(:uuid) { "12345678" } + let(:rack_headers) do + { + "HTTP_ACCEPT" => "application/hal+json" + } + end + let(:decorator) do + instance_double("PactBroker::Api::Decorators::ReleasedVersionDecorator", + to_json: "response", + from_json: parsed_released_version + ) + end + + describe "GET" do + subject { get(path, nil, rack_headers) } + + it "attempts to find the ReleasedVersion" do + expect(PactBroker::Deployments::ReleasedVersionService).to receive(:find_by_uuid).with(uuid) + subject + end + + context "when the released_version does not exist" do + let(:released_version) { nil } + + it { is_expected.to be_a_404_response } + end + + context "when the ReleasedVersion exists" do + it "generates a JSON representation of the ReleasedVersion" do + expect(PactBroker::Api::Decorators::ReleasedVersionDecorator).to receive(:new).with(released_version) + expect(decorator).to receive(:to_json).with(user_options: hash_including(base_url: "http://example.org")) + subject + end + + it { is_expected.to be_a_hal_json_success_response } + + it "includes the JSON representation in the response body" do + expect(subject.body).to eq "response" + end + end + end + end + end + end +end diff --git a/spec/lib/pact_broker/deployments/deployed_version_spec.rb b/spec/lib/pact_broker/deployments/deployed_version_spec.rb new file mode 100644 index 000000000..616e06cdc --- /dev/null +++ b/spec/lib/pact_broker/deployments/deployed_version_spec.rb @@ -0,0 +1,109 @@ +require 'pact_broker/deployments/deployed_version' + +module PactBroker + module Deployments + describe DeployedVersion do + let!(:environment) { td.create_environment("test").and_return(:environment) } + let!(:version) do + td.create_consumer + .create_consumer_version("1") + .and_return(:consumer_version) + end + + let(:params) do + { + uuid: "1234", + version_id: version.id, + pacticipant_id: version.pacticipant_id, + environment_id: environment.id, + target: target + } + end + + let(:target) { nil } + + subject { DeployedVersion.create(params) } + + it "creates a CurrentlyDeployedVersionId" do + expect{ subject }.to change { CurrentlyDeployedVersionId.count}.by(1) + end + + it "sets the currently deployed version id" do + expect(subject.currently_deployed_version_id.deployed_version_id).to eq subject.id + end + + context "when a deployed version for the same environment and nil instance name exists" do + before do + td.create_deployed_version_for_consumer_version(environment_name: "test", target: target) + end + + it "does not make a new currently deployed version id" do + expect{ subject }.to change { CurrentlyDeployedVersionId.count}.by(0) + end + + it "stores an empty string as the target_for_index in the database so that the unique constraint works" do + expect(subject.target).to be nil + expect(subject.target_for_index).to eq "" + expect(subject.currently_deployed_version_id.target_for_index).to eq "" + end + + it "updates the currently deployed version id" do + expect { subject }.to change { CurrentlyDeployedVersionId.last.deployed_version_id } + expect(CurrentlyDeployedVersionId.last.deployed_version_id).to eq subject.id + end + + its(:currently_deployed) { is_expected.to be true } + end + + context "when a deployed version for the same environment and same instance name exists" do + before do + td.create_deployed_version_for_consumer_version(environment_name: "test", target: target) + end + + let(:target) { "green" } + + its(:currently_deployed) { is_expected.to be true } + + it "does not make a new currently deployed version id" do + expect{ subject }.to change { CurrentlyDeployedVersionId.count}.by(0) + end + + it "updates the currently deployed version id" do + expect { subject }.to change { CurrentlyDeployedVersionId.last.deployed_version_id } + expect(CurrentlyDeployedVersionId.last.deployed_version_id).to eq subject.id + end + + describe "the previously deployed version" do + it "is no longer currently deployed" do + subject + version.refresh + expect(version.deployed_versions.first.currently_deployed).to be false + end + end + end + + context "when a deployed version for the same environment and different instance name exists" do + before do + td.create_deployed_version_for_consumer_version(environment_name: "test", target: "blue") + end + + let(:target) { "green" } + + it "makes a new currently deployed version id" do + expect{ subject }.to change { CurrentlyDeployedVersionId.count}.by(1) + expect(CurrentlyDeployedVersionId.last.deployed_version_id).to eq subject.id + end + + describe "the previously deployed version" do + it "is still currently deployed" do + subject + version.refresh + expect(version.deployed_versions.first.currently_deployed).to be true + end + end + + its(:currently_deployed) { is_expected.to be true } + end + end + end +end diff --git a/spec/lib/pact_broker/domain/version_spec.rb b/spec/lib/pact_broker/domain/version_spec.rb index 292fcac94..5e3b821ba 100644 --- a/spec/lib/pact_broker/domain/version_spec.rb +++ b/spec/lib/pact_broker/domain/version_spec.rb @@ -148,12 +148,12 @@ def version_numbers td.create_environment("test") .create_consumer("Foo") .create_consumer_version("1") - .create_deployed_version_for_consumer_version + .create_deployed_version_for_consumer_version(target: "1") .create_consumer_version("2") .create_environment("prod") - .create_deployed_version_for_consumer_version + .create_deployed_version_for_consumer_version(target: "2") .create_consumer_version("3") - .create_deployed_version_for_consumer_version + .create_deployed_version_for_consumer_version(target: "3") .create_consumer_version("4") .create_deployed_version_for_consumer_version(currently_deployed: false) .create_consumer_version("5") @@ -174,15 +174,15 @@ def version_numbers td.create_environment("test") .create_consumer("Foo") .create_consumer_version("1") - .create_deployed_version_for_consumer_version + .create_deployed_version_for_consumer_version(target: "1") .create_consumer_version("2") .create_environment("prod") - .create_deployed_version_for_consumer_version + .create_deployed_version_for_consumer_version(target: "2") .create_consumer_version("3") .create_consumer_version("5") .create_consumer("Bar") .create_consumer_version("10") - .create_deployed_version_for_consumer_version + .create_deployed_version_for_consumer_version(target: "3") .create_consumer_version("11") .create_deployed_version_for_consumer_version(currently_deployed: false) end @@ -376,9 +376,9 @@ def version_numbers .create_consumer("Foo") .create_consumer_version("1") .create_deployed_version_for_consumer_version(currently_deployed: false, environment_name: "test") - .create_deployed_version_for_consumer_version(currently_deployed: true, environment_name: "prod") + .create_deployed_version_for_consumer_version(currently_deployed: true, environment_name: "prod", target: "1") .create_consumer_version("2") - .create_deployed_version_for_consumer_version(currently_deployed: true, environment_name: "prod") + .create_deployed_version_for_consumer_version(currently_deployed: true, environment_name: "prod", target: "2") end it "returns the currently active deployed versions" do diff --git a/spec/lib/pact_broker/matrix/integration_environment_spec.rb b/spec/lib/pact_broker/matrix/integration_environment_spec.rb index 3db8f09af..369f761ce 100644 --- a/spec/lib/pact_broker/matrix/integration_environment_spec.rb +++ b/spec/lib/pact_broker/matrix/integration_environment_spec.rb @@ -99,11 +99,11 @@ module Matrix before do td.create_environment("prod") .create_pact_with_hierarchy("Foo", "1", "Bar") - .create_deployed_version_for_consumer_version(environment_name: "prod") + .create_deployed_version_for_consumer_version(environment_name: "prod", target: "1") .create_verification(provider_version: "10") .create_consumer_version("2") .create_pact - .create_deployed_version_for_consumer_version(environment_name: "prod") + .create_deployed_version_for_consumer_version(environment_name: "prod", target: "2") end let(:selectors) { [ UnresolvedSelector.new(pacticipant_name: "Bar", pacticipant_version_number: "10") ]} @@ -137,11 +137,11 @@ module Matrix td.create_environment("prod") .create_pact_with_hierarchy("Foo", "1", "Bar") .create_verification(provider_version: "10") - .create_deployed_version_for_provider_version(environment_name: "prod") + .create_deployed_version_for_provider_version(environment_name: "prod", target: "1") .create_consumer_version("2") .create_pact .create_provider_version("11") - .create_deployed_version_for_provider_version(environment_name: "prod") + .create_deployed_version_for_provider_version(environment_name: "prod", target: "2") end let(:selectors) { [ UnresolvedSelector.new(pacticipant_name: "Foo", pacticipant_version_number: "2") ]} diff --git a/spec/lib/pact_broker/pacts/repository_find_for_currently_deployed_spec.rb b/spec/lib/pact_broker/pacts/repository_find_for_currently_deployed_spec.rb index f6059cf85..4575e5a71 100644 --- a/spec/lib/pact_broker/pacts/repository_find_for_currently_deployed_spec.rb +++ b/spec/lib/pact_broker/pacts/repository_find_for_currently_deployed_spec.rb @@ -20,10 +20,10 @@ def find_by_consumer_name_and_consumer_version_number(consumer_name, consumer_ve .create_pact_with_hierarchy("Foo", "1", "Bar") .create_deployed_version_for_consumer_version(currently_deployed: false) .create_pact_with_hierarchy("Foo", "2", "Bar") - .create_deployed_version_for_consumer_version(currently_deployed: true) + .create_deployed_version_for_consumer_version(currently_deployed: true, target: "1") .create_pact_with_hierarchy("Waffle", "3", "Bar") .create_pact_with_hierarchy("Waffle", "4", "Bar") - .create_deployed_version_for_consumer_version(currently_deployed: true) + .create_deployed_version_for_consumer_version(currently_deployed: true, target: "2") end let(:consumer_version_selectors) do