package plugin import ( "context" "encoding/json" "fmt" "sort" "sync" ) // Trigger is the contract for one redeploy signal source (registry push, // git push, manual, cron, ...). A Trigger has one job: given an inbound // event and a workload's TriggerConfig, decide whether a deploy should // fire and shape the resulting DeploymentIntent. // // Triggers do not perform deploys themselves — they hand the intent back // to the deployer, which routes it to the matching Source. This keeps // the (M sources × N triggers) cross-product code-free. type Trigger interface { // Kind is the registration key (e.g. "registry", "git", "manual", "cron"). Kind() string // Validate type-checks a raw trigger config blob before it is persisted. Validate(cfg json.RawMessage) error // Match decides whether evt fires a deploy of w. Returning (nil, nil) // means "not interested, skip silently"; an error is reserved for // configuration or signature problems the operator should see. Match(ctx context.Context, deps Deps, w Workload, evt InboundEvent) (*DeploymentIntent, error) } var ( triggersMu sync.RWMutex triggers = map[string]Trigger{} ) // RegisterTrigger installs t under t.Kind(). Panics on duplicate // registration (init-time bug, never a runtime condition). func RegisterTrigger(t Trigger) { triggersMu.Lock() defer triggersMu.Unlock() k := t.Kind() if _, dup := triggers[k]; dup { panic(fmt.Sprintf("plugin: trigger %q already registered", k)) } triggers[k] = t } // GetTrigger returns the Trigger for kind. Errors carry the missing kind // for diagnostics. func GetTrigger(kind string) (Trigger, error) { triggersMu.RLock() defer triggersMu.RUnlock() t, ok := triggers[kind] if !ok { return nil, fmt.Errorf("plugin: no trigger registered for kind %q", kind) } return t, nil } // TriggerKinds returns all registered trigger kinds, sorted. func TriggerKinds() []string { triggersMu.RLock() defer triggersMu.RUnlock() out := make([]string, 0, len(triggers)) for k := range triggers { out = append(out, k) } sortStrings(out) return out } // sortStrings is shared by SourceKinds / TriggerKinds. func sortStrings(s []string) { sort.Strings(s) }