Documentation
¶
Overview ¶
Package automatic is the daemon's scheduler for reviews nobody asked for: it turns new pull request heads and new review requests, seen after automatic generation was enabled, into jobs on the existing queue. It has no model backend and no GitHub client of its own; discovery feeds it snapshots and jobs.Queue.SubmitAutomatic prepares, refuses or queues each job with the same preparation and isolation as a confirmed one.
Index ¶
- Constants
- func SavedHead(ctx context.Context, clone repos.Clone, number int) (string, error)
- type Groups
- type Overview
- type Queue
- type Registry
- type Scheduler
- func (s *Scheduler) BeginIdentityChange() func(bool)
- func (s *Scheduler) CatchUp(ctx context.Context, n int) error
- func (s *Scheduler) Gate(j jobs.Job) jobs.Admission
- func (s *Scheduler) Handler() http.Handler
- func (s *Scheduler) Observe(ctx context.Context, snapshot discovery.Snapshot)
- func (s *Scheduler) Overview(ctx context.Context) (Overview, error)
- func (s *Scheduler) Pass(ctx context.Context)
- func (s *Scheduler) ResetIdentity()
- func (s *Scheduler) Run(ctx context.Context)
- func (s *Scheduler) Trigger(ctx context.Context, repository string) error
- func (s *Scheduler) Wake()
- type Status
Constants ¶
const ( GateOff = "automatic_off" GateRepositoryOff = "repository_automatic_off" GateRepositoryRemoved = "repository_removed" GateUnreadable = jobs.ReasonSettingsUnreadable )
Why Gate refuses an automatic job.
NoticeUnavailable is the notice of a repository whose triggered PR got no job because GitHub or the clone stayed unavailable; the most recent notice wins. A "daily_cap" notice an older baum saved is dropped on load.
const SetupCatchUp = 3
SetupCatchUp is how many pull requests desktop setup asks CatchUp for.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Groups ¶
type Groups interface {
List(context.Context) ([]reviewgroups.Group, error)
Summary(context.Context, string) (reviewgroups.Summary, error)
}
Groups is the review group store as the scheduler reads it.
type Overview ¶
type Overview struct {
Enabled bool `json:"enabled"`
// PullRequests is which pull requests get automatic reviews: both,
// authored, requested or all.
PullRequests string `json:"pull_requests"`
Repositories []Status `json:"repositories"`
}
Overview is GET /api/automatic.
type Queue ¶
type Queue interface {
SubmitAutomatic(context.Context, jobs.AutomaticRequest) (jobs.Job, error)
// Interrupted lists automatic jobs a daemon stop or restart cut short
// that may be retried once.
Interrupted() []jobs.Job
// Refused lists automatic jobs cancelled before any model call without
// using up their head (the PR turned draft, or its clone went away).
Refused() []jobs.Job
// CancelDisallowedAutomatic cancels queued automatic jobs the gate
// (Scheduler.Gate) now refuses.
CancelDisallowedAutomatic() []jobs.Job
// QueuedAutomatic lists the automatic jobs waiting to start.
QueuedAutomatic() []jobs.Job
}
type Registry ¶
type Registry interface {
Repositories(context.Context) ([]repos.Repository, error)
Preferences(context.Context) (repos.Preferences, error)
UpdatePreferences(context.Context, func(repos.Preferences) repos.Preferences) (repos.Preferences, error)
RepositorySettings(ctx context.Context, repository string) (repos.Settings, bool, error)
}
type Scheduler ¶
type Scheduler struct {
Registry Registry
Queue Queue
// Path is the application database recording what was already seen, so a
// restart neither forgets pending work nor treats old heads as new.
Path string
// Discover polls one repository's open pull requests; Trigger and
// CatchUp use it.
Discover func(context.Context, github.Repository) (discovery.Snapshot, error)
// Discovered, when set, receives CatchUp's polls in place of Observe: the
// daemon passes background discovery's, which also brings the stack
// groups up to date before CatchUp reads them.
Discovered func(context.Context, discovery.Snapshot)
// Reviewed returns the head of the PR's latest saved review, "" if none.
// Nil uses SavedHead.
Reviewed func(context.Context, repos.Clone, int) (string, error)
// Groups holds the review groups; the reviews of stack groups follow
// their members' (see passGroups). Nil generates no group review.
Groups Groups
// Hold reports that the daemon is stopping or waiting to restart as a
// newer version; nothing is submitted meanwhile, and the new daemon's
// passes submit what is pending.
Hold func() bool
// Notify publishes a repository's changed status (a notice) for the app
// and the desktop app's notifications.
Notify func(Status)
Now func() time.Time
Interval time.Duration
Log *slog.Logger
// contains filtered or unexported fields
}
Scheduler decides which pull requests get automatic jobs. Run it once in the daemon; Observe and Trigger may be called from other goroutines.
func (*Scheduler) BeginIdentityChange ¶
BeginIdentityChange stops submission before credentials change. The returned function must be called once to release the fence, even on failed sign-in.
func (*Scheduler) CatchUp ¶
CatchUp queues automatic reviews of the n most recently updated open pull requests automatic generation covers, across its repositories, though they were open before it was enabled. Desktop setup asks for it once, so the first reviews run while the person takes the tour. Each repository is polled now, and the poll is its baseline when it has none yet; the chosen pull requests become pending with jobs.TriggerSetup and the next pass submits them like any other, skipping a head already reviewed or queued. A pull request in a stack group counts with its group as one and the group's eligible members are caught up together, so the group review can follow theirs (passGroups).
func (*Scheduler) Gate ¶
Gate reads the current settings for an automatic job, for jobs.Queue.SetAutomaticGate: the queue asks it when the job is submitted and again before it starts, so turning generation off (globally or for the repository) stops jobs that are queued but not started. It reads only the registry database, never the scheduler's state or the queue: the queue's mutex is held.
func (*Scheduler) Handler ¶
Handler serves GET and PUT /api/automatic and POST /api/automatic/catch-up (CatchUp). Like the registry handler it does not authenticate: mount it only behind the daemon's authenticated, Host/Origin-checked middleware.
func (*Scheduler) Observe ¶
Observe records a complete discovery snapshot. The first one after a repository is enabled is its baseline; afterwards a new head, or a new review request, on an eligible PR leaves a pending job for the next pass. Background discovery calls it after every successful poll, and Trigger after its own; a snapshot fetched before the newest one observed for its repository is ignored.
func (*Scheduler) ResetIdentity ¶
func (s *Scheduler) ResetIdentity()
ResetIdentity forgets account-dependent PR baselines while preserving repository preferences and saved reviews.
func (*Scheduler) Run ¶
Run submits pending jobs until ctx ends: at once, whenever woken, and every Interval (30 s by default) to retry refusals.
func (*Scheduler) Trigger ¶
Trigger looks at one repository again now and feeds what it finds through Observe, the only way pull requests become automatic jobs. The daemon calls it when a hook event showed a pull request's head moved (internal/ hookrefresh), with Discover polling before discovery's deadline but within its rate budget.
type Status ¶
type Status struct {
Repository string `json:"repository"`
// Enabled is effective: the repository's explicit choice, else the
// global preference.
Enabled bool `json:"enabled"`
// Notice is the latest reason a triggered PR got no job:
// NoticeUnavailable or a jobs.NotAutomaticError reason.
Notice string `json:"notice,omitempty"`
Pending int `json:"pending"`
}
Status is one repository's automatic generation as the app shows it.