Documentation
¶
Overview ¶
Package githubapp implements an http.Handler for GitHub events and provides utilities for building GitHub applications. Most users will create implementations of githubapp.EventHandler to handle different webhook event types and register them with the event dispatcher.
Many functions are instrumented with optional logging and metrics collection. The package also defines functions to create authenticated GitHub clients and manage application installations.
Index ¶
- Constants
- func DefaultErrorHandler(w http.ResponseWriter, r *http.Request, err error)
- func GetInstallationIDFromEvent(event InstallationSource) int64
- func NewDefaultEventDispatcher(c Config, handlers ...EventHandler) http.Handler
- func NewEventDispatcher(handlers []EventHandler, secret string, onError ErrorHandler) http.Handler
- func PreparePRContext(ctx context.Context, installationID int64, repo *github.Repository, number int) (context.Context, zerolog.Logger)
- func PrepareRepoContext(ctx context.Context, installationID int64, repo *github.Repository) (context.Context, zerolog.Logger)
- type ClientCreator
- type ClientMiddleware
- type ClientOption
- type Config
- type ErrorHandler
- type EventHandler
- type Installation
- type InstallationNotFound
- type InstallationSource
- type InstallationsService
Constants ¶
const ( LogKeyEventType string = "github_event_type" LogKeyDeliveryID string = "github_delivery_id" LogKeyRepositoryName string = "github_repository_name" LogKeyRepositoryOwner string = "github_repository_owner" LogKeyPRNum string = "github_pr_num" LogKeyInstallationID string = "github_installation_id" )
const ( MetricsKeyRequests = "github.requests" MetricsKeyRequests2xx = "github.requests.2xx" MetricsKeyRequests3xx = "github.requests.3xx" MetricsKeyRequests4xx = "github.requests.4xx" MetricsKeyRequests5xx = "github.requests.5xx" )
const (
DefaultCachingClientCapacity = 64
)
const (
DefaultWebhookRoute string = "/api/github/hook"
)
Variables ¶
This section is empty.
Functions ¶
func DefaultErrorHandler ¶
func DefaultErrorHandler(w http.ResponseWriter, r *http.Request, err error)
DefaultErrorHandler logs errors and responds with a 500 status code.
func GetInstallationIDFromEvent ¶
func GetInstallationIDFromEvent(event InstallationSource) int64
GetInstallationIDFromEvent returns the installation ID from a GitHub webhook event payload.
func NewDefaultEventDispatcher ¶
func NewDefaultEventDispatcher(c Config, handlers ...EventHandler) http.Handler
NewDefaultEventDispatcher is a convenience method to create an EventDispatcher from configuration using the default error handler.
func NewEventDispatcher ¶
func NewEventDispatcher(handlers []EventHandler, secret string, onError ErrorHandler) http.Handler
NewEventDispatcher creates an http.Handler that dispatches GitHub webhook requests to the appropriate event handlers. It validates payload integrity using the given secret value.
If an error occurs during handling, the error handler is called with the error and should write an appropriate response. If the error handler is nil, a default handler is used.
Types ¶
type ClientCreator ¶
type ClientCreator interface { // NewAppClient returns a new github.Client that performs app authentication for // the GitHub app with a specific integration ID and private key. The returned // client makes all calls using the application's authorization token. The // client gets that token by creating and signing a JWT for the application and // requesting a token using it. The token is cached by the client and is // refreshed as needed if it expires. // // Used for performing app-level operations that are not associated with a // specific installation. // // See the following for more information: // * https://developer.github.com/apps/building-github-apps/authenticating-with-github-apps/#authenticating-as-a-github-app // // Authenticating as a GitHub App lets you do a couple of things: // * You can retrieve high-level management information about your GitHub App. // * You can request access tokens for an installation of the app. // // Tips for determining the arguments for this function: // * the integration ID is listed as "ID" in the "About" section of the app's page // * the key bytes must be a PEM-encoded PKCS1 or PKCS8 private key for the application NewAppClient() (*github.Client, error) // NewAppV4Client returns an app-authenticated v4 API client, similar to NewAppClient. NewAppV4Client() (*githubv4.Client, error) // NewInstallationClient returns a new github.Client that performs app // authentication for the GitHub app with the a specific integration ID, private // key, and the given installation ID. The returned client makes all calls using // the application's authorization token. The client gets that token by creating // and signing a JWT for the application and requesting a token using it. The // token is cached by the client and is refreshed as needed if it expires. // // See the following for more information: // * https://developer.github.com/apps/building-github-apps/authenticating-with-github-apps/#authenticating-as-an-installation // // Authenticating as an installation of a Github App lets you perform the following: // * https://developer.github.com/v3/apps/available-endpoints/ // // Tips for determining the arguments for this function: // * the integration ID is listed as "ID" in the "About" section of the app's page // * the installation ID is the ID that is shown in the URL of https://{githubURL}/settings/installations/{#} // (navigate to the "installations" page without the # and go to the app's page to see the number) // * the key bytes must be a PEM-encoded PKCS1 or PKCS8 private key for the application NewInstallationClient(installationID int64) (*github.Client, error) // NewInstallationV4Client returns an installation-authenticated v4 API client, similar to NewInstallationClient. NewInstallationV4Client(installationID int64) (*githubv4.Client, error) // NewTokenClient returns a *github.Client that uses the passed in OAuth token for authentication. NewTokenClient(token string) (*github.Client, error) // NewTokenV4Client returns a *githubv4.Client that uses the passed in OAuth token for authentication. NewTokenV4Client(token string) (*githubv4.Client, error) }
func NewCachingClientCreator ¶
func NewCachingClientCreator(delegate ClientCreator, capacity int) (ClientCreator, error)
NewCachingClientCreator returns a ClientCreator that creates a GitHub client for installations of the app specified by the provided arguments. It uses an LRU cache of the provided capacity to store clients created for installations and returns cached clients when a cache hit exists.
func NewClientCreator ¶
func NewClientCreator(v3BaseURL, v4BaseURL string, integrationID int, privKeyBytes []byte, opts ...ClientOption) ClientCreator
NewClientCreator returns a ClientCreator that creates a GitHub client for installations of the app specified by the provided arguments.
func NewDefaultCachingClientCreator ¶
func NewDefaultCachingClientCreator(c Config, opts ...ClientOption) (ClientCreator, error)
NewDefaultCachingClientCreator returns a ClientCreator using values from the configuration or other defaults.
type ClientMiddleware ¶
type ClientMiddleware func(http.RoundTripper) http.RoundTripper
ClientMiddleware modifes the transport of a GitHub client to add common functionality, like logging or metrics collection.
func ClientLogging ¶
func ClientLogging(lvl zerolog.Level) ClientMiddleware
ClientLogging creates client middleware that logs request and response information at the given level. If the request fails without creating a response, it is logged with a status code of -1. The middleware uses a logger from the request context.
func ClientMetrics ¶
func ClientMetrics(registry metrics.Registry) ClientMiddleware
ClientMetrics creates client middleware that records metrics about all requests. It also defines the metrics in the provided registry.
type ClientOption ¶
type ClientOption func(c *clientCreator)
func WithClientMiddleware ¶
func WithClientMiddleware(middleware ...ClientMiddleware) ClientOption
WithClientMiddleware adds middleware that is applied to all created clients.
func WithClientUserAgent ¶
func WithClientUserAgent(agent string) ClientOption
WithClientUserAgent sets the base user agent for all created clients.
type Config ¶
type Config struct { WebURL string `yaml:"web_url" json:"webUrl"` V3APIURL string `yaml:"v3_api_url" json:"v3ApiUrl"` V4APIURL string `yaml:"v4_api_url" json:"v4ApiUrl"` App struct { IntegrationID int `yaml:"integration_id" json:"integrationId"` WebhookSecret string `yaml:"webhook_secret" json:"webhookSecret"` PrivateKey string `yaml:"private_key" json:"privateKey"` } `yaml:"app" json:"app"` OAuth struct { ClientID string `yaml:"client_id" json:"clientId"` ClientSecret string `yaml:"client_secret" json:"clientSecret"` } `yaml:"oauth" json:"oauth"` }
type ErrorHandler ¶
type ErrorHandler func(http.ResponseWriter, *http.Request, error)
type EventHandler ¶
type EventHandler interface { // Handles returns a list of GitHub events that this handler handles // See https://developer.github.com/v3/activity/events/types/ Handles() []string // Handle processes the GitHub event "eventType" with the given delivery ID // and payload. The EventDispatcher guarantees that the Handle method will // only be called for the events returned by Handles(). // // If Handle returns an error, processing stops and the error is passed // directly to the configured error handler. Handle(ctx context.Context, eventType, deliveryID string, payload []byte) error }
type Installation ¶
Installation is a minimal representation of a GitHub app installation.
type InstallationNotFound ¶
type InstallationNotFound string
InstallationNotFound is returned when no installation exists for a specific owner or repository.
func (InstallationNotFound) Error ¶
func (err InstallationNotFound) Error() string
type InstallationSource ¶
type InstallationSource interface {
GetInstallation() *github.Installation
}
InstallationSource is implemented by GitHub webhook event payload types.
type InstallationsService ¶
type InstallationsService interface { // ListAll returns all installations for this app. ListAll(ctx context.Context) ([]Installation, error) // GetByOwner returns the installation for an owner (user or organization). // It returns an InstallationNotFound error if no installation exists for // the owner. GetByOwner(ctx context.Context, owner string) (Installation, error) }
InstallationsService retrieves installation information for a given app. Implementations may chose how to retrieve, store, or cache these values.
This service is useful for background processes that do not respond directly to webhooks, since webhooks provide installation IDs in their payloads.
func NewInstallationsService ¶
func NewInstallationsService(appClient *github.Client) InstallationsService
NewInstallationsService returns an InstallationsService that always queries GitHub. It should be created with a client that authenticates as the target application.