Documentation
¶
Overview ¶
Package ghapi provides a unified GitHub API client that owns both REST and GraphQL connections, retry transport, and profiling instrumentation. All GitHub API access in the CLI should go through a single Client instance constructed at startup.
Index ¶
- func DefaultSleep(ctx context.Context, d time.Duration)
- func IsNotFound(err error) bool
- func IsPermissionDenied(err error) bool
- func IsRateLimited(err error) bool
- func StatusCode(err error) (code int, ok bool)
- type ActionFileRequest
- type ActionFileResult
- type ActionRef
- type BranchHead
- type Client
- func (c *Client) BatchBranchContains(ctx context.Context, owner, repo, sha string, branches []BranchHead) (matchedBranch string, anyChecked bool, err error)
- func (c *Client) CommitSHA(ctx context.Context, owner, repo, ref string) (string, error)
- func (c *Client) CompareCommits(ctx context.Context, owner, repo, sha, branchHeadSHA string) (bool, error)
- func (c *Client) CompareRefs(ctx context.Context, owner, repo, base, head string) (status, mergeBaseSHA string, err error)
- func (c *Client) GetBranchHead(ctx context.Context, owner, repo, name string) (BranchHead, bool)
- func (c *Client) GetDefaultBranch(ctx context.Context, owner, repo string) string
- func (c *Client) ListBranches(ctx context.Context, owner, repo string) ([]BranchHead, error)
- func (c *Client) ListProtectedBranches(ctx context.Context, owner, repo string) []BranchHead
- func (c *Client) ListTags(ctx context.Context, owner, repo string) ([]TagEntry, error)
- func (c *Client) MatchingHeadRefs(ctx context.Context, owner, repo, prefix string) []BranchHead
- func (c *Client) PeelTagObject(ctx context.Context, owner, repo, sha string) (PeelTagObjectResult, error)
- func (c *Client) Releases(ctx context.Context, owner, repo string) ([]RepoRelease, error)
- func (c *Client) RepoIDs(ctx context.Context, owner, repo string) (int64, int64, error)
- func (c *Client) RepoMetadata(ctx context.Context, owner, repo string) (RepoMetadata, error)
- func (c *Client) RepoTags(ctx context.Context, owner, repo string) ([]RepoTag, error)
- func (c *Client) ResolveActionFiles(ctx context.Context, refs []ActionFileRequest) []ActionFileResult
- type ClientOption
- type Compare
- type NWOName
- type NWORef
- type NWOSha
- type PeelTagObjectResult
- type Repo
- type RepoMetadata
- type RepoRelease
- type RepoTag
- type TagEntry
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func DefaultSleep ¶
DefaultSleep waits d but returns early when ctx is canceled. Useful for rate-limit retry loops that need to honor cancellation.
func IsNotFound ¶
IsNotFound reports whether err is a 404 from the GitHub REST API.
func IsPermissionDenied ¶
IsPermissionDenied reports whether err is a 401, or a 403 that is not a rate-limit response. Rate-limit 403s are reported by IsRateLimited instead so callers can back off rather than treat the repo as inaccessible.
func IsRateLimited ¶
IsRateLimited reports whether err is a primary rate-limit response (HTTP 429) or a secondary one (HTTP 403 with the rate-limit budget exhausted).
func StatusCode ¶
StatusCode reports the HTTP status code carried by err when it originates from a REST call. ok is false when err is nil, a transport failure, or a GraphQL error that carries no HTTP status. It lets callers classify failures without importing go-gh, keeping the API transport internal to this package.
Types ¶
type ActionFileRequest ¶
type ActionFileRequest struct {
Owner string
Repo string
Path string // sub-action path within the repo, may be empty
Ref string // tag, branch, or SHA
}
ActionFileRequest identifies a GitHub Action ref to resolve via GraphQL.
type ActionFileResult ¶
type ActionFileResult struct {
Owner string
Repo string
Path string
Ref string
CommitOID string
ActionYML string
Err error
}
ActionFileResult holds the resolved commit OID and action.yml content for one ActionFileRequest. Err is non-nil when this specific ref could not be resolved (e.g. not found, SSO required).
type ActionRef ¶
type ActionRef struct {
// contains filtered or unexported fields
}
ActionRef is the path-aware key used by the resolver's per-ref cache and the BFS dedup set in ResolveAllRecursive. Sub-action paths must be distinct identities for graph traversal — actions/cache/save@v4 visits a different action.yml than actions/cache@v4 — even though they collapse to the same repo+ref tarball at runner-download granularity. Use NWORef (not ActionRef) when path is irrelevant.
func ForActionRef ¶
ForActionRef builds an ActionRef key.
type BranchHead ¶
BranchHead holds a branch name, the SHA of its HEAD commit, and whether the branch has branch-protection rules enabled in the upstream repo.
func OrderedBranches ¶
func OrderedBranches(branches []BranchHead, hintBranch, hintRef, defaultBranch string) []BranchHead
OrderedBranches returns branches in tiered order so the most trust-bearing candidates are compared first:
- hintBranch (previously recorded in lockfile for this commit)
- hintRef (ref the user wrote in the workflow)
- defaultBranch (e.g. main / master)
- protected branches, lex-sorted within tier
- unprotected branches, lex-sorted within tier
type Client ¶
type Client struct {
Hostname string
// contains filtered or unexported fields
}
Client holds authenticated REST and GraphQL clients for a single GitHub hostname. Construct via New with ClientOption values.
func New ¶
func New(hostname string, opts ...ClientOption) (*Client, error)
New creates an authenticated Client for the given hostname using the ambient gh credential store. Use WithClientTransport for test stubs and WithClientProfile for profiling.
func (*Client) BatchBranchContains ¶
func (c *Client) BatchBranchContains(ctx context.Context, owner, repo, sha string, branches []BranchHead) (matchedBranch string, anyChecked bool, err error)
BatchBranchContains checks whether sha is reachable from any of the given branches using the GraphQL Ref.compare API. It batches all branches into one or a few GraphQL queries (batchReachabilitySize per query) and returns the first matching branch name in the order provided.
Returns:
- matchedBranch: name of the first branch containing sha, or "" if none
- anyChecked: true if at least one branch was successfully checked
- err: non-nil only on transport/auth failures (not per-branch misses)
func (*Client) CommitSHA ¶
CommitSHA resolves a ref (branch, tag, or SHA) to its commit SHA via the repos/commits endpoint.
func (*Client) CompareCommits ¶
func (c *Client) CompareCommits(ctx context.Context, owner, repo, sha, branchHeadSHA string) (bool, error)
CompareCommits reports whether sha is on the lineage of branchHeadSHA using the Compare API. A 404 or 422 response (unrelated histories or missing commit) is treated as a non-error false return. Results are memoized for the lifetime of the Client and concurrent identical comparisons are coalesced via singleflight. The request runs under a cancel-free context so that one fanned-out caller's cancellation (the reachability scan cancels siblings on first match) cannot abort the shared comparison the others are waiting on.
func (*Client) CompareRefs ¶
func (c *Client) CompareRefs(ctx context.Context, owner, repo, base, head string) (status, mergeBaseSHA string, err error)
CompareRefs returns the Compare API status and merge-base SHA for base...head. Unlike CompareCommits it surfaces the raw verdict and the underlying error (including *api.HTTPError) so callers can distinguish ancestry, forgery, and inconclusive results. Not cached: ancestry checks key on distinct base/head pairs that rarely repeat within a run.
func (*Client) GetBranchHead ¶
GetBranchHead resolves a single branch's HEAD commit directly via the git/ref endpoint. Unlike ListBranches this is not subject to the paginated 300-branch cap. Results (including 404s) are cached and concurrent lookups are coalesced via singleflight. Returns ok=false on any error.
func (*Client) GetDefaultBranch ¶
GetDefaultBranch returns the repo's default branch name (e.g. "main"), or "" if the lookup fails. Backed by the shared repoMetadata fetch.
func (*Client) ListBranches ¶
ListBranches returns all branches with their HEAD SHAs for a repo. Paginates up to 3 pages (300 branches). Results are cached per owner/repo and coalesced via singleflight.
func (*Client) ListProtectedBranches ¶
func (c *Client) ListProtectedBranches(ctx context.Context, owner, repo string) []BranchHead
ListProtectedBranches returns the repo's protected branches. Best-effort: any error yields whatever was collected so far (possibly empty). Results are cached per owner/repo and coalesced via singleflight.
func (*Client) ListTags ¶
ListTags returns all tags with their commit SHAs for a repo (first page, up to 100). Results are cached per owner/repo and coalesced via singleflight.
func (*Client) MatchingHeadRefs ¶
func (c *Client) MatchingHeadRefs(ctx context.Context, owner, repo, prefix string) []BranchHead
MatchingHeadRefs returns branches whose names start with prefix via the git/matching-refs endpoint. Best-effort: any error yields nil.
func (*Client) PeelTagObject ¶
func (c *Client) PeelTagObject(ctx context.Context, owner, repo, sha string) (PeelTagObjectResult, error)
PeelTagObject queries whether sha is an annotated tag object in owner/repo and, if so, returns the commit it dereferences to. Returns a zero result (not an error) when the OID or repo is not accessible — callers decide how to interpret the negative.
func (*Client) RepoIDs ¶
RepoIDs returns the numeric owner ID and repo ID for a NWO. Backed by the shared repoMetadata fetch, so it shares a single repos/{owner}/{repo} round-trip with GetDefaultBranch.
func (*Client) RepoMetadata ¶
RepoMetadata fetches a repository's default branch, visibility, and last push time. Delegates to the shared repoMetadata fetch so it shares the cached, singleflight-coalesced repos/{owner}/{repo} round-trip with GetDefaultBranch and RepoIDs.
func (*Client) RepoTags ¶
RepoTags lists a repository's tags (up to 100) with the commit SHA each resolves to. Delegates to ListTags so it shares the cached, singleflight- coalesced tag fetch rather than issuing a second identical request.
func (*Client) ResolveActionFiles ¶
func (c *Client) ResolveActionFiles(ctx context.Context, refs []ActionFileRequest) []ActionFileResult
ResolveActionFiles resolves action refs to commit OIDs and fetches their action.yml/yaml content in a single batched GraphQL round-trip. Results are returned in the same order as inputs; per-ref failures are recorded in each result's Err field rather than aborting the batch.
If the whole query is rejected — transport failure, query cost/complexity, or a secondary rate limit — the batch is split in half and each half retried, recursively down to a single ref, so a few oversized or bad refs can't fail their batch-mates. Splitting is skipped once ctx is canceled so a canceled scan doesn't fan out into a flurry of doomed retries.
type ClientOption ¶
type ClientOption func(*clientConfig)
ClientOption configures a Client at construction time. Pass to New.
func WithClientProfile ¶
func WithClientProfile(p *profile.Session) ClientOption
WithClientProfile attaches profiling instrumentation to API calls.
func WithClientTransport ¶
func WithClientTransport(t http.RoundTripper) ClientOption
WithClientTransport overrides the HTTP transport. Use in tests with httpmock.
type Compare ¶
type Compare struct {
// contains filtered or unexported fields
}
Compare identifies a Compare API result between two SHAs in a repo, e.g. "is base an ancestor of head?". Both SHAs are lowercased.
func ForCompare ¶
ForCompare builds a Compare key, lowercasing both SHAs.
type NWOName ¶
type NWOName struct {
// contains filtered or unexported fields
}
NWOName pairs a repo with an arbitrary name (e.g. a branch name). The name preserves case; callers that want case-insensitive lookup must normalize before passing in.
func ForNWOName ¶
ForNWOName builds an NWOName key.
type NWORef ¶
type NWORef struct {
// contains filtered or unexported fields
}
NWORef pairs a repo with a git ref (tag, branch, or SHA-as-written). Refs preserve their original case because git refs are case-sensitive.
type NWOSha ¶
type NWOSha struct {
// contains filtered or unexported fields
}
NWOSha pairs a repo with a lowercased commit SHA.
type PeelTagObjectResult ¶
type PeelTagObjectResult struct {
// Typename is the __typename of the object at the given OID
// ("Tag", "Commit", "Blob", "Tree"), or empty if the OID/repo
// was not found.
Typename string
// CommitOID is the commit SHA the tag peels to (via ^{commit}).
// Empty when the peel fails or the object is not a tag.
CommitOID string
}
PeelTagObjectResult holds the outcome of a tag-object peel query.
type Repo ¶
type Repo struct {
// contains filtered or unexported fields
}
Repo identifies a GitHub repository by owner and name. Both components are lowercased on construction so case variants share a single cache slot.
type RepoMetadata ¶
type RepoMetadata struct {
DefaultBranch string
Visibility string // "public", "private", or "internal"
PushedAt string // ISO 8601 timestamp of last push
}
RepoMetadata holds repository-level metadata relevant for pinning decisions.
type RepoRelease ¶
RepoRelease holds release metadata for a tag.