refactor(plugin): centralize workload conversion + container cleanup

Three packages (api, reconciler, webhook) each carried a private 30-line
toPluginWorkload() copy that had drifted — only the api version logged
malformed public_faces JSON; the others swallowed it. Hoist the single
implementation to plugin.WorkloadFromStore() (convert.go); store is
already a plugin dependency so no new import edge or cycle forms.

Likewise the dockerfile and static sources each had a private
removeContainerByName() that disagreed (remove-all vs stop-at-first).
Docker enforces unique container names, so the two were equivalent for
every reachable state; converge on plugin.RemoveContainerByName()
(container.go, stop-at-first) with a note on why remove-all was moot.

Callers migrated; old copies removed. Adds convert_test.go pinning the
field-by-field contract and JSON edge cases.
This commit is contained in:
2026-06-19 16:21:54 +03:00
parent 6492944c8f
commit c8e71a0c34
9 changed files with 227 additions and 135 deletions
-28
View File
@@ -338,31 +338,3 @@ func buildInboundEvent(body []byte, headers http.Header) (plugin.InboundEvent, e
gitEvt.Headers = headers
return gitEvt, nil
}
// toPluginWorkload mirrors the api-layer converter but kept local so the
// webhook package does not depend on internal/api. Inlining is cheap and
// avoids elevating that converter to a shared package.
func toPluginWorkload(w store.Workload) plugin.Workload {
var faces []plugin.PublicFace
if w.PublicFaces != "" {
_ = json.Unmarshal([]byte(w.PublicFaces), &faces)
}
return plugin.Workload{
ID: w.ID,
Name: w.Name,
GroupID: w.AppID,
ParentWorkloadID: w.ParentWorkloadID,
SourceKind: w.SourceKind,
SourceConfig: json.RawMessage(w.SourceConfig),
TriggerKind: w.TriggerKind,
TriggerConfig: json.RawMessage(w.TriggerConfig),
PublicFaces: faces,
NotificationURL: w.NotificationURL,
NotificationSecret: w.NotificationSecret,
WebhookSecret: w.WebhookSecret,
WebhookSigningSecret: w.WebhookSigningSecret,
WebhookRequireSignature: w.WebhookRequireSignature,
CreatedAt: w.CreatedAt,
UpdatedAt: w.UpdatedAt,
}
}
+3 -4
View File
@@ -318,7 +318,7 @@ func (h *Handler) fireBinding(
b store.WorkloadTriggerBinding,
evt plugin.InboundEvent,
) (bool, string) {
pwl := toPluginWorkload(row)
pwl := plugin.WorkloadFromStore(row)
pwl, err := plugin.WithEffectiveTrigger(pwl, trg.Kind,
json.RawMessage(trg.Config), json.RawMessage(b.BindingConfig))
if err != nil {
@@ -395,7 +395,7 @@ func (h *Handler) handlePreviewIntent(
// it isn't bucketed as "no binding matched".
return false, ReasonPreviewNoop
}
childPwl := toPluginWorkload(child)
childPwl := plugin.WorkloadFromStore(child)
if err := h.plugins.DispatchTeardown(ctx, childPwl); err != nil {
slog.Warn("webhook: preview teardown dispatch failed",
"template", template.Name, "preview", child.Name, "error", err)
@@ -421,7 +421,7 @@ func (h *Handler) handlePreviewIntent(
"template", template.Name, "branch", branch, "error", err)
return false, ReasonPreviewError
}
childPwl := toPluginWorkload(child)
childPwl := plugin.WorkloadFromStore(child)
if err := h.plugins.DispatchPlugin(ctx, childPwl, *intent); err != nil {
slog.Warn("webhook: preview dispatch failed",
"template", template.Name, "preview", child.Name, "error", err)
@@ -431,4 +431,3 @@ func (h *Handler) handlePreviewIntent(
"template", template.Name, "branch", branch, "preview", child.Name, "reason", intent.Reason)
return true, intent.Reason
}