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
- Variables
- func IsPreviewEnvName(name string) bool
- func PreviewEnvName(pr int64) string
- func SignPayload(secret, body []byte) string
- type App
- type AppStore
- type Commenter
- type Deduper
- type Deployer
- type GitHubApp
- func (g *GitHubApp) CommentPR(ctx context.Context, token, repo string, pr int64, comment string) error
- func (g *GitHubApp) InstallationToken(ctx context.Context, installationID int64) (string, error)
- func (g *GitHubApp) SetCommitStatus(ctx context.Context, token, repo, sha, state, targetURL, description string) error
- type Option
- type PreviewEnv
- type PreviewStore
- type Previews
- type PullRequestEvent
- type TokenSource
- type Webhook
Constants ¶
const ( StatusPending = "pending" StatusSuccess = "success" StatusFailure = "failure" )
CommitStatus states for SetCommitStatus.
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 ¶
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 ¶
IsPreviewEnvName reports whether name belongs to a preview environment.
func PreviewEnvName ¶
PreviewEnvName is the environment name for a pull request.
func SignPayload ¶
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 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 ¶
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 ¶
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 ¶
InstallationToken returns a cached-or-fresh access token for an installation.
type Option ¶
type Option func(*GitHubApp)
Option configures a GitHubApp.
func WithBaseURL ¶
WithBaseURL overrides the GitHub API base (tests point it at httptest).
func WithHTTPClient ¶
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 ¶
OnPullRequest applies a pull_request event: open/reopen/synchronize ensure a preview exists and is deployed at the head SHA; close deletes it.
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 ¶
EnablePreviews turns on PR → preview-<n> environments (T-75). Without it pull_request events are acknowledged and ignored.