Documentation
¶
Overview ¶
Package ghapi wraps go-github behind a narrow domain interface. No other package may import go-github: a major-version bump changes the import path, and confining it here keeps that from rippling through every file that names a pull request.
Index ¶
- Constants
- Variables
- func Describe(err error) string
- type API
- type CachingTransport
- type Client
- func (c *Client) AuthenticatedLogin(ctx context.Context) (string, error)
- func (c *Client) FindPR(ctx context.Context, owner, repo, branch string) (PRInfo, error)
- func (c *Client) HasToken() bool
- func (c *Client) LastRate() (remaining int, reset time.Time)
- func (c *Client) ListRunJobs(ctx context.Context, owner, repo string, runID int64) ([]Job, error)
- func (c *Client) ListWorkflowRuns(ctx context.Context, owner, repo, workflowFile, branch string, limit int) ([]Run, error)
- func (c *Client) SuccessfulRunDurations(ctx context.Context, owner, repo, workflowFile, branch string, limit int) ([]time.Duration, error)
- type Conclusion
- type Job
- type Options
- type PRInfo
- type PRState
- type RateLimitError
- type RetryTransport
- type Run
- type RunStatus
- type Step
Constants ¶
const DefaultRequestTimeout = 15 * time.Second
DefaultRequestTimeout bounds every individual API call. The CI wait passes a much longer parent context but each request is still capped.
Variables ¶
var ErrNotFound = errors.New("not found on GitHub")
ErrNotFound reports a 404 from GitHub. Callers map it to exit code 3.
ErrUnauthorized reports a 401 or 403 that is not a rate limit. Its message names the token-resolution order, because that is almost always the fix.
Functions ¶
Types ¶
type API ¶
type API interface {
FindPR(ctx context.Context, owner, repo, branch string) (PRInfo, error)
ListWorkflowRuns(ctx context.Context, owner, repo, workflowFile, branch string, limit int) ([]Run, error)
ListRunJobs(ctx context.Context, owner, repo string, runID int64) ([]Job, error)
SuccessfulRunDurations(ctx context.Context, owner, repo, workflowFile, branch string, limit int) ([]time.Duration, error)
AuthenticatedLogin(ctx context.Context) (string, error)
HasToken() bool
// LastRate reports the rate-limit budget GitHub returned with the most
// recent call, so a long polling loop can widen its interval before it
// runs the quota out. remaining is -1 when nothing has been observed yet.
LastRate() (remaining int, reset time.Time)
}
API is the narrow interface the rest of flow depends on. Everything above this package mocks API, never go-github itself.
type CachingTransport ¶
type CachingTransport struct {
Base http.RoundTripper
// contains filtered or unexported fields
}
CachingTransport implements conditional requests with ETags. A 45-minute CI wait polling every 5s is roughly 540 requests; without this, each one costs a rate-limit unit even when nothing changed.
It is deliberately a small in-memory map rather than a dependency on an unmaintained HTTP cache library: flow's polling loop is the only consumer, the responses are small, and the cache lives no longer than one command.
func NewCachingTransport ¶
func NewCachingTransport(base http.RoundTripper) *CachingTransport
NewCachingTransport wraps base with an ETag cache.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client is the go-github-backed implementation of API.
func New ¶
New builds a client. A missing token is not an error: the client still works for public data, and every caller already handles the Unknown case.
func (*Client) AuthenticatedLogin ¶
AuthenticatedLogin returns the login the token belongs to. The token itself is never returned or logged.
func (*Client) FindPR ¶
FindPR returns the newest pull request whose head is branch. A branch with no pull request yields PRNone, not an error — working before opening a PR is the normal case.
func (*Client) ListRunJobs ¶
ListRunJobs returns every job of a run, following pagination: the ScaleOps workflow has well over one page of jobs, and a truncated list would silently drop a gating job.
type Conclusion ¶
type Conclusion string
Conclusion is how a completed run or job finished.
const ( ConclusionSuccess Conclusion = "success" ConclusionFailure Conclusion = "failure" ConclusionCancelled Conclusion = "cancelled" ConclusionSkipped Conclusion = "skipped" ConclusionTimedOut Conclusion = "timed_out" ConclusionNeutral Conclusion = "neutral" ConclusionNone Conclusion = "" )
Workflow run and job conclusions.
type Job ¶
type Job struct {
ID int64 `json:"id"`
Name string `json:"name"`
Status RunStatus `json:"status"`
Conclusion Conclusion `json:"conclusion,omitempty"`
StartedAt *time.Time `json:"started_at,omitempty"`
CompletedAt *time.Time `json:"completed_at,omitempty"`
HTMLURL string `json:"html_url,omitempty"`
Steps []Step `json:"steps,omitempty"`
}
Job is one job within a run.
func (Job) Done ¶
Done reports a job that will not change state again. A skipped job counts as satisfied: on a default dev build, the GPU and FIPS legs are always skipped, and waiting for them would hang forever.
type Options ¶
type Options struct {
APIBase string
Token string
UserAgent string
RequestTimeout time.Duration
DisableRetries bool
DisableCaching bool
// Transport overrides the base RoundTripper; tests use httptest.
Transport http.RoundTripper
}
Options configure the client.
type PRInfo ¶
type PRInfo struct {
State PRState `json:"state"`
Number int `json:"number,omitempty"` // 0 when None or Unknown
URL string `json:"url,omitempty"`
MergedAt *time.Time `json:"merged_at,omitempty"`
// Reason explains why State is Unknown, for display.
Reason string `json:"reason,omitempty"`
}
PRInfo is everything flow needs to know about a branch's pull request.
type PRState ¶
type PRState int
PRState models pull-request existence as three values, because "there is no PR" and "I could not find out" must never collapse into the same branch of a conditional — the wording a user sees differs, and so does the right action.
const ( // PRUnknown means the state could not be determined. PRUnknown PRState = iota // PRNone means it was determined that no pull request exists. PRNone PROpen PRMerged PRClosed )
Pull request states.
func (PRState) MarshalJSON ¶
MarshalJSON emits the name rather than the ordinal, so golden payloads stay readable and stable.
func (*PRState) UnmarshalJSON ¶
UnmarshalJSON parses the name form.
type RateLimitError ¶
RateLimitError reports an exhausted rate limit and when it resets.
func (*RateLimitError) Error ¶
func (e *RateLimitError) Error() string
type RetryTransport ¶
type RetryTransport struct {
Base http.RoundTripper
// Sleep is time.Sleep in production; tests substitute a no-op.
Sleep func(time.Duration)
}
RetryTransport retries transport errors, 5xx responses and 429s with exponential backoff plus jitter. Implementing it as a RoundTripper means the policy applies uniformly instead of being repeated at every call site.
func NewRetryTransport ¶
func NewRetryTransport(base http.RoundTripper) *RetryTransport
NewRetryTransport wraps base with the retry policy.
type Run ¶
type Run struct {
ID int64 `json:"id"`
Name string `json:"name,omitempty"`
Status RunStatus `json:"status"`
Conclusion Conclusion `json:"conclusion,omitempty"`
Branch string `json:"branch,omitempty"`
HTMLURL string `json:"html_url,omitempty"`
Attempt int `json:"run_attempt,omitempty"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at,omitempty"`
HeadSHA string `json:"head_sha,omitempty"`
}
Run is one workflow run, flattened to the fields flow uses.