Documentation
¶
Overview ¶
Package server is the control-plane HTTP service: it records multi-stack Terraform executions, drives one GitHub check run per environment, and projects approval-gate state — all as a pure function of its SQLite store. Terraform itself runs in the user's own CI; this server observes and gates.
Index ¶
- type App
- func (a *App) ClaimsSweepLoop(ctx context.Context, interval time.Duration)
- func (a *App) CleanLogBuffers(maxAge time.Duration)
- func (a *App) OrphanSweepLoop(ctx context.Context, interval time.Duration)
- func (a *App) ReconcileLoop(ctx context.Context, interval time.Duration)
- func (a *App) Routes() http.Handler
- type CheckRunUpdate
- type Config
- type FSStore
- type GitHub
- type MockGitHub
- func (m *MockGitHub) CreateCheckRun(ctx context.Context, repo, sha, name, detailsURL string) (int64, error)
- func (m *MockGitHub) MergeGroupPRs(ctx context.Context, repo, headSHA string) ([]int, error)
- func (m *MockGitHub) PRAbandoned(ctx context.Context, repo string, pr int) (bool, error)
- func (m *MockGitHub) PRHeadSHA(ctx context.Context, repo string, pr int) (string, error)
- func (m *MockGitHub) PostStatus(ctx context.Context, repo, sha, context_, state, description, targetURL string) error
- func (m *MockGitHub) UpdateCheckRun(ctx context.Context, repo string, checkRunID int64, u CheckRunUpdate) error
- type ObjectStore
- type RealClient
- func (c *RealClient) CreateCheckRun(ctx context.Context, repo, sha, name, detailsURL string) (int64, error)
- func (c *RealClient) MergeGroupPRs(ctx context.Context, repo, headSHA string) ([]int, error)
- func (c *RealClient) PRAbandoned(ctx context.Context, repo string, pr int) (bool, error)
- func (c *RealClient) PRHeadSHA(ctx context.Context, repo string, pr int) (string, error)
- func (c *RealClient) PostStatus(ctx context.Context, repo, sha, context_, state, description, targetURL string) error
- func (c *RealClient) UpdateCheckRun(ctx context.Context, repo string, checkRunID int64, u CheckRunUpdate) error
- type Shell
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type App ¶
type App struct {
// Approval is the optional approval-gate backend. nil disables gating
// (gates recorded AWAITING are never satisfied → action_required). Set after
// construction (e.g. by the serve command), so New's signature is unchanged.
Approval approval.Backend
// Objects is the optional object store for completed-log offload. nil keeps
// logs in the local buffer only. Set after construction, like Approval.
Objects ObjectStore
// PushVerifier verifies a Pub/Sub push OIDC bearer token, returning the
// token's email claim. Set externally (like Approval/Objects); nil disables
// the /pubsub/push endpoint (it returns 404).
PushVerifier func(ctx context.Context, bearer string) (email string, err error)
// contains filtered or unexported fields
}
App is the HTTP application.
func (*App) ClaimsSweepLoop ¶ added in v0.15.0
ClaimsSweepLoop periodically releases expired claims and re-evaluates held checks (mirrors OrphanSweepLoop). Self-disables when apply_lock is off.
func (*App) CleanLogBuffers ¶ added in v0.9.0
CleanLogBuffers removes execution buffer directories older than maxAge — orphans left by restarts mid-execution. Call at startup.
func (*App) OrphanSweepLoop ¶ added in v0.10.0
OrphanSweepLoop periodically runs sweepOrphanedGrants until ctx is cancelled. Slower cadence than ReconcileLoop: it calls the GitHub API per open-grant PR and orphan cleanup is not time-critical. No-op without an approval backend or GitHub client.
func (*App) ReconcileLoop ¶
ReconcileLoop periodically re-evaluates every not-yet-ACTIVE gate, so a grant that goes ACTIVE after the request (the common case) converges to success even with no provider event. No-op without a backend. Blocks until ctx is cancelled.
func (*App) Routes ¶
Routes returns the HTTP handler. Uses stdlib method-pattern routing (Go 1.22+). Auth model:
- /api/* require a short-lived HS256 JWT (aud=api) — generated by CI
- /live/* /pr/ /{$} require a 30-day HS256 JWT (aud=view) via ?token= or cookie
- /img/* /assets/* public (GitHub camo + CSS must not require auth)
- /logs/* public (accessed inline by the live page after view auth)
type CheckRunUpdate ¶
type CheckRunUpdate struct {
Title string // check-run title (e.g. "Terraform plan" / "Terraform apply")
Summary string // GFM blast-radius headline + verdict chips + per-stack table (renders at the top)
Text string // the rendered plan report (renders below the summary)
DetailsURL string // the live page for the full view
Conclusion string // "" while running; otherwise success|failure|action_required|neutral
}
CheckRunUpdate carries everything a PATCH to a check run needs.
type Config ¶
type Config struct {
// WebhookSecret is the bearer token required on /api/* mutations. Empty
// disables auth (local/dev only).
WebhookSecret string
// PublicBaseURL is the public origin used for check-run Details links. Empty
// derives it from the inbound request (e.g. behind a TLS-terminating proxy).
PublicBaseURL string
// UseChecks true → drive a rich GitHub check run (needs checks:write);
// false → link mode, posting a commit status (needs statuses:write).
UseChecks bool
// ReconcilerCore routes server-side gate/execution state transitions through
// the pure reconcile core (internal/reconcile) instead of the legacy
// handlers. Off by default; engaged only at quiescence (see Task 19).
ReconcilerCore bool
// ApplyLock enables the apply-serialization feature: at most one apply runs
// at a time across all PRs. Off by default; inert when false.
ApplyLock bool
// LogsDir is where per-stack log buffers are written. Empty disables log
// ingestion (the endpoints become no-ops).
LogsDir string
// GroupDepth controls the live DAG's grouping: stacks fold into groups by
// their first GroupDepth path segments. 0 = unset → handlers default to 2.
GroupDepth int
// GroupPattern is a regexp whose first capture group is the group key;
// overrides GroupDepth. Empty → fall back to GroupDepth grouping.
GroupPattern string
// PushServiceAccount is the allowed verified OIDC email for /pubsub/push.
// Empty accepts any verified token.
PushServiceAccount string
// GitHubWebhookSecret is the HMAC-SHA256 secret GitHub sends on every webhook
// delivery (X-Hub-Signature-256). Empty disables the /github/webhook endpoint.
GitHubWebhookSecret string
}
Config is the server runtime configuration.
type FSStore ¶
type FSStore struct{ Root string }
FSStore is a filesystem-backed ObjectStore rooted at Root.
type GitHub ¶
type GitHub interface {
// CreateCheckRun opens an in_progress check run with the given name whose
// Details link is detailsURL; returns its id.
CreateCheckRun(ctx context.Context, repo, sha, name, detailsURL string) (int64, error)
// UpdateCheckRun patches an existing check run.
UpdateCheckRun(ctx context.Context, repo string, checkRunID int64, u CheckRunUpdate) error
// PostStatus sets a commit status (link-mode fallback).
PostStatus(ctx context.Context, repo, sha, context_, state, description, targetURL string) error
// PRHeadSHA returns the current head commit SHA of a pull request, so a
// verdict is posted on the live head rather than a stale execution SHA.
PRHeadSHA(ctx context.Context, repo string, pr int) (string, error)
// PRAbandoned reports whether a pull request is closed WITHOUT having been
// merged (i.e. abandoned). A merged PR returns false so its post-merge apply
// keeps its grant. Returns (false, err) when the PR cannot be read.
PRAbandoned(ctx context.Context, repo string, pr int) (bool, error)
// MergeGroupPRs returns the PR numbers whose commits compose the merge group
// at headSHA, via the commit→PRs association API.
MergeGroupPRs(ctx context.Context, repo, headSHA string) ([]int, error)
}
GitHub is the surface the server needs from GitHub. A rich check run requires a GitHub App with checks:write; the link-mode fallback posts a commit status (statuses:write) whose target URL points at the live page. The real implementation lands in a later sub-plan; tests use MockGitHub.
type MockGitHub ¶
type MockGitHub struct {
CreateCheckRunFn func(ctx context.Context, repo, sha, name, detailsURL string) (int64, error)
UpdateCheckRunFn func(ctx context.Context, repo string, checkRunID int64, u CheckRunUpdate) error
PostStatusFn func(ctx context.Context, repo, sha, context_, state, description, targetURL string) error
PRHeadSHAFn func(ctx context.Context, repo string, pr int) (string, error)
PRAbandonedFn func(ctx context.Context, repo string, pr int) (bool, error)
MergeGroupPRsFn func(ctx context.Context, repo, headSHA string) ([]int, error)
// CreateCheckRunCalls counts CreateCheckRun invocations so tests can assert
// the check run is created exactly once (idempotency).
CreateCheckRunCalls int
}
MockGitHub is a test double for GitHub. Unset funcs are no-ops.
func (*MockGitHub) CreateCheckRun ¶
func (*MockGitHub) MergeGroupPRs ¶ added in v0.15.0
func (*MockGitHub) PRAbandoned ¶ added in v0.10.0
func (*MockGitHub) PostStatus ¶
func (m *MockGitHub) PostStatus(ctx context.Context, repo, sha, context_, state, description, targetURL string) error
func (*MockGitHub) UpdateCheckRun ¶
func (m *MockGitHub) UpdateCheckRun(ctx context.Context, repo string, checkRunID int64, u CheckRunUpdate) error
type ObjectStore ¶
type ObjectStore interface {
Put(ctx context.Context, key string, r io.Reader) error
Get(ctx context.Context, key string) (io.ReadCloser, error)
}
ObjectStore persists completed log objects (and, later, plan/verify outputs). FSStore backs tests/local; a cloud impl (e.g. GCS) is wired by the serve command for deployment.
type RealClient ¶
type RealClient struct {
// contains filtered or unexported fields
}
RealClient is the production GitHub implementation. It mints a fresh App installation token per request, so the token never goes stale on a long-running service. The App key + ids are supplied by the caller (a deployment concern); RealClient has no cloud-secret-store dependency.
func NewRealClient ¶
func NewRealClient(appID, installationID string, pemKey []byte) (*RealClient, error)
NewRealClient parses the PEM App private key and returns a client for the given App id + installation id.
func (*RealClient) CreateCheckRun ¶
func (c *RealClient) CreateCheckRun(ctx context.Context, repo, sha, name, detailsURL string) (int64, error)
CreateCheckRun opens an in_progress check run with the given name.
func (*RealClient) MergeGroupPRs ¶ added in v0.15.0
MergeGroupPRs returns the PR numbers whose commits compose the merge group at headSHA, via the commit→PRs association API.
func (*RealClient) PRAbandoned ¶ added in v0.10.0
PRAbandoned reports whether the PR is closed without having been merged.
func (*RealClient) PostStatus ¶
func (c *RealClient) PostStatus(ctx context.Context, repo, sha, context_, state, description, targetURL string) error
PostStatus sets a commit status (link-mode fallback; needs only statuses:write).
func (*RealClient) UpdateCheckRun ¶
func (c *RealClient) UpdateCheckRun(ctx context.Context, repo string, checkRunID int64, u CheckRunUpdate) error
UpdateCheckRun patches a check run. A non-empty Conclusion completes the run.
type Shell ¶ added in v0.9.9
type Shell struct {
// contains filtered or unexported fields
}
Shell is the imperative shell around the pure reconcile core. It gathers a scoped World per signal, runs reconcile.Step to a fixpoint, executes the resulting Actions, and persists the new ChangeSet — serialized per (pr, environment).