diff --git a/lib/api-helper/machine/AbstractSoftwareDeliveryMachine.ts b/lib/api-helper/machine/AbstractSoftwareDeliveryMachine.ts index 6247862de..c7ba54b3d 100644 --- a/lib/api-helper/machine/AbstractSoftwareDeliveryMachine.ts +++ b/lib/api-helper/machine/AbstractSoftwareDeliveryMachine.ts @@ -43,10 +43,7 @@ import { ExtensionPack } from "../../api/machine/ExtensionPack"; import { registrableManager } from "../../api/machine/Registerable"; import { SoftwareDeliveryMachine } from "../../api/machine/SoftwareDeliveryMachine"; import { SoftwareDeliveryMachineConfiguration } from "../../api/machine/SoftwareDeliveryMachineOptions"; -import { - GoalSetter, - GoalSettingStructure, -} from "../../api/mapping/GoalSetter"; +import { GoalSetter } from "../../api/mapping/GoalSetter"; import { PushMapping } from "../../api/mapping/PushMapping"; import { PushTest } from "../../api/mapping/PushTest"; import { AnyPush } from "../../api/mapping/support/commonPushTests"; @@ -56,7 +53,11 @@ import { CodeTransformRegistration } from "../../api/registration/CodeTransformR import { CommandHandlerRegistration } from "../../api/registration/CommandHandlerRegistration"; import { EventHandlerRegistration } from "../../api/registration/EventHandlerRegistration"; import { GeneratorRegistration } from "../../api/registration/GeneratorRegistration"; -import { GoalApprovalRequestVoter } from "../../api/registration/GoalApprovalRequestVoter"; +import { + GoalApprovalRequestVoteDecisionManager, + GoalApprovalRequestVoter, + UnanimousGoalApprovalRequestVoteDecisionManager, +} from "../../api/registration/GoalApprovalRequestVoter"; import { IngesterRegistration } from "../../api/registration/IngesterRegistration"; import { InterpretLog } from "../../spi/log/InterpretedLog"; import { DefaultGoalImplementationMapper } from "../goal/DefaultGoalImplementationMapper"; @@ -85,6 +86,9 @@ export abstract class AbstractSoftwareDeliveryMachine(cmd: CommandHandlerRegistration

): this { this.registrationManager.addCommand(cmd); return this; diff --git a/lib/api/machine/GoalDrivenMachine.ts b/lib/api/machine/GoalDrivenMachine.ts index cdbac75fd..8f192f871 100644 --- a/lib/api/machine/GoalDrivenMachine.ts +++ b/lib/api/machine/GoalDrivenMachine.ts @@ -21,7 +21,10 @@ import { GoalImplementationMapper } from "../goal/support/GoalImplementationMapp import { PushListenerInvocation } from "../listener/PushListener"; import { GoalSetter } from "../mapping/GoalSetter"; import { PushMapping } from "../mapping/PushMapping"; -import { GoalApprovalRequestVoter } from "../registration/GoalApprovalRequestVoter"; +import { + GoalApprovalRequestVoteDecisionManager, + GoalApprovalRequestVoter, +} from "../registration/GoalApprovalRequestVoter"; import { MachineConfiguration } from "./MachineConfiguration"; import { SoftwareDeliveryMachineConfiguration } from "./SoftwareDeliveryMachineOptions"; @@ -74,4 +77,10 @@ export interface GoalDrivenMachine Promise; + +/** + * Decide resulting vote on a set of votes + */ +export type GoalApprovalRequestVoteDecisionManager = + (votes: GoalApprovalRequestVoteResult[]) => GoalApprovalRequestVote; + + +/** + * Default GoalApprovalRequestVoteDecisionManager that decides unanimously on votes. + * One denied vote will deny the approval request; all granted votes with grant the request. + * All other votes with result in an abstained approval request. + * @param votes + */ +export const UnanimousGoalApprovalRequestVoteDecisionManager: GoalApprovalRequestVoteDecisionManager = + (votes: GoalApprovalRequestVoteResult[]) => { + logger.debug(`Deciding on provided votes '${votes.map(v => v.vote).join(", ")}'`); + if (votes.some(v => v.vote === GoalApprovalRequestVote.Denied)) { + logger.debug("At least one denied vote. Denying approval request"); + return GoalApprovalRequestVote.Denied; + } else if (!votes.some(v => v.vote !== GoalApprovalRequestVote.Granted)) { + logger.debug("All votes granted. Granting approval request"); + return GoalApprovalRequestVote.Granted; + } else { + logger.debug("Some abstain and granted votes. Abstaining approval request"); + return GoalApprovalRequestVote.Abstain; + } + }; \ No newline at end of file