Help us shape the future of Go! Take the 2026 Go Developer Survey

github

package
v0.32.0 Latest Latest
Warning

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

Go to latest
Published: Oct 26, 2026 License: MIT Imports: 21 Imported by: 0

Documentation

Overview

Package github provides owner-wide discovery and repository access through Service, using go-github for REST reads and merges, and GraphQL rebase and auto-merge requests and automation history. Client loads the App private key at startup. Rebases, auto-merge enablement, and immediate merges are guarded by the expected PR head SHA. Signing and installation token renewal are delegated to ghinstallation. Webhook verifies raw GitHub deliveries; worker and comment requests share Service. Snapshot completeness, label membership, and timeline timestamp extraction belong here; callers decide whether those facts authorize automation.

Index

Constants

This section is empty.

Variables

View Source
var ErrIgnoredDelivery = errors.New("github: delivery does not contain a new PR comment")

ErrIgnoredDelivery identifies a verified delivery that needs no command action.

View Source
var ErrRateLimited = errors.New("github: rate limit reached")

ErrRateLimited identifies a rate-limit error in a GraphQL HTTP-success payload.

Module provides shared API access and owner-wide discovery.

Functions

func HasCommentMetadata added in v0.13.0

func HasCommentMetadata(comment *IssueComment) bool

HasCommentMetadata checks for an author login and edit timestamp on a comment whose PR, author ID, and creation timestamp were already validated by GetComment.

func HasLabel added in v0.13.0

func HasLabel(labels []*Label, name string) bool

HasLabel reports exact, case-sensitive membership. Nil or empty label lists contain no matching label.

func HasPullRequestNodeID added in v0.13.0

func HasPullRequestNodeID(pull *PullRequest) bool

HasPullRequestNodeID checks the identity required by GraphQL operations. A numeric pull request ID does not substitute for its node ID.

func IsRateLimited added in v0.8.0

func IsRateLimited(err error) bool

IsRateLimited recognizes throttling so reconciliation stops the current sweep instead of making more requests for other repositories against the same limit.

func LatestAutomationEventTimes added in v0.13.0

func LatestAutomationEventTimes(events []*IssueEvent, label string) (time.Time, time.Time, time.Time)

LatestAutomationEventTimes returns the latest label application, removal, and auto-merge disable timestamps, in that order. Missing events return zero times. History must be validated, and label matching is exact. Disabling auto-merge is independent of the label; callers decide whether these facts revoke access.

func NewConnection added in v0.13.0

func NewConnection(params ConnectionParams) (*http.Client, error)

NewConnection constructs the shared transport. Only safe methods are retried; idle connections close after consumers stop using the client.

func ValidatePullRequestMetadata added in v0.13.0

func ValidatePullRequestMetadata(pull *PullRequest) error

ValidatePullRequestMetadata requires a node ID, head SHA, branch references, and repository names before guarded automation. Callers decide which PRs need this validation, so incomplete snapshots of ineligible PRs can be ignored.

Types

type AppConfig added in v0.13.0

type AppConfig struct {
	PrivateKey     string `yaml:"private_key,omitempty" json:"private_key,omitempty" toml:"private_key,omitempty" validate:"required"`
	ID             int64  `yaml:"id,omitempty" json:"id,omitempty" toml:"id,omitempty" validate:"gt=0"`
	InstallationID int64  `yaml:"installation_id,omitempty" json:"installation_id,omitempty" toml:"installation_id,omitempty" validate:"gt=0"`
}

AppConfig identifies one installation. PrivateKey is a go-service source read once at startup; installation access tokens are renewed automatically.

type Branch added in v0.29.0

type Branch = github.Branch

Branch aliases github.Branch for branch cleanup snapshots.

type Client

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

Client supplies installation access to the worker and webhook. The private application client uses JWT authentication to validate installation ownership.

func NewClient

func NewClient(cfg *Config, fs *os.FS, conn *http.Client) (*Client, error)

NewClient reads the App key once at startup. Missing or empty sources and invalid RSA PEMs prevent startup; replacement requires a restart. Signing and installation token renewal are handled by ghinstallation. Construction makes no GitHub requests.

type CommitFile added in v0.27.0

type CommitFile = github.CommitFile

CommitFile aliases github.CommitFile for pull request file snapshots.

type CommitsComparison

type CommitsComparison = github.CommitsComparison

CommitsComparison aliases github.CommitsComparison so consumers use the project-owned package.

type Config

type Config struct {
	Client  *client.Config `yaml:"client,omitempty" json:"client,omitempty" toml:"client,omitempty"`
	App     *AppConfig     `yaml:"app,omitempty" json:"app,omitempty" toml:"app,omitempty" validate:"required"`
	Webhook *WebhookConfig `yaml:"webhook,omitempty" json:"webhook,omitempty" toml:"webhook,omitempty" validate:"omitempty"`
	Owner   string         `yaml:"owner,omitempty" json:"owner,omitempty" toml:"owner,omitempty" validate:"required"`
	URL     string         `yaml:"url,omitempty" json:"url,omitempty" toml:"url,omitempty" validate:"omitempty,http_url"`
}

Config identifies the owner whose installation repositories are reconciled. App credentials supply worker and comment access. The private key is loaded at startup; installation tokens renew automatically. URL optionally overrides the REST API base URL; an empty URL uses api.github.com.

func (*Config) GetTimeout

func (c *Config) GetTimeout() time.Duration

GetTimeout returns the HTTP request timeout, defaulting to one minute when client settings are absent or their timeout is zero.

func (*Config) GetURL

func (c *Config) GetURL() string

GetURL returns the GitHub REST API URL, defaulting to https://api.github.com/ when no URL is configured.

type ConnectionParams added in v0.13.0

type ConnectionParams struct {
	di.In

	Connections *client.Factory
	ID          id.Generator
	Config      *Config
	Logger      *logger.Logger
	UserAgent   env.UserAgent
}

ConnectionParams supplies shared HTTP settings and lifecycle dependencies.

type EnablePullRequestAutoMergeInput added in v0.9.0

type EnablePullRequestAutoMergeInput struct {
	PullRequestID   string `json:"pullRequestId"`
	ExpectedHeadOID string `json:"expectedHeadOid"`
	MergeMethod     string `json:"mergeMethod"`
}

EnablePullRequestAutoMergeInput selects a PR and merge method for auto-merge, guarded by ExpectedHeadOID against concurrent pushes.

type EnablePullRequestAutoMergeRequest added in v0.9.0

type EnablePullRequestAutoMergeRequest struct {
	Query     string `json:"query"`
	Variables struct {
		Input EnablePullRequestAutoMergeInput `json:"input"`
	} `json:"variables"`
}

EnablePullRequestAutoMergeRequest encodes GitHub's auto-merge mutation.

type EnablePullRequestAutoMergeResponse added in v0.9.0

type EnablePullRequestAutoMergeResponse struct {
	Data struct {
		Enable struct {
			PullRequest struct {
				ID string `json:"id"`
			} `json:"pullRequest"`
		} `json:"enablePullRequestAutoMerge"`
	} `json:"data"`
	Errors Errors `json:"errors"`
}

EnablePullRequestAutoMergeResponse requires validation even on HTTP success.

func (*EnablePullRequestAutoMergeResponse) Validate added in v0.9.0

func (r *EnablePullRequestAutoMergeResponse) Validate(expectedID string) error

Validate rejects GraphQL errors and responses identifying a different PR.

type Errors added in v0.9.0

type Errors []struct {
	Message string `json:"message"`
	Type    string `json:"type"`
}

Errors contains GraphQL failures that may accompany data even on HTTP success.

func (Errors) Validate added in v0.9.0

func (e Errors) Validate() error

Validate joins reported failures and includes ErrRateLimited for rate limits. It returns nil when Errors is empty or nil.

type IssueComment added in v0.13.0

type IssueComment = github.IssueComment

IssueComment aliases github.IssueComment for signed command requests.

type IssueCommentEvent added in v0.13.0

type IssueCommentEvent = github.IssueCommentEvent

IssueCommentEvent aliases github.IssueCommentEvent for verified deliveries.

type IssueEvent added in v0.12.0

type IssueEvent = github.IssueEvent

IssueEvent aliases github.IssueEvent for pull request automation history.

type Label added in v0.13.0

type Label = github.Label

Label aliases github.Label for shared label membership checks.

type PullRequest

type PullRequest = github.PullRequest

PullRequest aliases github.PullRequest so consumers use the project-owned package.

type PullRequestAutomationEventsRequest added in v0.12.0

type PullRequestAutomationEventsRequest struct {
	Variables struct {
		ID    string  `json:"id"`
		After *string `json:"after"`
	} `json:"variables"`
	Query string `json:"query"`
}

PullRequestAutomationEventsRequest identifies a PR by node ID and supplies the cursor for the next page of its automation history.

type PullRequestAutomationEventsResponse added in v0.12.0

type PullRequestAutomationEventsResponse struct {
	Data struct {
		Node struct {
			ID            string `json:"id"`
			TimelineItems struct {
				Nodes    []*IssueEvent `json:"nodes"`
				PageInfo struct {
					EndCursor   *string `json:"endCursor"`
					HasNextPage *bool   `json:"hasNextPage"`
				} `json:"pageInfo"`
			} `json:"timelineItems"`
		} `json:"node"`
	} `json:"data"`
	Errors Errors `json:"errors"`
}

PullRequestAutomationEventsResponse decodes timeline history into SDK issue-event snapshots. Call Validate before using the history, even when the HTTP request succeeds.

func (*PullRequestAutomationEventsResponse) Validate added in v0.12.0

func (r *PullRequestAutomationEventsResponse) Validate(expectedID string) error

Validate rejects GraphQL errors, a PR node ID different from expectedID, incomplete pages, and events that cannot establish valid automation history.

type RefUpdate added in v0.29.0

type RefUpdate struct {
	Name      string `json:"name"`
	BeforeOID string `json:"beforeOid"`
	AfterOID  string `json:"afterOid"`
}

RefUpdate carries the expected and replacement OIDs for an atomic ref update.

type Repository

type Repository = github.Repository

Repository aliases github.Repository to keep SDK imports in this package.

type RepositoryCommit added in v0.29.0

type RepositoryCommit = github.RepositoryCommit

RepositoryCommit aliases github.RepositoryCommit for commit age checks.

type Service added in v0.8.0

type Service interface {
	// ListBranches collects complete, validated branch pagination before cleanup.
	ListBranches(ctx context.Context, repo *Repository) ([]*Branch, error)

	// GetBranch rechecks branch identity, protection, and head without redirects.
	GetBranch(ctx context.Context, repo *Repository, name string) (*Branch, error)

	// GetCommit reads an immutable commit and requires a matching SHA and date.
	GetCommit(ctx context.Context, repo *Repository, sha string) (*RepositoryCommit, error)

	// ListBranchPullRequests collects complete head-branch history, including open PRs.
	ListBranchPullRequests(ctx context.Context, repo *Repository, branch string) ([]*PullRequest, error)

	// DeleteBranch deletes a branch only while its expected SHA still matches.
	// GraphQL failures and unconfirmed responses fail without mutation retries.
	DeleteBranch(ctx context.Context, repo *Repository, branch *Branch) error

	// ValidateInstallation checks the configured App, owner, and suspension state
	// without caching. Comment commands must call it before accessing repositories.
	ValidateInstallation(ctx context.Context) error

	// GetComment reads the current comment and verifies its PR and author identity.
	GetComment(ctx context.Context, repo *Repository, number int, expected *IssueComment) (*IssueComment, error)

	// HasWritePermission checks the author's current repository permissions.
	HasWritePermission(ctx context.Context, repo *Repository, author *User) (bool, error)

	// AddLabel adds one label without replacing others or retrying mutations.
	AddLabel(ctx context.Context, repo *Repository, number int, label string) error

	// AddCommentReaction adds a reaction as the App. Repeated reactions are
	// idempotent in GitHub; mutation requests are not retried.
	AddCommentReaction(ctx context.Context, repo *Repository, comment *IssueComment, content string) error

	// AddComment publishes feedback once and validates the response. An ambiguous
	// failure may have published the comment; callers must not retry automatically.
	AddComment(ctx context.Context, repo *Repository, number int, body string) error

	// ListComments collects complete comment history and validates each comment's PR identity.
	ListComments(ctx context.Context, repo *Repository, number int) ([]*IssueComment, error)

	// IsAppComment requires a bot author and the configured GitHub App identity.
	IsAppComment(comment *IssueComment) bool

	// ListPullRequestFiles rejects incomplete pagination and mismatched file counts.
	ListPullRequestFiles(ctx context.Context, repo *Repository, pull *PullRequest) ([]*CommitFile, error)

	// ListRepositories validates the authenticated owner and collects all pages
	// before returning active owned repositories accessible to the installation.
	ListRepositories(ctx context.Context) ([]*Repository, error)

	// GetRepository reads full settings omitted by discovery and validates that
	// the response identifies the discovered repository.
	GetRepository(ctx context.Context, repo *Repository) (*Repository, error)

	// IsSameRepository checks that both PR branches belong to the discovered
	// repository, comparing names case-insensitively.
	IsSameRepository(repo *Repository, pull *PullRequest) bool

	// IsBaseRepository checks that the PR targets the discovered repository,
	// comparing names case-insensitively. Its head may belong to a fork.
	IsBaseRepository(repo *Repository, pull *PullRequest) bool

	// IsSamePullRequest compares identity, branch repositories, refs, and head
	// SHA across snapshots. Repository names are compared case-insensitively.
	IsSamePullRequest(current, expected *PullRequest) bool

	// ListOpenPullRequests collects all pages in ascending creation order before
	// returning so mutations cannot change ordering partway through pagination.
	ListOpenPullRequests(ctx context.Context, repo *Repository) ([]*PullRequest, error)

	// GetPullRequest reads fresh auto-merge, branch, and identity state.
	GetPullRequest(ctx context.Context, repo *Repository, number int) (*PullRequest, error)

	// ListPullRequestAutomationEvents collects all label and auto-merge-disable
	// events through GraphQL. Event names are GraphQL type names. Errors,
	// incomplete pages, and mismatched PR identities reject the whole history.
	ListPullRequestAutomationEvents(ctx context.Context, pull *PullRequest) ([]*IssueEvent, error)

	// Compare reports commits missing from head relative to base. A missing
	// behind_by is an error rather than evidence that the branch is current.
	Compare(ctx context.Context, repo *Repository, base, head string) (*CommitsComparison, error)

	// Rebase requests a server-side rebase guarded by the expected head SHA.
	// HTTP failures, GraphQL errors, and mismatched responses fail without
	// retrying the mutation. Success confirms acceptance, not completion.
	Rebase(ctx context.Context, pull *PullRequest) error

	// EnableAutoMerge requests squash merging once GitHub's requirements pass,
	// guarded by the expected head SHA. Failures are not retried.
	EnableAutoMerge(ctx context.Context, pull *PullRequest) error

	// Merge squash-merges a ready pull request, guarded by its head SHA.
	// A rejected or unconfirmed merge fails without retrying.
	Merge(ctx context.Context, repo *Repository, pull *PullRequest) error
}

Service owns repository discovery, identity checks, REST reads, and guarded mutations. Callers own pull request eligibility, rebase, and merge policy.

func NewService added in v0.8.0

func NewService(cfg *Config, client *Client, log *logger.Logger) Service

NewService constructs shared worker and webhook access through the App client. Construction does not contact GitHub; each sweep discovers fresh remote state.

type UpdatePullRequestBranchInput

type UpdatePullRequestBranchInput struct {
	PullRequestID   string `json:"pullRequestId"`
	ExpectedHeadOID string `json:"expectedHeadOid"`
	UpdateMethod    string `json:"updateMethod"`
}

UpdatePullRequestBranchInput supplies GitHub's branch-update arguments. ExpectedHeadOID rejects concurrent head changes; UpdateMethod selects REBASE or MERGE.

type UpdatePullRequestBranchRequest

type UpdatePullRequestBranchRequest struct {
	Query     string `json:"query"`
	Variables struct {
		Input UpdatePullRequestBranchInput `json:"input"`
	} `json:"variables"`
}

UpdatePullRequestBranchRequest encodes a branch-update mutation. Query must declare $input with the GraphQL type UpdatePullRequestBranchInput.

type UpdatePullRequestBranchResponse

type UpdatePullRequestBranchResponse struct {
	Data struct {
		Update struct {
			PullRequest struct {
				ID string `json:"id"`
			} `json:"pullRequest"`
		} `json:"updatePullRequestBranch"`
	} `json:"data"`
	Errors Errors `json:"errors"`
}

UpdatePullRequestBranchResponse decodes GitHub's branch-update mutation. HTTP success can include GraphQL errors or incomplete data; call Validate before treating an update as accepted.

func (*UpdatePullRequestBranchResponse) Validate

func (r *UpdatePullRequestBranchResponse) Validate(expectedID string) error

Validate returns joined GraphQL errors or an error when the payload does not identify expectedID. A matching payload confirms acceptance, not completion.

type UpdateRefsRequest added in v0.29.0

type UpdateRefsRequest struct {
	Query     string `json:"query"`
	Variables struct {
		Input struct {
			RepositoryID     string      `json:"repositoryId"`
			ClientMutationID string      `json:"clientMutationId"`
			RefUpdates       []RefUpdate `json:"refUpdates"`
		} `json:"input"`
	} `json:"variables"`
}

UpdateRefsRequest deletes one branch with an atomic expected-commit guard. The zero AfterOID deletes the reference; ClientMutationID must be echoed.

type UpdateRefsResponse added in v0.29.0

type UpdateRefsResponse struct {
	Data struct {
		Update *struct {
			ClientMutationID string `json:"clientMutationId"`
		} `json:"updateRefs"`
	} `json:"data"`
	Errors Errors `json:"errors"`
}

UpdateRefsResponse requires a matching mutation ID and no GraphQL errors.

func (*UpdateRefsResponse) Validate added in v0.29.0

func (r *UpdateRefsResponse) Validate(expectedID string) error

Validate rejects absent, unconfirmed, or failed reference updates.

type User added in v0.13.0

type User = github.User

User aliases github.User for current command-author permission checks.

type Webhook added in v0.13.0

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

Webhook verifies raw GitHub deliveries before exposing SDK events to policies. It holds no delivery history; policy must re-read current remote state.

func NewWebhook added in v0.13.0

func NewWebhook(cfg *Config, filesystem *os.FS) (*Webhook, error)

NewWebhook resolves optional delivery credentials at startup, returning nil when webhook configuration is disabled. A configured webhook requires App credentials, a nonempty secret, and a timeout below ten seconds.

func (*Webhook) GetTimeout added in v0.13.0

func (w *Webhook) GetTimeout() time.Duration

GetTimeout returns the independent synchronous processing budget.

func (*Webhook) Read added in v0.13.0

func (w *Webhook) Read(req *http.Request) (*IssueCommentEvent, error)

Read verifies SHA-256 signatures and installation/repository identity. Signed events other than newly created PR comments are acknowledged without action.

type WebhookConfig added in v0.13.0

type WebhookConfig struct {
	Secret  string        `yaml:"secret,omitempty" json:"secret,omitempty" toml:"secret,omitempty" validate:"required"`
	Timeout time.Duration `yaml:"timeout,omitempty" json:"timeout,omitempty" toml:"timeout,omitempty"`
}

WebhookConfig enables signed GitHub comment deliveries with App credentials. Secret is a go-service source read at startup. Timeout bounds synchronous processing and defaults to five seconds, below GitHub's ten-second deadline.

func (*WebhookConfig) GetTimeout added in v0.13.0

func (c *WebhookConfig) GetTimeout() time.Duration

GetTimeout returns the delivery processing budget, defaulting to five seconds.

func (*WebhookConfig) IsEnabled added in v0.21.0

func (c *WebhookConfig) IsEnabled() bool

IsEnabled reports whether webhook configuration is present.

func (*WebhookConfig) IsValid added in v0.21.0

func (c *WebhookConfig) IsValid() bool

IsValid reports whether the configured processing budget is positive and below GitHub's ten-second deadline. A zero timeout uses the default budget.

Jump to

Keyboard shortcuts

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