lifecycle

package
v0.4.0 Latest Latest
Warning

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

Go to latest
Published: Mar 12, 2026 License: MIT Imports: 7 Imported by: 0

Documentation

Overview

Package lifecycle manages the end-to-end PR lifecycle state machine.

It connects Bellows events to downstream actions: CI fixes, review fixes, bead closure on merge, and cleanup on close. The lifecycle manager is the central dispatcher that wires together all Bellows-triggered behaviors.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Action

type Action int

Action enumerates lifecycle actions to take.

const (
	ActionNone      Action = iota
	ActionFixCI            // Spawn CI fix worker
	ActionFixReview        // Spawn review fix worker
	ActionCloseBead        // Close bead after merge
	ActionCleanup          // Clean up worktree/branch after close
	ActionRebase           // Rebase branch on top of main to resolve conflict
)

type ActionHandler

type ActionHandler func(ctx context.Context, req ActionRequest)

ActionHandler processes lifecycle actions. Implementations should be async-safe.

type ActionRequest

type ActionRequest struct {
	Action     Action
	PRNumber   int
	BeadID     string
	Anvil      string
	Branch     string
	BaseBranch string // Target branch for the PR (empty = main)
}

ActionRequest is dispatched to the action handler.

type Manager

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

Manager tracks PR states and dispatches actions based on events.

func New

func New(db *state.DB, logger *slog.Logger, handler ActionHandler) *Manager

New creates a lifecycle Manager.

func (*Manager) ActivePRs

func (m *Manager) ActivePRs() int

ActivePRs returns the count of non-merged, non-closed tracked PRs.

func (*Manager) GetState

func (m *Manager) GetState(anvil string, prNumber int) *PRState

GetState returns the current lifecycle state for a PR.

func (*Manager) HandleEvent

func (m *Manager) HandleEvent(ctx context.Context, event bellows.PREvent)

HandleEvent processes a Bellows PR event and dispatches any required actions.

func (*Manager) Load

func (m *Manager) Load(ctx context.Context) error

Load pre-populates the lifecycle map with open PRs from the database.

func (*Manager) NotifyCIFixCompleted

func (m *Manager) NotifyCIFixCompleted(anvil string, prNumber int)

NotifyCIFixCompleted clears the CINeedsFix flag after a CI fix worker finishes. This allows the next EventCIFailed (if CI still fails after the fix attempt) to dispatch a new fix cycle rather than being suppressed by the "already failing, skipping dispatch" guard in HandleEvent for EventCIFailed when CINeedsFix is true.

Without this, CINeedsFix stays true after the fix worker completes. When bellows re-detects CI failure, HandleEvent sees CINeedsFix=true and silently drops the event, permanently sticking the PR.

CIPassing is intentionally left unchanged here — it reflects the last observed CI result from Bellows and must not be faked to avoid incorrectly surfacing the PR as ready-to-merge before CI actually passes.

func (*Manager) NotifyReviewFixCompleted

func (m *Manager) NotifyReviewFixCompleted(anvil string, prNumber int)

NotifyReviewFixCompleted clears the ReviewNeedsFix flag after a review fix worker finishes. This allows the next EventReviewChanges (triggered automatically by GitHub when the reviewer re-examines the updated push) to dispatch a new fix cycle rather than being suppressed by the "already in fix cycle" guard.

Without this, ReviewNeedsFix stays true after the fix worker pushes its changes. When the reviewer re-reviews and still requests changes, HandleEvent sees ReviewNeedsFix=true and silently drops the event.

func (*Manager) Remove

func (m *Manager) Remove(anvil string, prNumber int)

Remove deletes tracking state for a PR (e.g., after cleanup).

func (*Manager) ResetPRState

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

ResetPRState resets the in-memory lifecycle state for a PR so that new Bellows events can dispatch fresh fix/rebase workers. This must be called alongside ResetPRFixCounts (which resets the DB) to keep the two in sync. Without this, the lifecycle manager still believes the PR is exhausted after a retry and silently drops incoming events.

func (*Manager) SetBranch

func (m *Manager) SetBranch(anvil string, prNumber int, branch string)

SetBranch sets the branch name for a tracked PR.

func (*Manager) SetThresholds

func (m *Manager) SetThresholds(maxCI, maxRev, maxRebase int)

SetThresholds overrides the default max attempt limits. Zero values are ignored (the existing default is kept). Must be called before any goroutines call HandleEvent, or the caller must ensure exclusive access.

type PRState

type PRState struct {
	ID             int // Database ID
	PRNumber       int
	BeadID         string
	Anvil          string
	Branch         string
	BaseBranch     string // Target branch for the PR (empty = repo default)
	CIPassing      bool
	Approved       bool
	CINeedsFix     bool // CI failure fix cycle in progress
	ReviewNeedsFix bool // Review comment fix cycle in progress
	Conflicting    bool
	Merged         bool
	Closed         bool
	CIFixCount     int
	ReviewFixCnt   int
	RebaseCount    int
}

PRState tracks the lifecycle of a single PR.

func (*PRState) NeedsFix

func (s *PRState) NeedsFix() bool

NeedsFix returns true if either a CI or review fix cycle is active.

Jump to

Keyboard shortcuts

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