github

package
v0.1.0-alpha.8 Latest Latest
Warning

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

Go to latest
Published: Jul 18, 2026 License: Apache-2.0 Imports: 22 Imported by: 0

Documentation

Overview

Package github implements push-to-deploy: a webhook endpoint that turns GitHub push events into builds, and GitHub App authentication for cloning private repos and posting commit statuses (spec F9, T-37).

Index

Constants

View Source
const (
	StatusPending = "pending"
	StatusSuccess = "success"
	StatusFailure = "failure"
)

CommitStatus states for SetCommitStatus.

View Source
const (
	// DefaultPreviewTTL is how long a preview survives without a new push. Every
	// PR event extends it; the janitor deletes previews past their deadline.
	DefaultPreviewTTL = 7 * 24 * time.Hour
	// DefaultMaxPreviewsPerApp caps concurrent previews per app. The cap exists
	// to protect the cluster's Let's Encrypt rate limit: every preview needs a
	// certificate for its own <app>-preview-<n>.<domain> hostname.
	DefaultMaxPreviewsPerApp = 5
)

Preview environment policy (spec §3.6, T-75).

Variables

View Source
var ErrPreviewCapReached = errors.New("github: preview environment cap reached")

ErrPreviewCapReached is returned when an app already has the maximum number of concurrent preview environments.

Functions

func IsPreviewEnvName

func IsPreviewEnvName(name string) bool

IsPreviewEnvName reports whether name belongs to a preview environment.

func PreviewEnvName

func PreviewEnvName(pr int64) string

PreviewEnvName is the environment name for a pull request.

func SignPayload

func SignPayload(secret, body []byte) string

SignPayload returns the "sha256=<hex>" signature for a body (used by tests and the CLI setup helper).

Types

type App

type App struct {
	ProjectID          string
	AppID              string
	Repo               string // "owner/name"
	InstallationID     int64
	WebhookSecret      []byte // unsealed HMAC secret
	BranchEnvironments map[string]string
}

App is the resolved GitHub configuration for a repository.

type AppStore

type AppStore interface {
	AppByRepo(repo string) (*App, bool)
}

AppStore resolves a repo ("owner/name") to its configured app.

type Commenter

type Commenter interface {
	CommentPR(ctx context.Context, token, repo string, pr int64, body string) error
}

Commenter posts a comment on a pull request.

type Deduper

type Deduper interface {
	Seen(deliveryID string) bool
}

Deduper records processed delivery ids (with a TTL) so redelivered webhooks are not built twice. Seen returns true if the id was already recorded.

type Deployer

type Deployer interface {
	DeployGit(ctx context.Context, app *App, envName, branch, sha, cloneURL, token string) (deploymentID string, err error)
}

Deployer creates a build + deployment for a pushed commit.

type GitHubApp

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

GitHubApp authenticates as a GitHub App: it signs a short-lived JWT with the app private key, exchanges it for per-installation access tokens (cached until just before expiry), and posts commit statuses.

func NewGitHubApp

func NewGitHubApp(appID int64, pemKey []byte, opts ...Option) (*GitHubApp, error)

NewGitHubApp builds an app authenticator from a PEM-encoded RSA private key.

func (*GitHubApp) CommentPR

func (g *GitHubApp) CommentPR(ctx context.Context, token, repo string, pr int64, comment string) error

CommentPR posts an issue comment on a pull request (PRs are issues in the REST API) using an installation token — used to announce preview URLs (T-75).

func (*GitHubApp) InstallationToken

func (g *GitHubApp) InstallationToken(ctx context.Context, installationID int64) (string, error)

InstallationToken returns a cached-or-fresh access token for an installation.

func (*GitHubApp) SetCommitStatus

func (g *GitHubApp) SetCommitStatus(ctx context.Context, token, repo, sha, state, targetURL, description string) error

SetCommitStatus posts a commit status (pending/success/failure) using an installation token.

type Option

type Option func(*GitHubApp)

Option configures a GitHubApp.

func WithBaseURL

func WithBaseURL(u string) Option

WithBaseURL overrides the GitHub API base (tests point it at httptest).

func WithClock

func WithClock(c clock.Clock) Option

WithClock overrides the clock (tests use a fake).

func WithHTTPClient

func WithHTTPClient(c *http.Client) Option

WithHTTPClient overrides the HTTP client.

type PreviewEnv

type PreviewEnv struct {
	ID        string
	Name      string
	AppID     string
	ProjectID string
	PRNumber  int64
	// HeadSHA is the commit of the environment's newest release, used to skip
	// redundant rebuilds when GitHub replays a synchronize for a SHA we already
	// deployed (force-push storms send several in a row).
	HeadSHA   string
	ExpiresAt time.Time
}

PreviewEnv is the control plane's view of one preview environment.

type PreviewStore

type PreviewStore interface {
	// ListPreviews returns the app's current preview environments.
	ListPreviews(appID string) []PreviewEnv
	// AllPreviews returns every preview environment in the cluster (janitor).
	AllPreviews() []PreviewEnv
	// CreatePreview creates a PREVIEW environment named name, cloning its
	// service spec from the app's base (staging) environment.
	CreatePreview(ctx context.Context, app *App, name string, pr int64, expiresAt time.Time) (PreviewEnv, error)
	// TouchPreview extends an existing preview's TTL.
	TouchPreview(ctx context.Context, env PreviewEnv, expiresAt time.Time) error
	// DeletePreview removes the environment; teardown of its containers is a
	// cascade handled by the scheduler's orphan reconciler.
	DeletePreview(ctx context.Context, env PreviewEnv) error
	// PreviewURL renders the public URL an environment is reachable at.
	PreviewURL(app *App, envName string) string
}

PreviewStore is the control-plane port for preview environment lifecycle. The api package implements it against cluster state + raft.

type Previews

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

Previews turns pull-request events into preview environments and reaps expired ones. All policy (cap, TTL, SHA dedupe) lives here; storage and GitHub I/O are ports so this is unit-testable end to end.

func NewPreviews

func NewPreviews(store PreviewStore, deployer Deployer, tokens TokenSource, comments Commenter, clk clock.Clock, log *slog.Logger) *Previews

NewPreviews builds the preview manager. comments may be nil (no PR comments).

func (*Previews) OnPullRequest

func (p *Previews) OnPullRequest(ctx context.Context, app *App, ev PullRequestEvent) error

OnPullRequest applies a pull_request event: open/reopen/synchronize ensure a preview exists and is deployed at the head SHA; close deletes it.

func (*Previews) SweepExpired

func (p *Previews) SweepExpired(ctx context.Context) int

SweepExpired deletes every preview past its deadline. Returns the number deleted. Called from a leader-gated janitor loop.

type PullRequestEvent

type PullRequestEvent struct {
	Action   string
	Number   int64
	Branch   string // head ref
	HeadSHA  string
	CloneURL string
}

PullRequestEvent is the subset of GitHub's pull_request payload we act on.

type TokenSource

type TokenSource interface {
	InstallationToken(ctx context.Context, installationID int64) (string, error)
}

TokenSource mints GitHub App installation access tokens for cloning.

type Webhook

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

Webhook is the POST /v1/github/webhook handler.

func NewWebhook

func NewWebhook(apps AppStore, deployer Deployer, dedup Deduper, tokens TokenSource, log *slog.Logger) *Webhook

NewWebhook builds the webhook handler.

func (*Webhook) EnablePreviews

func (h *Webhook) EnablePreviews(p *Previews)

EnablePreviews turns on PR → preview-<n> environments (T-75). Without it pull_request events are acknowledged and ignored.

func (*Webhook) ServeHTTP

func (h *Webhook) ServeHTTP(w http.ResponseWriter, r *http.Request)

func (*Webhook) Wait

func (h *Webhook) Wait()

Wait blocks until all async deploy jobs finish (used by tests).

Jump to

Keyboard shortcuts

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