Documentation
¶
Overview ¶
Package github reads the person's GitHub budget: the hourly REST core limit and the GraphQL limit every session, every gh call and the person's own developer portal login draw from.
The budget is read from the X-RateLimit headers of a real request, never from /rate_limit: that endpoint is exempt and reported a full budget while real requests were already refused. The REST request is conditional (the ETag of the last answer), so a 304 costs nothing; the GraphQL one is a rateLimit query, one point.
Index ¶
- Constants
- Variables
- func ActingOn(ctx context.Context, repo string) context.Context
- func PushesBranch(workflow []byte, branch string) (bool, error)
- func RefStates(ctx context.Context, run GH, refs []PR) (map[PR]RefState, error)
- func Repo(ctx context.Context) string
- func RunGH(ctx context.Context, args ...string) ([]byte, error)
- func Token(ctx context.Context) (string, error)
- type AppDeclaration
- type AppManifest
- type BaseRelease
- type Budget
- type Check
- type GH
- type GraphQL
- type PR
- type Pull
- type Rebase
- type RefState
- type Roster
- type Squash
- type SquashDoc
- type UnansweredReview
Constants ¶
const ( CheckMissing = "missing" CheckPending = "pending" CheckPass = "pass" CheckFail = "fail" )
The outcomes of a pull request's check on its head.
const ( Member = "member" NotMember = "not a member" )
The answers of an org membership question.
const ( Open = "OPEN" Merged = "MERGED" Closed = "CLOSED" )
The states of a pull request.
const ( FeedbackReview = "review" FeedbackReviewComment = "review_comment" FeedbackComment = "comment" )
The kinds of feedback the review guard reads, devctl pr merge's own.
const ( SquashMerged = 0 SquashRed = 1 SquashTimeout = 2 SquashNotApplicable = 3 SquashRefused = 5 SquashTooling = 7 )
The plain squash merge's exit codes and verdicts, devctl pr merge's own (docs/pr-merge.md in giantswarm/devctl), so the gate reads either the same.
const AutoReleaseWorkflow = ".github/workflows/zz_generated.auto_release.yaml"
AutoReleaseWorkflow is the Auto-release workflow devctl generates: on a push to a branch its on.push filter names, it tags the merge commit.
const DirtyState = "dirty"
DirtyState is GitHub's mergeable_state of a pull request that conflicts with its base.
const InstallationFile = "installation.json"
InstallationFile is the file next to an App's manifest that declares its installation: {"repositories": "all" | ["<name>", …]}.
const SquashRoute = "plain squash merge"
SquashRoute names the route in the document and the gate's lines.
Variables ¶
var ErrPermission = errors.New("permission missing")
ErrPermission is a token that may not read an org's whole membership: it sees the public members only, so its "not a member" would be a guess.
Functions ¶
func ActingOn ¶ added in v0.125.0
ActingOn returns ctx with repo (owner/name) as the repository every gh call under it acts on: RunGH names it in GH_REPO. A gh link that picks its login by the repository's owner (devctl's agent link: the App for the owners it is installed on, the person's own login for every other) then acts with the login that reaches the repository, also on a call that names no repository itself, such as gh api graphql.
func PushesBranch ¶ added in v0.107.1
PushesBranch says whether a workflow runs on a push to branch, by its on: trigger and GitHub's branch filters (branches with ! negations, the last matching pattern deciding; branches-ignore; a tags filter alone leaves branch pushes out).
func RefStates ¶ added in v0.69.0
RefStates reads in one GraphQL request the state of each issue or pull request of refs, and for a closed issue the pull request or commit whose closing keyword closed it. A reference GitHub does not answer is missing from the map.
Types ¶
type AppDeclaration ¶ added in v0.125.0
type AppDeclaration struct {
// Name is the App's name.
Name string
// Manifest is the manifest document as declared, a JSON object.
Manifest map[string]any
// Repositories are the installation's repositories by name; nil is all
// of the organisation's, declared or by the file's absence.
Repositories []string
// Source is where the manifest was read, <repo>@<commit>:<path>, and
// Installation where the installation file was, "" when absent.
Source, Installation string
}
AppDeclaration is a GitHub App's declaration as its creation reads it: the manifest document GitHub's manifest flow takes and the installation it declares.
func ReadAppDeclaration ¶ added in v0.125.0
ReadAppDeclaration reads the App manifest at path in repo's default branch, the document itself, and the installation file next to it at the same commit. A manifest that is missing, unreadable or names no App is an error: the App is not declared; so is an installation file of another shape than {"repositories": "all" | ["<name>", …]}.
type AppManifest ¶ added in v0.124.0
type AppManifest struct {
// Name is the App's name.
Name string
// Callbacks are the hosts (with a port where the URL has one) of the
// manifest's callback_urls, lower-case, each once; none for an App
// without callback URLs, one used through the device flow.
Callbacks []string
// Source is where it was read: <repo>@<commit>:<path>.
Source string
}
AppManifest is a GitHub App's declaration in the organisation's repository: its name and the hosts of its callback URLs, read from the manifest on the default branch.
func ReadAppManifest ¶ added in v0.124.0
ReadAppManifest reads the App manifest at path in repo's default branch: its name, its callback hosts and the commit it was read at. A manifest that is missing, unreadable or names no App is an error: the App is not declared.
type BaseRelease ¶ added in v0.107.1
BaseRelease is how a pull request's base branch releases: Auto when the Auto-release workflow on the branch runs on a push to it, so a merge into it is tagged; otherwise its tags are cut by hand (a maintenance branch, a fork line's backport branch).
func ReadBaseRelease ¶ added in v0.107.1
ReadBaseRelease reads repo#n's base branch and the Auto-release workflow on it, two requests. A branch without the workflow has no auto-release; an error is GitHub not answering either.
type Budget ¶
type Budget struct {
Resource string `json:"resource"`
Limit int `json:"limit"`
Remaining int `json:"remaining"`
Used int `json:"used"`
Reset time.Time `json:"reset"`
// GraphQL is the GraphQL limit; nil when it was not read.
GraphQL *GraphQL `json:"graphql,omitempty"`
}
Budget is the core rate limit as GitHub reported it, and the GraphQL limit beside it.
type Check ¶ added in v0.58.0
type Check struct {
// State is the pull request's: Open, Merged or Closed.
State string
// Outcome is CheckMissing when the head has no check of that name.
Outcome string
// URL is the check run's page.
URL string
// Annotations are the messages a failed check run annotated with its
// own name as the title: what it found.
Annotations []string
}
Check is one named check of a pull request's head and the pull request's state.
type GraphQL ¶ added in v0.97.1
type GraphQL struct {
Limit int `json:"limit"`
Remaining int `json:"remaining"`
Used int `json:"used"`
// Reset is when the refusal ends: the hourly reset of a spent limit,
// Retry-After of a secondary one; zero when GitHub named no time.
Reset time.Time `json:"reset,omitzero"`
// Refused is GitHub's words while it refuses GraphQL calls, empty while
// it answers them.
Refused string `json:"refused,omitempty"`
// Secondary says the refusal is a secondary limit (too many concurrent
// or too fast calls), not the hourly limit spent.
Secondary bool `json:"secondary,omitempty"`
// Err is why the limit could not be read.
Err string `json:"error,omitempty"`
}
GraphQL is the GraphQL limit as GitHub reported it for a real query.
func ProbeGraphQL ¶ added in v0.97.1
ProbeGraphQL reads the GraphQL limit with a real query, so a refusal shows even while the counter looks healthy: a secondary limit refuses with headroom left.
type Rebase ¶ added in v0.113.0
type Rebase struct {
Known bool
Rebaseable bool
// State is GitHub's mergeable_state: clean, dirty, blocked, behind, …
State string
}
Rebase is whether a pull request rebases onto its base as GitHub computed it. Known is false while GitHub has not computed it yet (rebaseable null), which it does in the background after the first read.
func ReadRebase ¶ added in v0.113.0
ReadRebase reads repo#n's rebaseable and mergeable_state, one request; an error is GitHub not answering.
type RefState ¶ added in v0.109.0
RefState is the state of an issue or pull request as GitHub answered: OPEN, CLOSED or MERGED, and for an issue a closing keyword closed, what closed it (Closer): the pull request whose merge did, as owner/repo#n, or a bare commit as "commit <sha>". Empty for a close by hand.
type Roster ¶ added in v0.105.0
type Roster struct {
Org string `json:"org"`
// Members are the logins, lower case and sorted.
Members []string `json:"members"`
At time.Time `json:"at"`
}
Roster is an org's members as a token that may read them all saw them.
func ReadRoster ¶ added in v0.105.0
func ReadRoster(ctx context.Context, client *http.Client, token, org string, now time.Time) (Roster, error)
ReadRoster reads org's members with token. The token's own membership comes first: only an active member's token, holding the read:org scope (or the App's members permission), lists the private members too; any other answer is ErrPermission, never an empty or public-only roster.
type Squash ¶ added in v0.31.2
type Squash struct {
GH GH
Repo string
Number int
Timeout time.Duration
Poll time.Duration
Progress io.Writer
Now func() time.Time
Sleep func(time.Duration)
}
Squash is one plain squash merge: the route of a repository devctl does not serve (its GitHub App login reaches the giantswarm organisation and public repositories only), made with the gh CLI's login as the person.
func (Squash) Run ¶ added in v0.31.2
Run waits until the head's checks finished, all green, and squash-merges it through the merge API with that head as the expected one, the subject "<title> (#<n>)", then deletes the head branch. It refuses what devctl refuses before its wait: a draft, a closed, merged or conflicting pull request (3), another human's (5) and one with a reviewer's unanswered feedback (5), devctl's review guard: read before any refusal, so the document carries the review state whatever ends the merge, and again right before the merge call. Its document says what happened; nothing waits for a release.
type SquashDoc ¶ added in v0.31.2
type SquashDoc struct {
Command string `json:"command"`
Route string `json:"route"`
SchemaVersion int `json:"schemaVersion"`
ExitCode int `json:"exitCode"`
Verdict string `json:"verdict"`
Reason string `json:"reason"`
Repo string `json:"repository"`
Number int `json:"number"`
HeadSha string `json:"headSha,omitempty"`
MergeCommitSha string `json:"mergeCommitSha,omitempty"`
Release *string `json:"release"`
// UnansweredReviews is the feedback the last review read found
// unanswered, empty when nothing held the merge; null only when gh
// failed before the first read.
UnansweredReviews []UnansweredReview `json:"unansweredReviews"`
}
SquashDoc is the plain squash merge's JSON document, shaped as devctl pr merge's: the gate parses mergeCommitSha and release alike.
type UnansweredReview ¶ added in v0.125.1
type UnansweredReview struct {
Kind string `json:"kind"`
Login string `json:"login"`
State string `json:"state,omitempty"`
At time.Time `json:"at"`
URL string `json:"url"`
}
UnansweredReview is one piece of a reviewer's feedback the merge waits on, shaped as devctl pr merge's: a review, a comment on the diff or a comment on the conversation, newer than the head and not answered since.