// Package plugin defines the Source and Trigger contracts that decouple // Tinyforge's deployer pipeline from any single deployable shape (image, // compose, static, ...) or any single redeploy trigger (registry push, // git push, manual, ...). // // A Workload is the unifying user-facing entity. It carries an opaque // SourceConfig (interpreted by the matching Source) and an opaque // TriggerConfig (interpreted by the matching Trigger). Both kinds are // strings; lookup happens through the registries below. // // New deployable shapes or trigger types are added by: // 1. Implementing Source or Trigger in a sub-package. // 2. Calling Register (Source/Trigger) from that package's init(). // 3. Blank-importing the sub-package from cmd/ to pull the registration in. // // No code in this package or in the deployer/api layers needs to change // when a new kind appears — the registry is the only seam. package plugin import ( "encoding/json" "github.com/alexei/tinyforge/internal/dns" "github.com/alexei/tinyforge/internal/docker" "github.com/alexei/tinyforge/internal/events" "github.com/alexei/tinyforge/internal/health" "github.com/alexei/tinyforge/internal/notify" "github.com/alexei/tinyforge/internal/proxy" "github.com/alexei/tinyforge/internal/store" ) // Deps is the bundle of services every Source or Trigger may need. Passed // per-call so plugin implementations stay stateless and testable. type Deps struct { Store *store.Store Docker *docker.Client Proxy proxy.Provider DNS dns.Provider // nil when wildcard DNS is active Health *health.Checker Notifier *notify.Notifier Events EventPublisher EncKey [32]byte // pass-through to crypto.Encrypt/Decrypt for config secrets } // EventPublisher matches the deployer's existing event-bus surface. Kept as // a local interface so plugin/ does not pull events transitively into every // caller. type EventPublisher interface { Publish(evt events.Event) } // Workload is the value-shape every plugin consumes. It is constructed by // the store layer from the workloads row plus its decoded JSON blobs; the // physical schema can evolve independently of this struct. type Workload struct { ID string Name string GroupID string // formerly app_id; "" = ungrouped ParentWorkloadID string // for stage chains; "" = root SourceKind string // "image" | "compose" | "static" | ... SourceConfig json.RawMessage // shape determined by SourceKind TriggerKind string // "registry" | "git" | "manual" | "cron" | ... TriggerConfig json.RawMessage // shape determined by TriggerKind PublicFaces []PublicFace // zero or more public routes // Notification + webhook security live on the Workload itself rather // than on per-kind tables so the rules are consistent across shapes. NotificationURL string NotificationSecret string WebhookSecret string WebhookSigningSecret string WebhookRequireSignature bool CreatedAt string UpdatedAt string }