Implement single-owner reconciliation modes

This commit is contained in:
2026-06-08 18:30:52 +00:00
parent b7db3993fb
commit 93821ea6f9
6 changed files with 431 additions and 20 deletions

View File

@@ -34,6 +34,7 @@ type Request struct {
Publish config.PublishPolicy
Transform config.Transform
Links *config.Links
Reconciliation config.ReconciliationPolicy
Transformers TransformerResolver
Transfer config.TransferPolicy
DistributorVersion string
@@ -55,6 +56,7 @@ type Plan struct {
Reason string
Force bool
PrimaryURL string
Reconciliation config.ReconciliationPolicy
Outputs []Output
ExistingState *state.DistributorState
}
@@ -88,6 +90,7 @@ func Build(ctx context.Context, req Request) (Plan, error) {
}
comparison := compareDestination(req, status)
action, reason := actionForComparison(comparison, req.Transfer, req.Force)
reconciliation := normalizeReconciliation(req.Reconciliation)
plan := Plan{
PipelineID: req.PipelineID,
DestinationID: req.DestinationID,
@@ -99,6 +102,7 @@ func Build(ctx context.Context, req Request) (Plan, error) {
Reason: reason,
Force: action == ActionForceReplace,
PrimaryURL: primaryURL,
Reconciliation: reconciliation,
Outputs: outputs,
ExistingState: status.State,
}
@@ -124,9 +128,21 @@ func validateRequest(req Request) error {
if err := config.ValidatePublishTransformPolicy(req.Publish, req.Transform); err != nil {
return fmt.Errorf("publish/transform policy: %w", err)
}
switch normalizeReconciliation(req.Reconciliation).Mode {
case config.ReconciliationModeReplace, config.ReconciliationModeMerge:
default:
return fmt.Errorf("reconciliation.mode must be %s or %s", config.ReconciliationModeReplace, config.ReconciliationModeMerge)
}
return nil
}
func normalizeReconciliation(policy config.ReconciliationPolicy) config.ReconciliationPolicy {
if policy.Mode == "" {
policy.Mode = config.ReconciliationModeReplace
}
return policy
}
func compareDestination(req Request, status state.DestinationStatus) state.Comparison {
comparison := state.Compare(req.SourceBundle.Manifest, req.PipelineID, req.DestinationID, status)
if req.PathMapping != config.PathMappingFixed || comparison.Outcome != state.OutcomeDifferentSourceConflict || status.State == nil {