ghapi

package
v0.1.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 29, 2026 License: MIT Imports: 19 Imported by: 0

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

Constants

This section is empty.

Variables

This section is empty.

Functions

func DefaultSleep

func DefaultSleep(ctx context.Context, d time.Duration)

DefaultSleep waits d but returns early when ctx is canceled. Useful for rate-limit retry loops that need to honor cancellation.

func IsNotFound

func IsNotFound(err error) bool

IsNotFound reports whether err is a 404 from the GitHub REST API.

func IsPermissionDenied

func IsPermissionDenied(err error) bool

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

func IsRateLimited(err error) bool

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

func StatusCode(err error) (code int, ok bool)

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.

func (ActionFileRequest) NWO

func (r ActionFileRequest) NWO() string

NWO returns "Owner/Repo".

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

func ForActionRef(owner, repo, path, ref string) ActionRef

ForActionRef builds an ActionRef key.

func (ActionRef) String

func (k ActionRef) String() string

String is diagnostics-only; do not parse.

type BranchHead

type BranchHead struct {
	Name      string
	SHA       string
	Protected bool
}

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:

  1. hintBranch (previously recorded in lockfile for this commit)
  2. hintRef (ref the user wrote in the workflow)
  3. defaultBranch (e.g. main / master)
  4. protected branches, lex-sorted within tier
  5. 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

func (c *Client) CommitSHA(ctx context.Context, owner, repo, ref string) (string, error)

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

func (c *Client) GetBranchHead(ctx context.Context, owner, repo, name string) (BranchHead, bool)

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

func (c *Client) GetDefaultBranch(ctx context.Context, owner, repo string) string

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

func (c *Client) ListBranches(ctx context.Context, owner, repo string) ([]BranchHead, error)

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

func (c *Client) ListTags(ctx context.Context, owner, repo string) ([]TagEntry, error)

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) Releases

func (c *Client) Releases(ctx context.Context, owner, repo string) ([]RepoRelease, error)

Releases lists a repository's most recent releases (up to 30).

func (*Client) RepoIDs

func (c *Client) RepoIDs(ctx context.Context, owner, repo string) (int64, int64, error)

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

func (c *Client) RepoMetadata(ctx context.Context, owner, repo string) (RepoMetadata, error)

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

func (c *Client) RepoTags(ctx context.Context, owner, repo string) ([]RepoTag, error)

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

func ForCompare(owner, repo, base, head string) Compare

ForCompare builds a Compare key, lowercasing both SHAs.

func (Compare) String

func (k Compare) String() string

String is diagnostics-only; do not parse.

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

func ForNWOName(owner, repo, name string) NWOName

ForNWOName builds an NWOName key.

func (NWOName) String

func (k NWOName) String() string

String is diagnostics-only; do not parse.

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.

func ForNWORef

func ForNWORef(owner, repo, ref string) NWORef

ForNWORef builds an NWORef key.

func (NWORef) String

func (k NWORef) String() string

String is diagnostics-only; do not parse.

type NWOSha

type NWOSha struct {
	// contains filtered or unexported fields
}

NWOSha pairs a repo with a lowercased commit SHA.

func ForNWOSha

func ForNWOSha(owner, repo, sha string) NWOSha

ForNWOSha builds an NWOSha key, lowercasing the SHA.

func (NWOSha) String

func (k NWOSha) String() string

String is diagnostics-only; do not parse.

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.

func ForRepo

func ForRepo(owner, repo string) Repo

ForRepo builds a Repo key, lowercasing owner and repo.

func (Repo) String

func (r Repo) String() string

String returns the normalized "owner/repo" key, used for cache-key diagnostics and for singleflight coalescing.

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

type RepoRelease struct {
	TagName     string
	PublishedAt string // ISO 8601 date
	Immutable   bool
}

RepoRelease holds release metadata for a tag.

type RepoTag

type RepoTag struct {
	Name string
	SHA  string
}

RepoTag is a tag name paired with the commit SHA it resolves to, as returned by the repos/tags endpoint (annotated tags dereferenced).

type TagEntry

type TagEntry struct {
	Name string
	SHA  string
}

TagEntry holds a tag name and the commit SHA it points at.

Directories

Path Synopsis
Package httpmock provides HTTP test fakes for the ghapi client.
Package httpmock provides HTTP test fakes for the ghapi client.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL