prupdate

package
v0.2.0-rc.3 Latest Latest
Warning

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

Go to latest
Published: Nov 13, 2026 License: MIT Imports: 15 Imported by: 0

Documentation

Overview

Package prupdate makes the GitHub writes that unblock a pull request without changing its code: merging its base branch into it (update branch), re-running its failed GitHub Actions workflow runs, and resolving a review thread. Like merging, the first two are confirmed by the user against the head commit they saw, and each is re-checked against GitHub before anything is sent.

Index

Constants

View Source
const (
	DefaultThreadTTL    = time.Minute
	DefaultChecksTTL    = 2 * time.Minute
	DefaultAllChecksTTL = 20 * time.Second
)

How long the Inbox panel's reads are served without asking GitHub again: a pull request's review threads while their count still matches discovery's, and a head commit's failing checks. Threads resolved on GitHub do not change what discovery's probe sees, so the panel reads them again soon, when shown. All of a head's checks, whose runs finish meanwhile, are kept only briefly.

View Source
const (
	HeadMoved = "head_moved"
	Conflict  = "conflict"
	Blocked   = "blocked"
	Forbidden = "forbidden"
	NotOpen   = "not_open"
	UpToDate  = "up_to_date"
	NoRuns    = "no_runs"
	Fork      = "fork"
	NotFound  = "not_found"
	NoClone   = "no_clone"
	Failed    = "failed"
)

Failure codes, stable for the app to branch on.

View Source
const DescriptionLimit = 64 << 10

DescriptionLimit bounds the description the app shows, in bytes.

Variables

This section is empty.

Functions

This section is empty.

Types

type Cache

type Cache struct {
	ThreadTTL, ChecksTTL, AllChecksTTL time.Duration
	Now                                func() time.Time
	// contains filtered or unexported fields
}

Cache keeps what the Inbox panel reads of a pull request, so moving through the Inbox does not read GitHub every time a panel shows one. A thread resolved from the app leaves the cached list at once, and a re-run of the checks forgets the head's failing checks. What it holds was read with the signed-in account's credential, so a change of account empties it (ResetIdentity). It is safe for concurrent use; the zero value is ready.

func (*Cache) ResetIdentity

func (c *Cache) ResetIdentity()

ResetIdentity forgets everything: the GitHub account changed or was disconnected. A read already under way is not stored.

type CheckList

type CheckList struct {
	HeadSHA string        `json:"head_sha"`
	Checks  []CheckStatus `json:"checks"`
	Total   int           `json:"total"`
	Capped  bool          `json:"capped"`
}

CheckList lists all of a head commit's checks, failing ones first, then those still running, each group by name.

At most fix.MaxAllChecks are listed, chosen after sorting, so failing ones are never the ones left out. Total is how many GitHub reports for the head (check runs and commit statuses), so the app can say "showing 100 of 130"; Capped is true when Checks lists fewer than Total.

type CheckStatus

type CheckStatus struct {
	Name string `json:"name"`
	// Status is queued, in_progress or completed.
	Status string `json:"status"`
	// Conclusion is the check run's conclusion (success, failure, neutral,
	// cancelled, skipped, timed_out, action_required, startup_failure,
	// stale) or the commit status's state (success, failure, error); empty
	// until the check completes.
	Conclusion string `json:"conclusion"`
	Title      string `json:"title,omitempty"`
	URL        string `json:"url,omitempty"`
	// JobID is the GitHub Actions job behind a failing check run, which
	// RerunJob re-runs; absent otherwise.
	JobID int64 `json:"job_id,omitempty"`
}

CheckStatus is one check run or commit status of the head commit as the app lists it, whatever its state. Name and Title come from the check itself and are untrusted.

type Checks

type Checks struct {
	HeadSHA string         `json:"head_sha"`
	Checks  []FailingCheck `json:"checks"`
}

Checks lists a head commit's failing checks.

type ConflictFiles

type ConflictFiles struct {
	HeadSHA string   `json:"head_sha"`
	BaseRef string   `json:"base_ref"`
	BaseSHA string   `json:"base_sha"`
	Files   []string `json:"files"`
}

ConflictFiles is the files a pull request's head conflicts with in its base branch, as of the base commit BaseSHA; none when they merge cleanly.

type Description

type Description struct {
	Body string `json:"body"`
	URL  string `json:"url"`
}

Description is a pull request's description as GitHub holds it: Markdown, untrusted, and empty when the author wrote none. URL is the pull request's page.

type Error

type Error struct {
	Code    string `json:"code"`
	Message string `json:"message"`
}

Error is a refusal, worded for the person who clicked the button.

func AsError

func AsError(err error) *Error

AsError returns err as a refusal, wording any other error as a connection failure.

func (*Error) Error

func (e *Error) Error() string

type FailingCheck

type FailingCheck struct {
	Name string `json:"name"`
	// Conclusion is the check run's conclusion or the commit status's state:
	// failure, timed_out, startup_failure, action_required or error.
	Conclusion string `json:"conclusion"`
	// Title is the check's own one-line account of the failure, if any.
	Title string `json:"title,omitempty"`
	URL   string `json:"url,omitempty"`
	// JobID is the GitHub Actions job behind a check run, which RerunJob
	// re-runs; absent for other apps' checks and commit statuses.
	JobID int64 `json:"job_id,omitempty"`
}

FailingCheck is a failing check of the head commit as the app lists it. Name and Title come from the check itself and are untrusted.

type Refusal

type Refusal struct {
	Name    string `json:"name"`
	Message string `json:"message"`
}

Refusal is one workflow run GitHub would not re-run.

type RerunOptions

type RerunOptions struct {
	State   string `json:"state"`
	HeadSHA string `json:"head_sha"`
	// Runs are the head commit's finished workflow runs that failed, were
	// cancelled or timed out; each is re-run for its failed jobs only.
	Runs []Run `json:"runs"`
	// NotRerunnable names the failing checks no workflow run is behind: other
	// apps' checks and commit statuses, which only their own app can re-run.
	NotRerunnable []string `json:"not_rerunnable"`
}

RerunOptions lists what re-running the failed checks would do.

type RerunResult

type RerunResult struct {
	Rerun   []Run     `json:"rerun"`
	Refused []Refusal `json:"refused"`
}

RerunResult is what a re-run started.

type Run

type Run struct {
	ID   int64  `json:"id"`
	Name string `json:"name"`
}

Run is a GitHub Actions workflow run of the head commit.

type Service

type Service struct {
	Client *github.Client
	Cache  *Cache
	// Clone returns the directory of an available clone of the repository,
	// for the reads that need git; false when baum has none.
	Clone   func(ctx context.Context, repository github.Repository) (string, bool)
	Counted func(ctx context.Context, repository github.Repository, number, unresolved int)
}

Service reads and writes through one GitHub client. Cache, when set, keeps the review threads and checks it read for the Inbox panel. Counted, when set, hears of a pull request's unresolved threads read from GitHub that no longer number discovery's count, so the inbox shows the new count before discovery's next poll.

func (Service) AllChecks

func (s Service) AllChecks(ctx context.Context, repository github.Repository, number int, head string) (CheckList, error)

AllChecks lists every check run and commit status of head, the pull request's head commit as the app saw it, or of the pull request's current head when head is empty. Running checks change, so the cache keeps the list only briefly.

func (Service) Conflicts

func (s Service) Conflicts(ctx context.Context, repository github.Repository, number int) (ConflictFiles, error)

Conflicts merges the pull request's head into its base branch's current tip in a local clone, without touching the clone's files, and lists the files that conflict. GitHub says only that there are conflicts.

func (Service) Description

func (s Service) Description(ctx context.Context, repository github.Repository, number int) (Description, error)

Description reads the pull request's description, whatever its state, so a review's citation of it can be read in the app. The body is cut at DescriptionLimit and its invalid UTF-8 dropped.

func (Service) FailingChecks

func (s Service) FailingChecks(ctx context.Context, repository github.Repository, number int, head string) (Checks, error)

FailingChecks lists the failing check runs and commit statuses of head, the pull request's head commit as the app saw it, or of the pull request's current head when head is empty.

func (Service) RerunFailedChecks

func (s Service) RerunFailedChecks(ctx context.Context, repository github.Repository, number int, expectedHead string) (RerunResult, error)

RerunFailedChecks re-runs the failed jobs of each failed workflow run of the head commit the user confirmed. It errors only when no run was started; runs GitHub refuses beside started ones are reported in the result. The run list is read here, never taken from the request.

func (Service) RerunJob

func (s Service) RerunJob(ctx context.Context, repository github.Repository, number int, expectedHead string, job int64) error

RerunJob re-runs one failed GitHub Actions job of the head commit the user saw, as GitHub's Re-run job button does. The job must be one of that head's failing checks, read here, so a request cannot name another job.

func (Service) RerunOptions

func (s Service) RerunOptions(ctx context.Context, repository github.Repository, number int) (RerunOptions, error)

RerunOptions finds the failed workflow runs of the pull request's head.

func (Service) ResolveThread

func (s Service) ResolveThread(ctx context.Context, repository github.Repository, number int, id string) error

ResolveThread resolves one review thread of the pull request, as GitHub's Resolve conversation button does. The thread is read first, so only a thread of this pull request is resolved; one someone resolved meanwhile is done.

func (Service) ReviewThreads

func (s Service) ReviewThreads(ctx context.Context, repository github.Repository, number, unresolved int) (Threads, error)

ReviewThreads returns the pull request's unresolved review threads, from the cache while it still matches unresolved, discovery's count (negative when unknown), else read from GitHub.

func (Service) UpdateBranch

func (s Service) UpdateBranch(ctx context.Context, repository github.Repository, number int, expectedHead string) error

UpdateBranch merges the base branch into the pull request's head branch, as GitHub's Update branch button does. GitHub refuses when the head is no longer expectedHead, so the user updates only the commit they confirmed. The update itself runs on GitHub after it accepts the request.

func (Service) UpdateOptions

func (s Service) UpdateOptions(ctx context.Context, repository github.Repository, number int) (UpdateOptions, error)

UpdateOptions reads the pull request's branches and whether it is behind or conflicting.

type Thread

type Thread struct {
	ID       string `json:"id"`
	Path     string `json:"path"`
	Line     int    `json:"line,omitempty"`
	Outdated bool   `json:"outdated"`
	Author   string `json:"author"`
	Excerpt  string `json:"excerpt"`
	Comments int    `json:"comments"`
	URL      string `json:"url"`
	// Messages are the comments baum read, in order, which may be fewer than
	// Comments.
	Messages []ThreadComment `json:"messages"`
	// CanResolve is the signed-in account's permission to resolve it.
	CanResolve bool `json:"can_resolve"`
}

Thread is an unresolved review thread as the app lists it. Excerpt is the headline of its first comment, the reviewer's text, untrusted; Messages are the comments in full.

type ThreadComment

type ThreadComment struct {
	Author   string `json:"author"`
	Body     string `json:"body"`
	Markdown string `json:"markdown,omitempty"`
	URL      string `json:"url,omitempty"`
}

ThreadComment is one comment of a review thread. Body is the reviewer's text as plain text (fix.PlainText), untrusted, at most maxMessage characters. Markdown is the same text as GitHub has it, for the app to render as GitHub does, sanitised; it is left out of a comment longer than maxMarkdown, which the app then shows as Body.

type Threads

type Threads struct {
	Threads []Thread `json:"threads"`
	// Capped: the pull request has more threads than baum read.
	Capped bool `json:"capped"`
}

Threads lists a pull request's unresolved review threads.

type UpdateOptions

type UpdateOptions struct {
	State   string `json:"state"`
	Draft   bool   `json:"draft"`
	HeadSHA string `json:"head_sha"`
	HeadRef string `json:"head_ref"`
	BaseRef string `json:"base_ref"`
	// Behind is GitHub's report that the head is out of date with its base.
	Behind   bool `json:"behind"`
	Conflict bool `json:"conflict"`
	Fork     bool `json:"fork"`
}

UpdateOptions is what updating the branch would do, read just before the user confirms.

Jump to

Keyboard shortcuts

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