Documentation
¶
Overview ¶
Package prwait is the wait engine behind `devctl pr wait` (and the merge that follows it): one bounded, blocking call that returns when a pull request's head is green, red, or cannot become green as it is.
Green is the merge box's view, not `gh pr checks`': every check run and commit status of the head (every run of a check name, the latest status per context), every CircleCI workflow of the head revision (the newest run per name, read from CircleCI because a job behind `requires:` has posted nothing yet), no GitHub Actions run of the head still queued, running or awaiting approval, and every required status context reported. Draft, closed, conflicting and behind-a-strict-base end the wait before it starts.
Index ¶
- Constants
- func IsFork(pr *github.PullRequest) bool
- func NotApplicable(pr *github.PullRequest) error
- func PrintFailedJobs(w io.Writer, jobs []FailedJob)
- type ActionRun
- type Check
- type CircleCI
- type Config
- type EntryFinder
- type FailedJob
- type FailedLog
- type RateSource
- type Result
- type Waiter
- type Workflow
Constants ¶
const ( SourceActions = "actions" SourceCircleCI = "circleci" )
The sources of a failed job.
const ( // MinInterval is the shortest a poll waits, however large the budget. MinInterval = 15 * time.Second // MaxInterval is the longest a poll waits, however small the budget. MaxInterval = 60 * time.Second )
The bounds of the poll interval at scale 1.
const ( SourceCheckRun = "check_run" SourceStatus = "status" )
The check sources of the document.
const CircleCIConfigPath = ".circleci/config.yml"
CircleCIConfigPath is the file whose presence at the head makes CircleCI part of the verdict.
const DefaultFailedLogLines = 50
DefaultFailedLogLines is how much of a failed job's log --failed-log keeps.
const DefaultTimeout = 30 * time.Minute
DefaultTimeout bounds a wait whose caller names none.
Variables ¶
This section is empty.
Functions ¶
func IsFork ¶ added in v8.82.0
func IsFork(pr *github.PullRequest) bool
IsFork says whether the head lives in another repository than the base.
func NotApplicable ¶ added in v8.82.0
func NotApplicable(pr *github.PullRequest) error
NotApplicable is the rule Wait applies before its first poll, for a caller that reads the pull request itself first (pr merge, whose refusals come before the wait): exit 3 for a pull request no wait can turn green, nil otherwise. The verdict is the one Wait would give.
func PrintFailedJobs ¶ added in v8.107.0
PrintFailedJobs writes the tail of each failed job's log to w.
Types ¶
type ActionRun ¶
type ActionRun struct {
Name string `json:"name"`
RunID int64 `json:"runId"`
Status string `json:"status"`
Conclusion string `json:"conclusion"`
URL string `json:"url"`
}
ActionRun is the latest GitHub Actions run of one workflow for the head.
type Check ¶
type Check struct {
Name string `json:"name"`
// ID is the check run's id, the job id of a GitHub Actions job; absent
// for a status.
ID int64 `json:"id,omitempty"`
// Workflow is the GitHub Actions run the check run's job belongs to, when
// the head's runs list it.
Workflow string `json:"workflow,omitempty"`
Source string `json:"source"`
// Status is queued, in_progress or completed for a check run; pending or
// completed for a status.
Status string `json:"status"`
// Conclusion is the check run's conclusion or the status's state once it
// is not pending; empty while unfinished.
Conclusion string `json:"conclusion"`
URL string `json:"url"`
// Required: branch protection or a ruleset of the base names this context.
Required bool `json:"required"`
}
Check is one check of the head as the merge box lists it: a check run or a commit status (the latest of that context). Every run of a check name counts: the jobs of a matrix, or of several workflows calling one reusable workflow, report under one name, and each is listed with its own ID. Of one workflow run several times for the head (a title check after a retitle), the newest run's jobs count.
type CircleCI ¶
type CircleCI struct {
PipelineID string `json:"pipelineId"`
PipelineNumber int64 `json:"pipelineNumber"`
Workflows []Workflow `json:"workflows"`
}
CircleCI is the newest pipeline of the head revision and its workflows, the newest run per workflow name.
type Config ¶
type Config struct {
// GitHub is required. From [githubclient.NewConditional] its polls are
// conditional requests and Rate is the [githubclient.Conditional].
GitHub *githubclient.Client
// Rate is where the poll interval comes from; nil polls at the floor.
Rate RateSource
// CircleCI returns the client once the head is known to carry a CircleCI
// configuration; it is the place the CircleCI token is required, so an
// [agentcli.ExitCoder] it returns ends the wait with that code. nil
// means CircleCI is never consulted.
CircleCI func(ctx context.Context) (*circleciclient.Client, error)
// Entries is read only for a template repository whose head carries
// CircleCIConfigPath: GitHub alone judges it while its entry declares
// gen.ci.templateContent. nil means no repository declares it.
Entries EntryFinder
// Clock defaults to the wall clock at scale 1.
Clock agentcli.Clock
// Progress may be nil.
Progress *agentcli.Progress
// Timeout defaults to DefaultTimeout.
Timeout time.Duration
// FailedLogLines, when positive, makes a red verdict read the log of
// each failed job once and keep that many of its last lines in
// Result.FailedJobs. A green or pending head reads no log.
FailedLogLines int
}
Config configures a Waiter.
type EntryFinder ¶ added in v8.127.1
type EntryFinder interface {
FindEntry(ctx context.Context, owner, repo string) (*reposetup.Fields, bool, error)
}
EntryFinder finds a repository's declaration in the team files; found false when no team file declares it.
type FailedJob ¶ added in v8.107.0
type FailedJob struct {
Name string `json:"name"`
// Source is actions or circleci.
Source string `json:"source"`
URL string `json:"url"`
// LogTail is the last lines of the job's log; on CircleCI, of the output
// of its failed steps.
LogTail string `json:"logTail,omitempty"`
// LogError says why the log could not be read; the verdict stands.
LogError string `json:"logError,omitempty"`
}
FailedJob is one failed job of a red head and the end of its log.
type FailedLog ¶ added in v8.107.0
FailedLog is the --failed-log flag pair of the commands that wait.
type RateSource ¶
type RateSource interface {
Rate() githubclient.RateLimit
}
RateSource reports the GitHub rate limit the newest response carried.
type Result ¶
type Result struct {
Repository string `json:"repository"`
Number int `json:"number"`
HeadSHA string `json:"headSha"`
BaseRef string `json:"baseRef"`
// Checks are the head's check runs, every run of a name that counts, and
// its statuses, the latest per context.
Checks []Check `json:"checks"`
// CircleCI is absent when the head carries no CircleCI configuration, the
// repository is a template whose entry declares that configuration as
// template content, or CircleCI has no project for it.
CircleCI *CircleCI `json:"circleci,omitempty"`
// Actions are the head's GitHub Actions runs, the latest per workflow.
Actions []ActionRun `json:"actions"`
// Unfinished names what the head was still waiting for when the wait
// ended without a verdict.
Unfinished []string `json:"unfinished,omitempty"`
// FailedJobs are the failed jobs of a red head with the tails of their
// logs, read with Config.FailedLogLines.
FailedJobs []FailedJob `json:"failedJobs,omitempty"`
// Warnings are for the envelope: a head that changed under the wait, a
// template repository, a CircleCI project that does not exist.
Warnings []string `json:"-"`
}
Result is the command's part of the document.
type Waiter ¶
type Waiter struct {
// contains filtered or unexported fields
}
Waiter runs waits.
func (*Waiter) Wait ¶
Wait blocks until owner/repo#number is green (nil), red or otherwise decided (an *agentcli.ExitError with the code of the table), or the timeout passes (exit 2). A required context absent from a head whose checks, runs and workflows have all finished is exit 4 at that poll, before the timeout, and so is a head that waits only for Actions runs awaiting a member's approval; while anything else is still pending, the timeout is 2 whatever is absent. The Result is always returned, as far as it was filled; a tooling failure is any other error.