Documentation
¶
Overview ¶
Package github wraps the gh CLI to fetch pull request and workflow run data.
Index ¶
- Constants
- Variables
- func CachedDefaultBranchCI(ctx context.Context, repoPath, remoteID string) (*forge.DefaultBranchCI, bool)
- func CachedMergedPRHeads(repoPath, remoteID string) (map[string]string, bool)
- func CachedPRForBranch(repoPath, remoteID, branch, upstream string) (*forge.PullRequest, bool)
- func CachedPRs(repoPath, remoteID, upstream string) ([]forge.PullRequest, bool)
- func CheckoutPR(ctx context.Context, repoPath string, prNumber int) (string, error)
- func CreatePR(ctx context.Context, repoPath, branch, base string) (string, error)
- func DefaultBranchCICacheKey(repoPath, remoteID, sha string) string
- func DependabotAlerts(ctx context.Context, repoPath, remoteRepo string) map[string]int
- func FleetSearchArgs(query string, flags ...string) []string
- func GetDefaultBranchCI(ctx context.Context, repoPath, remoteID string) (*forge.DefaultBranchCI, error)
- func GetMergedPRHeads(ctx context.Context, repoPath, remoteID string) (map[string]string, error)
- func GetPR(ctx context.Context, repoPath, remoteRepo string, number int) (*forge.PullRequest, error)
- func GetPRCount(ctx context.Context, repoPath, remoteID, upstream string) (int, error)
- func GetPRDetail(ctx context.Context, repoPath, remoteID string, prNumber int) (*forge.PRDetail, error)
- func GetPRForBranch(ctx context.Context, repoPath, remoteID, branch, upstream string) (*forge.PullRequest, error)
- func GetPRPreview(ctx context.Context, repoPath, prURL string) (*forge.PRPreview, error)
- func GetPRsForRepo(ctx context.Context, repoPath, remoteID, upstream string) ([]forge.PullRequest, error)
- func GetRun(ctx context.Context, repoPath, repo string, runID int64) (*forge.WorkflowRun, error)
- func GetWorkflowRunsForCommit(ctx context.Context, repoPath, remoteID, commitSHA string) (*forge.WorkflowSummary, error)
- func InvalidatePRCaches()
- func LatestPerWorkflow(runs []forge.WorkflowRun, within time.Duration) []forge.WorkflowRun
- func LatestRunsOnBranch(ctx context.Context, repoPath, repo, branch string, within time.Duration) ([]forge.WorkflowRun, error)
- func ListRuns(ctx context.Context, repoPath, repo string, q RunQuery) ([]forge.WorkflowRun, error)
- func MergedPRHeadsCacheKey(repoPath, remoteID string) string
- func PRCacheKey(repoPath, remoteID, upstream, branch string) string
- func PRDetailCacheKey(repoPath, remoteID string, prNumber int) string
- func PRDiff(ctx context.Context, repoPath, remoteRepo string, number int) ([]byte, error)
- func PRListCacheKey(repoPath, remoteID, upstream string) string
- func PRPreviewCacheKey(prURL string) string
- func PRSearchCacheKey(scope, query string) string
- func RunJobs(ctx context.Context, repoPath, repo string, runID int64) ([]forge.Job, error)
- func SearchPRsEverywhere(ctx context.Context, repoPath, query string) ([]forge.PullRequest, error)
- func SearchPRsInRepo(ctx context.Context, repoPath, remoteID, query string) ([]forge.PullRequest, error)
- func SquashMergePR(ctx context.Context, repoPath string, prNumber int) error
- func WithRunner(ctx context.Context, fn Runner) context.Context
- type RunQuery
- type Runner
Constants ¶
const PreviewTimeout = 10 * time.Second
PreviewTimeout bounds one preview read. A preview is a glance, so a gh invocation that outlives this is reported as a failure rather than left pending forever.
const SearchLimit = 50
SearchLimit caps how many pull requests one saved view reads. A view is a working set, not an archive: past this many rows the answer is to narrow the query rather than to scroll.
Variables ¶
var ( DefaultBranchCICache = cache.NewRegistered[*forge.DefaultBranchCI](workflowTTL) MergedPRHeadsCache = cache.NewRegistered[map[string]string](defaultTTL) PRCache = cache.NewRegistered[*forge.PullRequest](defaultTTL) PRDetailCache = cache.NewRegistered[*forge.PRDetail](defaultTTL) PRListCache = cache.NewRegistered[[]forge.PullRequest](defaultTTL) PRPreviewCache = cache.NewRegistered[*forge.PRPreview](defaultTTL) PRSearchCache = cache.NewRegistered[[]forge.PullRequest](defaultTTL) WorkflowCache = cache.NewRegistered[*forge.WorkflowSummary](workflowTTL) )
What a gh call said, keyed by who else may read it: RemoteScope for anything read off the remote, so parallel checkouts of one repo share a fetch.
Functions ¶
func CachedDefaultBranchCI ¶
func CachedDefaultBranchCI(ctx context.Context, repoPath, remoteID string) (*forge.DefaultBranchCI, bool)
CachedDefaultBranchCI returns the cached default-branch CI for the repo, if any, without invoking gh. Resolving the default branch head still reads local refs, which is free of network cost.
func CachedMergedPRHeads ¶
CachedMergedPRHeads returns the cached merged-PR head map for the remote, if any, without invoking gh.
func CachedPRForBranch ¶
func CachedPRForBranch(repoPath, remoteID, branch, upstream string) (*forge.PullRequest, bool)
CachedPRForBranch returns the cached pull request for branch, if any, without invoking gh, reading the remote's cache file when memory misses.
func CachedPRs ¶
func CachedPRs(repoPath, remoteID, upstream string) ([]forge.PullRequest, bool)
CachedPRs returns the cached open pull request list for the repo without invoking gh, reading the remote's cache file when memory misses.
func CheckoutPR ¶
CheckoutPR checks the pull request out into repoPath's working directory, fetching its head ref first. Returns the local branch name gh landed on.
func CreatePR ¶
CreatePR opens a pull request for the repo's current branch, filling title and body from its commits, and returns the new pull request's URL. It invalidates the repo's cached pull request lists so the next read sees it.
func DefaultBranchCICacheKey ¶
DefaultBranchCICacheKey builds the cache key for one commit's default-branch CI. The commit is part of the key, so a new head is a new entry rather than an eviction, and the TTL alone governs how stale a run's state may be.
func DependabotAlerts ¶
DependabotAlerts returns the count of open Dependabot alerts by severity. A repo whose alerts endpoint denies access (archived repos, or a token without the scope) reports an empty map rather than an error, because the distinction is not actionable to a fleet report.
func FleetSearchArgs ¶
FleetSearchArgs turns a saved view's query into the arguments gh search prs takes: the flags the caller adds, the sort the query asked for, then its terms, with a subject when the view named none.
The terms follow a -- separator, because a negated qualifier such as -org:acme is otherwise read as a bundle of short flags and gh refuses the call. That is also why flags are passed in here rather than appended by the caller: anything after the separator is a term.
func GetDefaultBranchCI ¶
func GetDefaultBranchCI(ctx context.Context, repoPath, remoteID string) (*forge.DefaultBranchCI, error)
GetDefaultBranchCI returns the latest run of each workflow on the repo's default branch head, with the failing job names filled in for red runs, using the cache when fresh.
The branch and commit come from local refs, so a healthy repo costs one gh call; each failing workflow costs one more to name what broke.
func GetMergedPRHeads ¶
GetMergedPRHeads returns merged pull requests' head branch name mapped to head commit OID for repoPath, using the cache when fresh. A branch whose tip matches one of these OIDs was squash-merged: `git branch --merged` won't catch it because the squash commit differs from the branch's own tip.
func GetPR ¶
func GetPR(ctx context.Context, repoPath, remoteRepo string, number int) (*forge.PullRequest, error)
GetPR reads one pull request by number, including the head commit a review anchors to. It does not cache: the cached readers key on a branch and a remote, which a lookup by number cannot supply, and a review that reads a stale head would anchor its comments to the wrong commit.
The repository is named as owner/name in remoteRepo, for a caller holding pull requests from several repositories at once or standing outside a checkout of this one. Empty leaves the repository to gh's own resolution, which reads the remotes of repoPath and picks a fork's upstream correctly.
func GetPRCount ¶
GetPRCount returns the number of open pull requests for the repo, using the cache when fresh.
func GetPRDetail ¶
func GetPRDetail(ctx context.Context, repoPath, remoteID string, prNumber int) (*forge.PRDetail, error)
GetPRDetail returns the full detail for a single pull request, using the cache when fresh.
func GetPRForBranch ¶
func GetPRForBranch(ctx context.Context, repoPath, remoteID, branch, upstream string) (*forge.PullRequest, error)
GetPRForBranch returns the pull request associated with branch, if any, using the cache when fresh.
func GetPRPreview ¶
GetPRPreview reads the little a PRs-tab row shows inline. It addresses the pull request by URL, so a row from a repository that was never scanned locally previews the same as one that was; repoPath and its environment only supply gh's credentials and can be any repo in the fleet.
func GetPRsForRepo ¶
func GetPRsForRepo(ctx context.Context, repoPath, remoteID, upstream string) ([]forge.PullRequest, error)
GetPRsForRepo returns the open pull requests worth showing for the repo, using the cache when fresh.
It reads two pages rather than one: the newest pull requests that are not the operator's, and the operator's own. Splitting the budget that way keeps a repo whose pull requests all belong to a bot from spending it on the operator (who has none there), and keeps the operator's older work from falling off the recent list on a busy repo. Either page failing still returns the other.
func GetWorkflowRunsForCommit ¶
func GetWorkflowRunsForCommit( ctx context.Context, repoPath, remoteID, commitSHA string, ) (*forge.WorkflowSummary, error)
GetWorkflowRunsForCommit returns the CI workflow run summary for a commit, using the cache when fresh.
func InvalidatePRCaches ¶
func InvalidatePRCaches()
InvalidatePRCaches drops every cached pull request view. Each of these caches is keyed by the remote and by upstream, and a mutation changes what every checkout of that remote sees, so they are cleared wholesale rather than by key.
func LatestPerWorkflow ¶ added in v0.5.1
func LatestPerWorkflow(runs []forge.WorkflowRun, within time.Duration) []forge.WorkflowRun
LatestPerWorkflow reduces a run listing to each workflow's current state, newest first, dropping anything that finished before within elapsed. A non-positive within keeps every age.
A run listing is mostly history: one workflow re-run twenty times says nothing a reader needs beyond its current state. Runs are keyed by branch, workflow file, and display title together, because a workflow that reports a mode in its title (a Pulumi preview against a Pulumi deploy) has two current states rather than one.
func LatestRunsOnBranch ¶ added in v0.5.0
func LatestRunsOnBranch( ctx context.Context, repoPath, repo, branch string, within time.Duration, ) ([]forge.WorkflowRun, error)
LatestRunsOnBranch returns the newest run of each distinct workflow on a branch, newest first.
func ListRuns ¶ added in v0.5.0
ListRuns fetches recent workflow runs matching q, newest first.
The repo argument is "owner/name". The repoPath argument is the checkout gh runs in, which is what supplies the host and the token.
func MergedPRHeadsCacheKey ¶
MergedPRHeadsCacheKey builds the cache key for a remote's merged-PR head map.
func PRCacheKey ¶
PRCacheKey and PRListCacheKey scope cache entries by the remote the values were read from, so parallel checkouts of one repository share a lookup; upstream is part of the key only because a repo can track more than one remote. Exported so callers seeding the cache can't drift from this format.
func PRDetailCacheKey ¶
PRDetailCacheKey builds the cache key for one pull request's full detail.
func PRDiff ¶
PRDiff returns the pull request's cumulative unified diff against its merge base, which is what review comment line numbers are relative to. The bytes are what a review anchors against, so callers keep them verbatim rather than re-rendering.
Never pass --patch: that returns a format-patch series, one diff per commit, where a file touched twice appears twice and the line numbers are the intermediate commit's rather than the head's.
func PRListCacheKey ¶
PRListCacheKey builds the cache key for the full PR list of a repo's upstream.
func PRPreviewCacheKey ¶
PRPreviewCacheKey keys a preview on the pull request's own URL, which identifies it across every repository a fleet-wide search reaches.
func PRSearchCacheKey ¶
PRSearchCacheKey scopes a search result by where it ran. A fleet search has no repository of its own, so it keys on the query alone and every repo in the fleet shares the one answer.
func SearchPRsEverywhere ¶
SearchPRsEverywhere runs a saved view's query across every repository the search reaches, which is what makes a view like review-requested:@me worth having. Rows carry their repository and lack the per-check detail a repo-scoped read has, since the search index does not report it.
func SearchPRsInRepo ¶
func SearchPRsInRepo(ctx context.Context, repoPath, remoteID, query string) ([]forge.PullRequest, error)
SearchPRsInRepo runs a saved view's query against one repository, returning the same shape the repo's own list does, checks included.
func SquashMergePR ¶
SquashMergePR squash-merges a pull request and deletes its head branch, both on the remote and locally. It invalidates the repo's cached pull request lists so the next read reflects the merge.
func WithRunner ¶ added in v0.5.0
WithRunner returns a context that makes every gh call in this package go through fn instead of executing a subprocess directly. The runner travels on the context rather than in package state, so callers and tests can hold different ones concurrently.
Types ¶
type RunQuery ¶ added in v0.5.0
type RunQuery struct {
// Workflow is a workflow filename ("ci.yml"), not its display name. The
// Actions API has no filter for the display name.
Workflow string
Branch string
Status string
Event string
Limit int
}
RunQuery narrows a run listing. A zero value lists the most recent runs across every workflow.