Documentation
¶
Overview ¶
Package githubhook authenticates and parses inbound GitHub webhook requests. It exposes a constant-time HMAC verifier, an HTTP middleware that gates a downstream handler, and a JSON parser for the pull request payloads we care about.
Index ¶
Constants ¶
const MaxBodyBytes int64 = 1 << 20 // 1 MiB
MaxBodyBytes caps the size of an accepted webhook body. GitHub limits its own webhook payloads to ~25 MiB but our handler should not need anywhere near that — a generous 1 MiB protects against memory exhaustion attacks.
const SignatureHeader = "X-Hub-Signature-256"
SignatureHeader is the HTTP header GitHub uses to carry the HMAC-SHA256 digest of the raw request body.
Variables ¶
var ErrInvalidSignature = errors.New("githubhook: invalid signature")
ErrInvalidSignature is returned when the signature does not match.
var ErrMissingPRNumber = errors.New("githubhook: missing pull_request.number")
ErrMissingPRNumber is returned when the payload lacks a pull request number.
Functions ¶
func NewHandler ¶
NewHandler returns an http.Handler that parses the JSON body of an inbound GitHub webhook and forwards the parsed Payload to sink.
The handler assumes the body has already been validated by SignatureMiddleware. It returns:
- 400 if the body is not valid JSON,
- 400 if the payload has no pull_request.number,
- 200 with body `"ok"` after the sink runs successfully,
- 500 if the sink returns an error.
Response bodies are intentionally generic; details go to logs.
func SignatureMiddleware ¶
SignatureMiddleware returns an HTTP middleware that:
- rejects any request whose body exceeds MaxBodyBytes (413),
- rejects any request whose X-Hub-Signature-256 header does not match the HMAC of the body (401),
- passes a fresh body reader to next, so downstream handlers can read the verified body without juggling the raw stream themselves.
Types ¶
type EventSink ¶
EventSink receives a parsed Payload. It is the seam between the HTTP layer and the pullrequest dispatcher; defining it here keeps githubhook unaware of any downstream package.
type Payload ¶
type Payload struct {
Event string
Action string
Repository string
PullRequest PullRequest
// Review is non-nil only for pull_request_review events.
Review *Review
// PRComment is true for issue_comment events fired on a pull request —
// the payload carries an issue.pull_request reference. It is false for
// comments on plain issues, which handlers ignore.
PRComment bool
// Sender is the actor who fired the event (GitHub's `sender` object).
// Zero value when the field is absent in the payload.
Sender Sender
}
Payload is the parsed view of an inbound GitHub webhook body, holding only the fields the notifier uses. Adding a new event-type usually means extending this struct rather than adding a new parser.
func ParsePayload ¶
ParsePayload decodes a raw GitHub webhook body into a Payload. It validates only what the dispatcher needs (PR number > 0); everything else is treated as best-effort and surfaced to handlers, which decide their own preconditions.
type PullRequest ¶
PullRequest holds the PR fields extracted from the payload.
type Review ¶
type Review struct {
State string
}
Review carries the review state (approved | commented | changes_requested).
type Sender ¶ added in v0.5.0
Sender identifies the actor that fired the webhook. Type is "User" for humans and "Bot" for GitHub Apps or legacy bot accounts.
type Verifier ¶
type Verifier struct {
// contains filtered or unexported fields
}
Verifier checks HMAC-SHA256 signatures against a shared secret.
func NewVerifier ¶
NewVerifier returns a Verifier configured with the given shared secret.