bellows

package
v0.22.0 Latest Latest
Warning

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

Go to latest
Published: Jun 19, 2026 License: MIT Imports: 17 Imported by: 0

Documentation

Overview

Package bellows monitors open PRs for status changes, CI results, and reviews.

Bellows periodically polls all open PRs in the state DB and updates their status. It triggers downstream actions: CI fix workers, review comment forwarding, and PR lifecycle state tracking.

Index

Constants

View Source
const (
	EventCIPassed       = "ci_passed"
	EventCIFailed       = "ci_failed"
	EventReviewApproved = "review_approved"
	EventReviewChanges  = "review_changes_requested"
	EventPRMerged       = "pr_merged"
	EventPRClosed       = "pr_closed"
	EventPRConflicting  = "pr_conflicting"
	EventPRReadyToMerge = "pr_ready_to_merge"
	// EventPRReviewNeeded signals that a PR's current head should be reviewed
	// by Assay. It is emitted by the Assay trigger gate in checkPR when the
	// head SHA differs from the last reviewed SHA and all gating conditions
	// (managed, open, not draft, CI settled, debounce, daily cost) are met.
	EventPRReviewNeeded = "pr_review_needed"
)

Event types emitted by the Bellows monitor.

Variables

This section is empty.

Functions

This section is empty.

Types

type AssayGateConfig added in v0.20.0

type AssayGateConfig struct {
	// Enabled gates the whole feature: when false the trigger never fires.
	Enabled bool
	// SkipDrafts suppresses the trigger for draft PRs when true.
	SkipDrafts bool
	// DebounceSeconds is the minimum interval between Assay runs for the same
	// (anvil, PR). Values <= 0 fall back to defaultAssayDebounceSeconds.
	DebounceSeconds int
	// DailyCostLimitUSD caps total Assay spend per day; 0 means no limit.
	DailyCostLimitUSD float64
	// MaxRuns caps the number of executed Assay reviews per PR; once reached the
	// trigger never fires again for that PR, stopping the Assay→Burnish→new-head
	// loop. Values <= 0 mean no cap.
	MaxRuns int
}

AssayGateConfig holds the resolved Assay settings the trigger gate needs to decide whether to emit EventPRReviewNeeded for a PR. The daemon supplies a per-anvil accessor via Monitor.SetAssayConfig so hot-reloaded config changes take effect without restarting.

type Handler

type Handler func(ctx context.Context, event PREvent)

Handler is called when a PR event is detected.

type Monitor

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

Monitor watches open PRs and dispatches events on status changes.

func New

func New(db *state.DB, vcsLookup func(anvil string) vcs.Provider, interval time.Duration, anvilPaths map[string]string, autoLearnRules func() bool, maxCIFixAttempts func() int, maxReviewFixAttempts func() int, maxRebaseAttempts func() int) *Monitor

New creates a Bellows monitor. The vcsLookup function returns the VCS provider for a given anvil name, enabling per-anvil platform support. The autoLearnRules function is called on each PR merge to check whether warden rule learning is enabled, so hot-reloaded config changes take effect without restarting the daemon. The maxCIFixAttempts, maxReviewFixAttempts, and maxRebaseAttempts functions return the current max fix attempts from config (any may be nil, in which case the corresponding state.Default* is used).

func (*Monitor) OnEvent

func (m *Monitor) OnEvent(h Handler)

OnEvent registers a handler for PR events.

func (*Monitor) Refresh

func (m *Monitor) Refresh()

Refresh triggers an immediate poll cycle.

func (*Monitor) ResetPRState

func (m *Monitor) ResetPRState(anvil string, prNumber int)

ResetPRState clears the internal status cache for a PR. This should be called when a PR is manually reset so that status changes (e.g. from failing back to passing) are re-detected on the next poll cycle even if the state is the same as it was before the reset.

func (*Monitor) Run

func (m *Monitor) Run(ctx context.Context) error

Run starts the polling loop. Blocks until ctx is canceled.

func (*Monitor) SetAssayConfig added in v0.20.0

func (m *Monitor) SetAssayConfig(f func(anvil string) AssayGateConfig)

SetAssayConfig registers an accessor returning the resolved Assay gate config for a given anvil. When set and enabled, the trigger gate in checkPR may emit EventPRReviewNeeded. When nil (the default), the Assay trigger is disabled.

func (*Monitor) SetAutoMergeHandler added in v0.8.0

func (m *Monitor) SetAutoMergeHandler(h func(ctx context.Context, anvil string, pr state.PR))

SetAutoMergeHandler registers a callback invoked when a PR transitions to the ready-to-merge state. The daemon uses this to trigger automatic merging for anvils that have auto_merge enabled.

func (*Monitor) SetSmelterEnabled added in v0.10.0

func (m *Monitor) SetSmelterEnabled(f func() bool)

SetSmelterEnabled registers a callback that returns whether the smelter is enabled. When true, learned warden rules are inserted into the pending table instead of creating immediate PRs.

func (*Monitor) UpdateAnvilPaths

func (m *Monitor) UpdateAnvilPaths(paths map[string]string)

UpdateAnvilPaths replaces the set of monitored anvil paths. This is safe to call while Run is active and takes effect on the next poll cycle.

type PREvent

type PREvent struct {
	PRNumber  int
	BeadID    string
	Anvil     string
	Branch    string
	EventType string
	Details   string
	Timestamp time.Time
	// PRURL is the GitHub URL of the PR, populated for events that need it
	// (e.g. pr_ready_to_merge).
	PRURL string
	// HeadSHA is the commit OID at the head of the PR branch, populated for
	// events that need it (e.g. pr_review_needed, so the Assay reviewer knows
	// which head it is reviewing and can record the run against it).
	HeadSHA string
}

PREvent is emitted when a PR status changes.

Jump to

Keyboard shortcuts

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