github

package
v0.0.40 Latest Latest
Warning

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

Go to latest
Published: Sep 28, 2026 License: MIT Imports: 8 Imported by: 0

Documentation

Overview

Package github fetches data from GitHub's GraphQL API.

Index

Constants

View Source
const BatchSize = 50

BatchSize is the number of repositories queried in one GraphQL request. GitHub charges GraphQL by node count rather than by request, so batching turns a sweep over ~2,300 packages from that many REST calls into ~46 requests.

100 aliases per query makes GitHub answer some of them with RESOURCE_LIMITS_EXCEEDED, which silently drops those repositories from the result. 75 and below were clean when measured, and 50 leaves room for the limit to move.

View Source
const SweepDepth = 10

SweepDepth is how many versions of each package a sweep looks at.

A sweep decides whether a package has anything new, and the newest releases are where anything new appears once the package's history is in the registry. Asking for more costs nothing in rate limit — GitHub charges a GraphQL query by what it returns, and a batch of 50 stays at one point either way — but it makes each answer bigger for something a sweep never reads.

What a sweep can't see is a release published with an old date, which lands further down the list. Those are for the reconciliation that walks the whole history to find.

Variables

This section is empty.

Functions

This section is empty.

Types

type Branches added in v0.0.22

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

Branches reads files on one repository's branches.

func (*Branches) Files added in v0.0.22

func (b *Branches) Files(ctx context.Context, logger *slog.Logger, prefix, path string) (map[string]string, error)

Files returns the file at path on every branch whose name starts with prefix and which has one, keyed by branch name.

One query per hundred branches rather than a request per branch. What this answers is what every package's definition says right now, which is the only thing that can be compared against what the catalogue says about it: an entry is made once, out of the definition the package arrived with, and a definition edited afterwards leaves the entry describing the package as it was. Nothing else notices, because the question "which packages is the catalogue missing" isn't the question.

A branch whose file isn't there is left out. GitHub reports that as an error against that one branch and answers for the others in the same response, so it is read as the answer it is: that is what a package branch looks like before its first pull request merges, and there is nothing to describe the package with until then.

type Client

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

Client queries GitHub's GraphQL API.

func NewClient

func NewClient(httpClient *http.Client) *Client

NewClient creates a Client. httpClient must attach the GitHub token.

func (*Client) Branches added in v0.0.22

func (c *Client) Branches(owner, repo string) *Branches

Branches returns a reader of the repository's branches.

func (*Client) EnableAutoMerge

func (c *Client) EnableAutoMerge(ctx context.Context, pullRequestID string) error

EnableAutoMerge turns on auto-merge for a pull request.

This is a GraphQL mutation because the REST API has no equivalent. Auto-merge is what makes CI the gate: the pull request merges itself once the checks pass, and stays open when they don't.

func (*Client) FillForbiddenStars

func (c *Client) FillForbiddenStars(ctx context.Context, stars map[string]int, reasons map[string]string)

FillForbiddenStars looks up, without a token, the repositories an organization's IP allow list refused.

Anonymous requests are not covered by an allow list, so this recovers what the authenticated query couldn't read. It is deliberately narrow: anonymous requests are limited to 60 an hour, and only the refused repositories are retried. A repository that genuinely doesn't exist is left alone, since asking again would only spend that budget.

func (*Client) GetStars

func (c *Client) GetStars(ctx context.Context, repos []Repo) (map[string]int, map[string]string, error)

GetStars returns the stargazer count of each repository, and why any of them couldn't be read.

A repository that can't be read is left out of the result rather than failing the whole batch, because one missing package must not stop the rest from being initialized. The reason is returned so the caller can say more than that it failed: a deleted repository and an organization refusing the request look the same from here otherwise.

A batch that fails outright is treated the same way. Returning nothing would throw away every count already read, and building the state from scratch asks for more than two thousand of them in 47 batches: one failing request would leave every package looking equally unused and the run processing them in name order.

func (*Client) Tags

func (c *Client) Tags(ctx context.Context, repos []Repo) (*Sweep, error)

Tags returns the newest tags of each repository, newest first.

Some packages are versioned by their tags rather than their releases — flutter tags every build and publishes the SDK elsewhere — and aqua-registry says so with version_source.

func (*Client) Versions

func (c *Client) Versions(ctx context.Context, repos []Repo) (*Sweep, error)

Versions returns the newest versions of each repository, newest first, and why any of them couldn't be read.

One request covers fifty repositories, and GitHub charges it as one point against a budget of its own: a sweep over the whole registry costs about forty-seven points out of five thousand an hour, and none of the REST budget that generating spends.

Conditional requests would have been the other way to do this, and can't be. The REST listing carries each asset's download count, which changes whenever anybody downloads one, so its ETag changes with it: the packages a sweep most wants to skip are the ones whose ETag never holds. GraphQL doesn't support ETags at all, and doesn't need them, because it returns only the fields that were asked for.

type Repo

type Repo struct {
	Owner string
	Name  string
}

Repo identifies a GitHub repository.

func (Repo) String

func (r Repo) String() string

type Sweep added in v0.0.20

type Sweep struct {
	// Versions is the newest versions of each repository, newest first.
	Versions map[string][]string
	// Names is what each repository is called now. It differs from the key when the
	// repository has been renamed or transferred since the registry recorded it:
	// GitHub answers a query made with the old name and says which name it answered
	// for, so a sweep finds this out without asking anything extra.
	Names map[string]string
	// Reasons says why a repository couldn't be read.
	Reasons map[string]string
}

Sweep is what one look at the registry's repositories found, keyed throughout by the name that was asked for.

Jump to

Keyboard shortcuts

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