engine

package
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 10, 2026 License: MIT Imports: 22 Imported by: 0

Documentation

Overview

Package engine turns a config plus live provider state into an ordered plan, and executes it.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Select

func Select(cfg config.Config, names []string) ([]config.App, error)

Select narrows a config to the named apps, in the order they were named. Exported because status answers a different question about the same subset.

Types

type CF

type CF interface {
	Do(ctx context.Context, method, path string, body, result any) error
}

CF is the Cloudflare transport, shared by the R2 and Pages planners.

type Engine

type Engine struct {
	// contains filtered or unexported fields
}

func New

func New(cfg config.Config, prov Providers, opts Options) *Engine

func (*Engine) Apply

func (e *Engine) Apply(ctx context.Context, p plan.Plan, w io.Writer) error

Apply runs every executable action in order, stopping at the first failure so a half-applied plan is re-runnable rather than compounded.

Manual actions are written to w and never executed: a caller that ignores them is reporting a half-built deployment as a finished one.

It then re-reads. A provider returning 200 is not evidence the change took — a value can be accepted and normalised, a setting can be write-through to something that rejects it later, and an API can simply lie. Every failure this tool was built after looked like success at the moment it happened.

func (*Engine) Plan

func (e *Engine) Plan(ctx context.Context) (plan.Plan, error)

Plan reads live state and returns everything that would change. It performs no writes.

type Fly added in v0.2.0

type Fly interface {
	Secrets(ctx context.Context, app string) (map[string]flyapi.Secret, error)
	SetSecret(ctx context.Context, app, name, value string) error
}

Fly is the second hosting provider. It shares no code with Render — only this shape — which is what makes the seam a seam.

type Neon

type Neon = neon.API

Neon is the read half of the database provider.

type Options

type Options struct {
	// Apps limits the run to these names. Empty means every app.
	Apps []string
	// Deploy also triggers a Render deploy after the environment converges.
	Deploy bool
	// Getenv resolves valueEnv references. Nil means os.Getenv.
	Getenv func(string) string
	// DeployTimeout bounds the wait for a triggered deploy. Zero means the
	// default; a deploy that is still building after this long is reported as
	// unfinished rather than failed, because it may yet succeed.
	DeployTimeout time.Duration
	// PollEvery is how often the deploy is checked. Zero means the default.
	PollEvery time.Duration
	// Sleep is injected so tests do not wait. Nil means time.Sleep.
	Sleep func(time.Duration)
	// Secrets resolves valueFrom references. Nil means the default set.
	Secrets *secret.Set
	// Fetch reads the URLs the auth checks probe. Nil means a real client.
	Fetch authcheck.Fetcher
	// Concurrency bounds how many apps are read at once. Zero means the
	// default; one makes a run strictly sequential.
	//
	// Only READING is parallel. Applying stays in order, because the order is
	// load-bearing — a bucket is created before its settings are written — and
	// because a failure part-way through a sequential apply is re-runnable
	// while a failure part-way through a parallel one is a puzzle.
	Concurrency int
}

type Providers

type Providers struct {
	Render Render
	CF     CF
	Neon   Neon
	Fly    Fly
}

Providers are the live systems. Any may be nil: an app that declares a surface with no provider behind it gets one manual action saying which credential is missing, rather than a crash halfway through a plan.

Interfaces, not clients, so the engine's own verify path can be tested against a provider that accepts every write and changes nothing — which is the failure it exists to catch, and which no real API will perform on demand.

type Render

type Render interface {
	EnvVars(ctx context.Context, serviceID string) (map[string]string, error)
	SetEnvVar(ctx context.Context, serviceID, key, value string) error
	Deploy(ctx context.Context, serviceID, image string) (string, error)
	DeployStatus(ctx context.Context, serviceID, deployID string) (renderapi.DeployStatus, error)
}

Render is everything the engine asks of Render: read an environment, write one variable, ship a deploy.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL