github

package
v0.189.0 Latest Latest
Warning

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

Go to latest
Published: Oct 15, 2026 License: AGPL-3.0 Imports: 22 Imported by: 0

Documentation

Overview

Package github is a client for the pieces of the GitHub API forge-dashboard needs: which repositories the credential can write to, their open pull requests and issues, and combined CI status per pull request. With a token, it talks to GitHub's GraphQL API — one request returns everything a REST-based Client used to need one call per repo/PR/CI-check for, and GraphQL draws from its own separate rate-limit pool rather than the REST budget every other tool on the account shares. GraphQL requires authentication for every request, so the username-only (public repos, no token) mode still uses REST — a fallback path that was never part of the authenticated budget anyway.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ValidateAppPrivateKey added in v0.100.0

func ValidateAppPrivateKey(appID int64, privateKeyPEM []byte) error

ValidateAppPrivateKey confirms privateKeyPEM parses as a usable GitHub App private key for appID (#620). Meant to be called once at process startup so a malformed GITHUB_APP_PRIVATE_KEY_BASE64 fails loudly there, rather than surfacing confusingly the first time some user's Settings save needs it. installationID 1 is a throwaway value — this never sends a real request, it only exercises ghinstallation's own PEM-parsing step.

Types

type Client

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

Client talks to GitHub, either as an authenticated user (a token, GraphQL) or anonymously against one user's public repositories (a username, no token, REST — GraphQL allows no anonymous access at all). The REST fallback is driven by google/go-github rather than hand-rolled requests — same wire calls, typed responses and typed rate-limit errors instead of reparsing JSON bodies by hand.

func NewAppClient added in v0.100.0

func NewAppClient(appID, installationID int64, privateKeyPEM []byte, baseURL string, recorder ...requestlog.Recorder) (*Client, error)

NewAppClient returns a Client authenticated as installationID's own installation of the GitHub App identified by appID/privateKeyPEM (#620) — draws from that installation's own independent rate-limit pool rather than the signed-in account's shared budget. Unlike NewClient this can fail: ghinstallation.New parses and validates privateKeyPEM itself.

The returned Client's httpClient.Transport mints and silently refreshes its own installation token on every request, so — unlike a token-based Client — this one can be kept and reused for a Manager/Aggregator's whole lifetime with no rebuild-on-expiry logic needed.

func NewClient

func NewClient(token, username, baseURL string, recorder ...requestlog.Recorder) *Client

NewClient returns a Client. With token set, Fetch queries GraphQL for every repo the token can push to, private included. With token empty and username set, Fetch falls back to unauthenticated REST and returns only username's public repos — there's no "write access" to filter by without a credential, so this mode returns everything public GitHub already shows anyone. baseURL defaults to the real GitHub API; tests override it to point at an httptest.Server. recorder is variadic, not a plain trailing parameter, purely so every existing call site (125+ of them, most in tests) keeps compiling unchanged (#482) — pass one to have every outbound request persisted, or omit it (or pass nil) to get requestlog.NoopRecorder{}, the same as before this parameter existed.

func NewUnreachableClient added in v0.100.0

func NewUnreachableClient(reason string) *Client

NewUnreachableClient returns a Client whose Fetch always reports reason as an unreachable GitHub forge (#620) — used when an App installation's credentials fail to construct and there's no personal access token to fall back to, so the failure surfaces as a real forge-health error instead of the GitHub source silently never being added at all.

func (*Client) AddLabel added in v0.69.0

func (c *Client) AddLabel(ctx context.Context, owner, name string, number int, label string) error

AddLabel implements dashboard.PullRequestLabeler: adds label to owner/name#number — Renovate's own rebase/retry trigger on GitHub. GitHub's labels-by-name endpoint needs no ID lookup, unlike Forgejo's.

func (*Client) ClosePullRequest added in v0.88.0

func (c *Client) ClosePullRequest(ctx context.Context, owner, name string, number int) error

ClosePullRequest implements dashboard.PullRequestCloser: closes owner/name#number without merging it, via the same Edit call GitHub's own PR-editing endpoint uses for any field change.

func (*Client) CommentPullRequest added in v0.68.0

func (c *Client) CommentPullRequest(ctx context.Context, owner, name string, number int, body string) error

CommentPullRequest implements dashboard.PullRequestCommenter: posts body as a plain comment on owner/name#number. GitHub has no separate pull-request-comment endpoint for a top-level comment — it's the same Issues API a regular issue comment uses, since every pull request is also an issue.

func (*Client) DependabotAck added in v0.137.0

func (c *Client) DependabotAck(ctx context.Context, owner, name string, number int, command string, since time.Time) (dashboard.CommandAck, error)

DependabotAck implements dashboard.DependabotAckReader: finds the newest comment on owner/name#number whose text is exactly command and that was posted at or after since (less ackClockSlack), and reports whether Dependabot has reacted to it with a thumbs-up, which is how it says it got the command (#1082, https://docs.github.com/en/code-security/how-tos/secure-your-supply-chain/manage-your-dependency-security/manage-dependabot-prs). With no such comment it returns the zero CommandAck.

func (*Client) DependabotCommandsBlockedReason added in v0.104.0

func (c *Client) DependabotCommandsBlockedReason() string

DependabotCommandsBlockedReason implements dashboard.DependabotCommandBlocker: an App-authenticated Client with no comment token can't make Dependabot listen.

func (*Client) DisableAutoMerge added in v0.166.0

func (c *Client) DisableAutoMerge(ctx context.Context, owner, name string, number int) error

DisableAutoMerge implements dashboard.PullRequestAutoMergeDisabler: turns off owner/name#number's native auto-merge via GitHub's disablePullRequestAutoMerge GraphQL mutation (#1293). Like EnableAutoMerge it looks the node ID up first, since REST has no equivalent.

func (*Client) EnableAutoMerge added in v0.95.0

func (c *Client) EnableAutoMerge(ctx context.Context, owner, name string, number int) error

EnableAutoMerge implements dashboard.PullRequestAutoMerger: arms owner/name#number's own native auto-merge via GitHub's enablePullRequestAutoMerge GraphQL mutation — REST has no equivalent endpoint, unlike a plain merge. That mutation asks for an explicit merge method rather than picking the repo's default itself, so this looks the pull request's node ID and the repo's allowed methods up in one query first, the GraphQL counterpart to MergePullRequest's own REST repo lookup.

func (*Client) EnsureWebhook added in v0.56.0

func (c *Client) EnsureWebhook(ctx context.Context, owner, name, targetURL, secret string) error

EnsureWebhook implements dashboard.WebhookManager: create a webhook targeting targetURL if owner/name has none yet, or bring an existing one (found by matching targetURL's own path, not c.webhookPath — this method is self-contained even if SetWebhookPath was never called) back to active with the right config rather than creating a second, duplicate hook — GitHub, unlike Forgejo, allows several hooks with the identical URL, so nothing stops a duplicate except checking first.

func (*Client) Fetch added in v0.37.0

func (c *Client) Fetch(ctx context.Context) dashboard.Result

Fetch implements dashboard.Source directly — GitHub drives its own fetch strategy (GraphQL vs. the REST fallback) rather than going through dashboard.GenericSource's one-call-per-repo model, which is exactly the round-trip count this exists to avoid.

func (*Client) FetchMainBranch added in v0.170.0

func (c *Client) FetchMainBranch(ctx context.Context, owner, name, fullName string) (dashboard.MainBranch, error)

FetchMainBranch implements dashboard.MainBranchRefresher (#1316): the default-branch row of one repo, for a webhook delivery that finished a check. Without it the row only moved on the full poll, so a rerun that passed still read as failed.

func (*Client) FetchRepo added in v0.40.0

func (c *Client) FetchRepo(ctx context.Context, owner, name, fullName string) ([]dashboard.PullRequest, []dashboard.Issue, error)

FetchRepo implements dashboard.RepoRefresher: the single-repo counterpart to Fetch's account-wide GraphQL query, for a webhook delivery that already knows exactly which repo changed.

func (*Client) Forge added in v0.38.0

func (c *Client) Forge() dashboard.Forge

Forge implements dashboard.Source.

func (*Client) GetPullRequestDetails added in v0.189.0

func (c *Client) GetPullRequestDetails(ctx context.Context, owner, name string, number int) (dashboard.PullRequestDetails, error)

GetPullRequestDetails implements dashboard.PullRequestDetailer: one GraphQL query for owner/name#number's description, comments and thumbs reactions.

func (*Client) HasWebhook added in v0.54.0

func (c *Client) HasWebhook(ctx context.Context, owner, name string) (bool, error)

HasWebhook implements dashboard.WebhookChecker: does repo owner/name already have a webhook whose target URL is this account's own webhook endpoint. REST-only — GitHub's GraphQL schema doesn't expose webhook configuration — so this is one extra REST call per repo, outside GraphQL's own separate rate-limit budget.

func (*Client) ListChecks added in v0.79.0

func (c *Client) ListChecks(ctx context.Context, owner, name string, number int) ([]dashboard.Check, error)

ListChecks implements dashboard.PullRequestChecker: lists every individual check run against owner/name#number's head commit — the per-job detail ciStatusREST folds into one CIStatus and discards. Always goes over REST regardless of whether Fetch itself used GraphQL or REST for this account: this is a separate, on-demand call the eager refresh never makes, and go-github's REST client already carries whatever credential this Client was built with.

func (*Client) MergePullRequest added in v0.62.0

func (c *Client) MergePullRequest(ctx context.Context, owner, name string, number int) error

MergePullRequest implements dashboard.PullRequestMerger: merges owner/name#number using a method the repo actually allows. GitHub's merge endpoint defaults to a real merge commit when no MergeMethod is given, regardless of the repo's own allow_merge_commit/allow_squash_ merge/allow_rebase_merge settings — confirmed live, "Merge commits are not allowed on this repository" against a squash-only repo — so this looks the repo up first and picks one it'll actually accept, the same shape forgejo.Client's own DefaultMergeStyle lookup already has.

func (*Client) PullRequestBody added in v0.139.0

func (c *Client) PullRequestBody(ctx context.Context, owner, name string, number int) (string, error)

PullRequestBody implements dashboard.PullRequestBodyEditor: the description of owner/name#number.

func (*Client) ReadPullRequestState added in v0.111.1

func (c *Client) ReadPullRequestState(ctx context.Context, owner, name string, number int) (dashboard.PullRequestState, error)

ReadPullRequestState implements dashboard.PullRequestStateReader via GitHub's "Get a pull request": merged and state say whether there's anything left to merge; mergeable_state says why a merge was refused.

func (*Client) RerunFailedChecks added in v0.135.0

func (c *Client) RerunFailedChecks(ctx context.Context, owner, name string, number int) error

RerunFailedChecks implements dashboard.ChecksRerunner (#698): it finds the failed or timed-out check runs on the pull request's head commit, maps each Actions job to its workflow run, and asks GitHub to rerun only the failed jobs of every such run, once per run. A check that isn't an Actions job (a third-party check, a legacy status) can't be rerun here and is skipped.

func (*Client) SetCommentToken added in v0.104.0

func (c *Client) SetCommentToken(token string)

SetCommentToken makes CommentPullRequest post with token (a user's personal access token) instead of this Client's own credential, so Dependabot accepts the command (#666). Only meaningful on an App-mode Client; every other request still uses the App.

func (*Client) SetPullRequestBody added in v0.139.0

func (c *Client) SetPullRequestBody(ctx context.Context, owner, name string, number int, body string) error

SetPullRequestBody implements dashboard.PullRequestBodyEditor: replaces the description of owner/name#number and nothing else about it.

func (*Client) SetWebhookDenialTTL added in v0.128.1

func (c *Client) SetWebhookDenialTTL(d time.Duration)

SetWebhookDenialTTL changes how long a webhook check GitHub refused for lack of permission is remembered before it is asked again (#894). The default is an hour.

func (*Client) SetWebhookPath added in v0.54.0

func (c *Client) SetWebhookPath(path string)

SetWebhookPath tells Client the path (not the full URL — see dashboard.WebhookTargetsPath) this account's own GitHub webhook endpoint lives at, e.g. "/api/webhooks/github/<token>". Left unset, HasWebhook always reports false without calling GitHub at all — the same "optional, degrades quietly" shape RateLimit's nil pointer already uses elsewhere in this codebase.

func (*Client) UpdateBranch added in v0.63.0

func (c *Client) UpdateBranch(ctx context.Context, owner, name string, number int) (bool, error)

UpdateBranch implements dashboard.BranchUpdater: merges owner/name#number's base branch into its head branch. GitHub can schedule this as a background job and answer 202 before it's actually done — go-github surfaces that as a *github.AcceptedError rather than a real failure (see its own doc comment), so that specific case is unwrapped into accepted=true instead of being treated as an error.

Jump to

Keyboard shortcuts

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