store

package
v0.21.1 Latest Latest
Warning

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

Go to latest
Published: Jul 4, 2026 License: Apache-2.0 Imports: 11 Imported by: 0

Documentation

Overview

Package store is the server's SQLite persistence layer: executions, their stack/edge subgraph, and per-(class,target) approval gate state. Pure-Go SQLite (modernc.org/sqlite, no cgo); schema migrated by goose at Open.

Index

Constants

This section is empty.

Variables

View Source
var ErrConcurrencyConflict = errors.New("eventstore: concurrency conflict")

ErrConcurrencyConflict is returned by Append when the stream's current version is not the expected version — i.e. another writer advanced the stream since the caller last read it. The caller should reload and retry.

Functions

func AssociateClaimExecution added in v0.15.0

func AssociateClaimExecution(db *sql.DB, env string, pr int, execID string) error

AssociateClaimExecution links a PR's claims to the apply execution that now owns them (so heartbeats/finalize can target by pr+env).

func BumpRev

func BumpRev(db *sql.DB, id string) error

BumpRev increments the cache-bust revision (used by the rendered SVG URL so GitHub's image proxy re-fetches on each state change).

func DeleteTarget added in v0.9.9

func DeleteTarget(tx *sql.Tx, pr int, environment, class, target string) error

DeleteTarget removes a single gate target row.

func EnvironmentsForPR added in v0.15.0

func EnvironmentsForPR(db *sql.DB, pr int) ([]string, error)

EnvironmentsForPR returns the distinct environments that have at least one execution for the given PR. Order is unspecified.

func FindNonSupersededExecution added in v0.18.2

func FindNonSupersededExecution(db *sql.DB, pr int, environment, sha, statusContext, incomingID string) (string, bool, error)

FindNonSupersededExecution looks up the most recent non-superseded execution for the given (pr, environment, sha, status_context) where pr > 0 and id != incoming id.

func GetStackOutput added in v0.6.0

func GetStackOutput(db *sql.DB, execID, stack, kind string) (pointer, excerpt string, ok bool, err error)

GetStackOutput returns the stored pointer + excerpt for a stack's output kind. ok is false when none is recorded.

func LatestExecutionID added in v0.6.0

func LatestExecutionID(db *sql.DB, pr int, environment string) (string, bool)

LatestExecutionID returns the most recent execution id for (pr, environment). ok is false when none exists.

func LatestVerifyExecutionID added in v0.6.0

func LatestVerifyExecutionID(db *sql.DB, pr int, environment string) (string, bool)

LatestVerifyExecutionID returns the most recent verify-context execution id for (pr, environment) — i.e. a run whose status_context begins with "verify". ok is false when none exists.

func LoadGraph

func LoadGraph(db *sql.DB, id string) (events.Graph, error)

LoadGraph loads the stacks (ordered by path) and edges of an execution.

func Open

func Open(dsn string) (*sql.DB, error)

Open opens the SQLite database at dsn, enables WAL, and applies all migrations. dsn is a modernc.org/sqlite DSN, e.g. a file path or "file:/data/server.db".

func ReplaceClaims added in v0.17.0

func ReplaceClaims(db *sql.DB, env string, rows map[string]Claim) error

ReplaceClaims rewrites the apply_claims projection for env to exactly match `rows` (stack_path → {owner_pr, expires_at}). Upserts each row and deletes any existing rows for env not present in the new set. This is the projector seam: the env:<env> event stream is the source of truth, apply_claims a derived cross-env index for the sweep + the live-UI list. Atomic in one tx.

func SetCheckRunID

func SetCheckRunID(db *sql.DB, id string, checkRunID int64) error

SetCheckRunID records the GitHub check-run id created for an execution.

func SetExecutionStatus added in v0.13.2

func SetExecutionStatus(db *sql.DB, id, status string) error

SetExecutionStatus persists the execution-level commit status (e.g. terminal "success"/"failure"). This is the signal isFinished reads for an apply; the apply driver writes it once the apply concludes.

func SetReport

func SetReport(db *sql.DB, id, markdown string) error

SetReport stores the rendered plan report markdown for an execution.

func SupersedeExecution added in v0.18.2

func SupersedeExecution(db *sql.DB, oldID, newID string) error

SupersedeExecution links an old execution ID to its replacing execution ID.

func SweepExpiredClaims added in v0.15.0

func SweepExpiredClaims(db *sql.DB, now time.Time) ([]string, error)

SweepExpiredClaims deletes all claims expired at `now` and returns the distinct environments that lost a claim (so the caller can re-evaluate their held checks).

func UpdateStack

func UpdateStack(db *sql.DB, id, stack string, status events.Status, detail string) error

UpdateStack ticks one stack's status (and optional failure detail).

func UpsertApplyLockCheck added in v0.15.0

func UpsertApplyLockCheck(db *sql.DB, c ApplyLockCheck) error

func UpsertInit

func UpsertInit(db *sql.DB, in events.Init) error

UpsertInit records an execution and its changed subgraph from an Init event. Re-init with the same id is upsert-safe. The phase column is intentionally left untouched: the lifecycle phase is owned by UpsertPhase, which may run before Init. Stack status is set only on first insert; a repeat Init (e.g. run register followed by run plan) never regresses an already-advanced stack.

func UpsertPhase

func UpsertPhase(db *sql.DB, p events.PhaseEvent) error

UpsertPhase sets the execution's lifecycle phase, creating a bare row if Init has not run yet. Identity fields are only overwritten when the event carries a non-zero value, so a bare phase bump never clobbers data set by an earlier Init (and an early phase event survives a later Init).

func UpsertStackOutput added in v0.6.0

func UpsertStackOutput(db *sql.DB, execID, stack, kind, pointer, excerpt string) error

UpsertStackOutput records (or updates) the pointer + tail excerpt for one stack's output of a given kind ("log", later "plan"/"verify").

Types

type ApplyLockCheck added in v0.15.0

type ApplyLockCheck struct {
	Environment string
	HeadSHA     string
	CheckRunID  int64
	PR          int
	Repo        string
	Stacks      []string
	State       string // clear | held | unverifiable
	Kind        string // merge_group | pr_head
}

ApplyLockCheck is a persisted apply-lock check run (so serve can PATCH it later when an overlapping apply releases). Keyed by (environment, head_sha).

func GetApplyLockCheck added in v0.15.0

func GetApplyLockCheck(db *sql.DB, env, headSHA string) (ApplyLockCheck, bool, error)

func HeldApplyLockChecks added in v0.15.0

func HeldApplyLockChecks(db *sql.DB, env string) ([]ApplyLockCheck, error)

type Claim added in v0.15.0

type Claim struct {
	Environment string
	StackPath   string
	OwnerPR     int
	ExpiresAt   time.Time
}

Claim is one row from the apply_claims table, returned by ListClaims.

func ListClaims added in v0.15.0

func ListClaims(db *sql.DB, env string) ([]Claim, error)

ListClaims returns all claims for env (any expiry) ordered by stack_path.

type EventStore added in v0.17.0

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

EventStore is the append-only event log + snapshot cache over SQLite. It is domain-agnostic: it deals only in StoredEvent and []byte snapshot blobs.

func NewEventStore added in v0.17.0

func NewEventStore(db *sql.DB) *EventStore

NewEventStore wraps db as an EventStore.

func (*EventStore) Append added in v0.17.0

func (s *EventStore) Append(streamID string, expectedVersion int, evs []StoredEvent) error

Append writes evs as the next contiguous versions after expectedVersion (the caller's last-seen stream version; 0 for a new/empty stream). It is all-or-nothing. Returns ErrConcurrencyConflict if the stream's current version is not expectedVersion.

func (*EventStore) Load added in v0.17.0

func (s *EventStore) Load(streamID string) ([]StoredEvent, int, error)

Load returns the stream's events in version order plus its current version (0 and an empty slice for an unknown/empty stream).

func (*EventStore) LoadSnapshot added in v0.17.0

func (s *EventStore) LoadSnapshot(streamID string) (state []byte, version int, ok bool, err error)

LoadSnapshot returns the latest snapshot for the stream (ok=false if none).

func (*EventStore) SaveSnapshot added in v0.17.0

func (s *EventStore) SaveSnapshot(streamID string, version int, state []byte) error

SaveSnapshot upserts the latest snapshot for the stream (last-write-wins). No concurrency check: the events table is authoritative, so a stale snapshot only means replaying a longer event tail. version is the event version the snapshot reflects.

type Execution

type Execution struct {
	ID             string
	Repo           string
	SHA            string
	PR             int
	Environment    string
	CheckRunID     sql.NullInt64
	Rev            int
	ReportMarkdown string
	LogURL         string
	Status         string // execution-level commit status (e.g. "in_progress"/"success"/"failure"); written by the serve handler, distinct from per-stack events.Status
	StatusContext  string
	Phase          string
	CreatedAt      time.Time
	SupersededBy   string
}

Execution is a row of the executions table.

func GetExecution

func GetExecution(db *sql.DB, id string) (Execution, error)

GetExecution loads one execution row.

func ListExecutions added in v0.6.0

func ListExecutions(db *sql.DB, limit int) ([]Execution, error)

ListExecutions returns the most recent executions, newest first.

func ListExecutionsForPR added in v0.6.0

func ListExecutionsForPR(db *sql.DB, pr int) ([]Execution, error)

ListExecutionsForPR returns all executions for a PR, newest first.

type Gate

type Gate struct {
	PR          int
	Environment string
}

Gate identifies the unit an approval verdict is posted for.

func PendingGates

func PendingGates(db *sql.DB) ([]Gate, error)

PendingGates returns the (pr, environment) gates that still have at least one target not yet ACTIVE — i.e. gates whose verdict may still need posting. The reconcile loop walks these to self-heal the gap where an approval event is processed while the grant is still activating (some providers fire no further event for the activating→active transition) and dropped events / restarts.

type GateTarget

type GateTarget struct {
	Class     string
	Target    string
	GrantName string
	State     string
	Requester string
}

GateTarget holds the per-(class,target) grant state recorded for a (pr, environment).

func TargetsFor

func TargetsFor(db *sql.DB, pr int, environment string) ([]GateTarget, error)

TargetsFor returns every GateTarget recorded for (pr, environment). Returns a non-nil empty slice when none match.

type OpenGrantPR added in v0.10.0

type OpenGrantPR struct {
	PR   int
	Repo string
}

OpenGrantPR is a PR that still holds at least one open (non-terminal) grant, paired with the repo of its latest execution (for the orphan sweep's GitHub closed-state check). Repo is "" when no execution row exists.

func OpenGrantPRs added in v0.10.0

func OpenGrantPRs(db *sql.DB) ([]OpenGrantPR, error)

OpenGrantPRs returns every PR with at least one gate target in an open state (AWAITING/ACTIVATING/ACTIVE), each paired with its latest execution's repo. Unlike PendingGates it INCLUDES fully-ACTIVE (Satisfied) gates — the merged-PR orphan whose grants were never revoked — which is exactly what the sweep must re-examine. Terminal states (DENIED/REVOKED/EXPIRED) are deliberately excluded: those grants are no longer live, so the sweep has nothing to revoke for them (an EXPIRED grant the reconciler may later re-arm becomes AWAITING again — open — and is caught on the next sweep). A PR is one row regardless of how many environments hold open grants (GROUP BY pr); revokeOrphans handles every env.

type PRTarget added in v0.9.5

type PRTarget struct {
	Environment string
	Class       string
	Target      string
}

PRTarget is a (environment, class, target) tuple recorded for a PR, used by the PR-closed webhook to revoke orphaned grants across all environments.

func PRTargets added in v0.9.5

func PRTargets(db *sql.DB, pr int) ([]PRTarget, error)

PRTargets returns every (environment, class, target) recorded for pr across all environments. Returns a non-nil empty slice when none match.

type StoredEvent added in v0.17.0

type StoredEvent struct {
	Type string
	Data []byte
}

StoredEvent is one opaque appended fact. Type is an event-type tag and Data is the opaque payload (JSON bytes in practice). The store never interprets either.

Directories

Path Synopsis
Package migrations embeds the goose SQL migrations for the server store.
Package migrations embeds the goose SQL migrations for the server store.

Jump to

Keyboard shortcuts

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