gitlabwebhook

package module
v3.1.0 Latest Latest
Warning

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

Go to latest
Published: May 2, 2026 License: MIT Imports: 8 Imported by: 0

README

Gitlab Webhook Dispatcher 🚀

Supported Go Versions Package Version GoDoc codecov Go Report Card CI tests MIT license

This is a simple webhook dispatcher for Gitlab. It listens for incoming webhooks and dispatches them to the appropriate handler.

✨ Features

  • 📋 Very convenient registration of listeners
  • 🔄 A single listener can implement multiple different webhook functions
  • ⚡ Support asynchronous and efficient processing
  • 🚀 Multiple dispatch methods
  • 🔐 Token validation support for secure webhook handling

📦 Installation

go get github.com/flc1125/go-gitlab-webhook/v3

🔗 Compatibility

go-gitlab-webhook GitLab Go Client
1.x xanzy/go-gitlab
2.x gitlab-org/api/client-go
3.x gitlab-org/api/client-go/v2

💻 Usage

package main

import (
	"context"
	"log"
	"net/http"

	"github.com/flc1125/go-gitlab-webhook/v3"
	"gitlab.com/gitlab-org/api/client-go/v2"
)

var (
	_ gitlabwebhook.BuildListener         = (*testBuildListener)(nil)
	_ gitlabwebhook.CommitCommentListener = (*testCommitCommentListener)(nil)
	_ gitlabwebhook.BuildListener         = (*testBuildAndCommitCommentListener)(nil)
	_ gitlabwebhook.CommitCommentListener = (*testBuildAndCommitCommentListener)(nil)
)

type testBuildListener struct{}

func (l *testBuildListener) OnBuild(ctx context.Context, event *gitlab.BuildEvent) error {
	// do something
	return nil
}

type testCommitCommentListener struct{}

func (l *testCommitCommentListener) OnCommitComment(ctx context.Context, event *gitlab.CommitCommentEvent) error {
	// do something
	return nil
}

type testBuildAndCommitCommentListener struct{}

func (l *testBuildAndCommitCommentListener) OnBuild(ctx context.Context, event *gitlab.BuildEvent) error {
	// do something
	return nil
}

func (l *testBuildAndCommitCommentListener) OnCommitComment(ctx context.Context, event *gitlab.CommitCommentEvent) error {
	// do something
	return nil
}

func main() {
	dispatcher := gitlabwebhook.NewDispatcher(
		gitlabwebhook.RegisterListeners(
			&testBuildListener{},
			&testCommitCommentListener{},
			&testBuildAndCommitCommentListener{},
		),
		gitlabwebhook.WithMiddlewares(
			loggingMiddleware,
			// Only runs for push events.
			gitlabwebhook.MiddlewareForEvent(func(ctx context.Context, event *gitlab.PushEvent) error {
				log.Printf("push event: %s", event.Project.PathWithNamespace)
				return nil
			}),
		),
	)

	dispatcher.RegisterListeners(
		&testBuildListener{},
		&testCommitCommentListener{},
		&testBuildAndCommitCommentListener{},
	)

	http.Handle("/webhook", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if err := dispatcher.DispatchRequest(r,
			gitlabwebhook.DispatchRequestWithToken("your-secret-token"), // validate token, if needed
			gitlabwebhook.DispatchRequestWithContext(context.Background()), // custom context
			gitlabwebhook.DispatchRequestWithMaxBodyBytes(10<<20), // limit payload size to 10 MiB
		); err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}

		w.WriteHeader(http.StatusNoContent)
	}))

	if err := http.ListenAndServe(":8080", nil); err != nil {
		panic(err)
	}
}

func loggingMiddleware(next gitlabwebhook.HandlerFunc) gitlabwebhook.HandlerFunc {
	return func(ctx context.Context, event any) error {
		log.Printf("received webhook event: %T", event)
		return next(ctx, event)
	}
}

🔐 Security Notes

If your webhook endpoint is exposed publicly, limit request body size before parsing payloads. You can use DispatchRequestWithMaxBodyBytes when calling DispatchRequest, or enforce an equivalent limit in your HTTP server or reverse proxy.

📜 License

MIT License. See LICENSE for the full license text.

💖 Thanks

Documentation

Overview

Package gitlabwebhook dispatches GitLab webhook events to registered listeners.

Create a Dispatcher with NewDispatcher, register listeners, and pass incoming HTTP webhook requests to Dispatcher.DispatchRequest. Middleware can be added with WithMiddlewares or Dispatcher.Use before dispatching starts.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrUnsupportedEvent is returned when an event type has no registered dispatcher branch.
	ErrUnsupportedEvent = errors.New("gitlab-webhook: unsupported event type")
	// ErrInvalidToken is returned when the GitLab token header does not match.
	ErrInvalidToken = errors.New("gitlab-webhook: invalid token")
	// ErrPayloadTooLarge is returned when a request body exceeds the configured limit.
	ErrPayloadTooLarge = errors.New("gitlab-webhook: payload too large")
)

Functions

func Version added in v3.1.0

func Version() string

Version returns the module version.

Types

type BuildListener

type BuildListener interface {
	OnBuild(ctx context.Context, event *gitlab.BuildEvent) error
}

BuildListener handles GitLab build webhook events.

type CommitCommentListener

type CommitCommentListener interface {
	OnCommitComment(ctx context.Context, event *gitlab.CommitCommentEvent) error
}

CommitCommentListener handles GitLab commit comment webhook events.

type DeploymentListener

type DeploymentListener interface {
	OnDeployment(ctx context.Context, event *gitlab.DeploymentEvent) error
}

DeploymentListener handles GitLab deployment webhook events.

type DispatchRequestOption

type DispatchRequestOption func(*dispatchRequestOptions)

DispatchRequestOption configures Dispatcher.DispatchRequest.

func DispatchRequestWithContext

func DispatchRequestWithContext(ctx context.Context) DispatchRequestOption

DispatchRequestWithContext sets the context used for webhook dispatch.

By default, Dispatcher.DispatchRequest uses http.Request.Context.

func DispatchRequestWithMaxBodyBytes added in v3.1.0

func DispatchRequestWithMaxBodyBytes(max int64) DispatchRequestOption

DispatchRequestWithMaxBodyBytes limits the number of request body bytes read.

Values less than or equal to zero disable the limit and keep the default behavior. When the body exceeds max bytes, Dispatcher.DispatchRequest returns ErrPayloadTooLarge before parsing or dispatching the webhook.

func DispatchRequestWithToken

func DispatchRequestWithToken(token string) DispatchRequestOption

DispatchRequestWithToken requires the GitLab token header to match token.

When token is non-empty, Dispatcher.DispatchRequest compares it with the X-Gitlab-Token request header and returns ErrInvalidToken on mismatch.

type Dispatcher

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

Dispatcher routes parsed GitLab webhook events to registered listeners.

Configure a dispatcher before using it to handle events. Once dispatching starts, it is safe to call Dispatcher.Dispatch, Dispatcher.DispatchWebhook, and Dispatcher.DispatchRequest concurrently, but listener and middleware registration must be complete.

func NewDispatcher

func NewDispatcher(opts ...Option) *Dispatcher

NewDispatcher creates a dispatcher and applies its construction options.

A Dispatcher is safe for concurrent dispatch after construction is complete. Register all listeners and middleware before serving requests; mutating the dispatcher while events are being dispatched is not supported.

func (*Dispatcher) Dispatch

func (d *Dispatcher) Dispatch(ctx context.Context, event any) error

Dispatch sends an already parsed GitLab webhook event to registered listeners.

Registered Middleware runs before listener dispatch. Dispatch returns ErrUnsupportedEvent when event is not one of the supported GitLab webhook event pointer types.

func (*Dispatcher) DispatchRequest

func (d *Dispatcher) DispatchRequest(req *http.Request, opts ...DispatchRequestOption) error

DispatchRequest validates and dispatches an HTTP GitLab webhook http.Request.

The event type is read from the X-Gitlab-Event request header. If a token is configured, the X-Gitlab-Token header is validated before the request body is read. Body read errors, payload size errors, parse errors, and dispatch errors are returned to the caller.

func (*Dispatcher) DispatchWebhook

func (d *Dispatcher) DispatchWebhook(ctx context.Context, eventType gitlab.EventType, payload []byte) error

DispatchWebhook parses a GitLab webhook payload and dispatches the parsed event.

eventType selects the GitLab webhook parser branch. Parse errors are returned before middleware or listeners run. Parsed events are dispatched through Dispatcher.Dispatch.

func (*Dispatcher) RegisterBuildListener

func (d *Dispatcher) RegisterBuildListener(listeners ...BuildListener)

RegisterBuildListener registers listeners for build events.

func (*Dispatcher) RegisterCommitCommentListener

func (d *Dispatcher) RegisterCommitCommentListener(listeners ...CommitCommentListener)

RegisterCommitCommentListener registers listeners for commit comment events.

func (*Dispatcher) RegisterDeploymentListener

func (d *Dispatcher) RegisterDeploymentListener(listeners ...DeploymentListener)

RegisterDeploymentListener registers listeners for deployment events.

func (*Dispatcher) RegisterEmojiListener added in v3.0.1

func (d *Dispatcher) RegisterEmojiListener(listeners ...EmojiListener)

RegisterEmojiListener registers listeners for emoji events.

func (*Dispatcher) RegisterFeatureFlagListener

func (d *Dispatcher) RegisterFeatureFlagListener(listeners ...FeatureFlagListener)

RegisterFeatureFlagListener registers listeners for feature flag events.

func (*Dispatcher) RegisterGroupResourceAccessTokenListener

func (d *Dispatcher) RegisterGroupResourceAccessTokenListener(listeners ...GroupResourceAccessTokenListener)

RegisterGroupResourceAccessTokenListener registers listeners for group resource access token events.

func (*Dispatcher) RegisterIssueCommentListener

func (d *Dispatcher) RegisterIssueCommentListener(listeners ...IssueCommentListener)

RegisterIssueCommentListener registers listeners for issue comment events.

func (*Dispatcher) RegisterIssueListener

func (d *Dispatcher) RegisterIssueListener(listeners ...IssueListener)

RegisterIssueListener registers listeners for issue events.

func (*Dispatcher) RegisterJobListener

func (d *Dispatcher) RegisterJobListener(listeners ...JobListener)

RegisterJobListener registers listeners for job events.

func (*Dispatcher) RegisterListeners

func (d *Dispatcher) RegisterListeners(listeners ...any)

RegisterListeners registers values that implement one or more listener interfaces.

A listener can implement multiple listener interfaces and will be registered for each matching event type. Call this method before the dispatcher starts handling events; concurrent registration and dispatch is not supported.

func (*Dispatcher) RegisterMemberListener

func (d *Dispatcher) RegisterMemberListener(listeners ...MemberListener)

RegisterMemberListener registers listeners for member events.

func (*Dispatcher) RegisterMergeCommentListener

func (d *Dispatcher) RegisterMergeCommentListener(listeners ...MergeCommentListener)

RegisterMergeCommentListener registers listeners for merge request comment events.

func (*Dispatcher) RegisterMergeListener

func (d *Dispatcher) RegisterMergeListener(listeners ...MergeListener)

RegisterMergeListener registers listeners for merge request events.

func (*Dispatcher) RegisterMilestoneListener added in v3.0.1

func (d *Dispatcher) RegisterMilestoneListener(listeners ...MilestoneListener)

RegisterMilestoneListener registers listeners for milestone events.

func (*Dispatcher) RegisterPipelineListener

func (d *Dispatcher) RegisterPipelineListener(listeners ...PipelineListener)

RegisterPipelineListener registers listeners for pipeline events.

func (*Dispatcher) RegisterProjectListener added in v3.0.1

func (d *Dispatcher) RegisterProjectListener(listeners ...ProjectListener)

RegisterProjectListener registers listeners for project events.

func (*Dispatcher) RegisterProjectResourceAccessTokenListener

func (d *Dispatcher) RegisterProjectResourceAccessTokenListener(listeners ...ProjectResourceAccessTokenListener)

RegisterProjectResourceAccessTokenListener registers listeners for project resource access token events.

func (*Dispatcher) RegisterPushListener

func (d *Dispatcher) RegisterPushListener(listeners ...PushListener)

RegisterPushListener registers listeners for push events.

func (*Dispatcher) RegisterReleaseListener

func (d *Dispatcher) RegisterReleaseListener(listeners ...ReleaseListener)

RegisterReleaseListener registers listeners for release events.

func (*Dispatcher) RegisterSnippetCommentListener

func (d *Dispatcher) RegisterSnippetCommentListener(listeners ...SnippetCommentListener)

RegisterSnippetCommentListener registers listeners for snippet comment events.

func (*Dispatcher) RegisterSubGroupListener

func (d *Dispatcher) RegisterSubGroupListener(listeners ...SubGroupListener)

RegisterSubGroupListener registers listeners for subgroup events.

func (*Dispatcher) RegisterTagListener

func (d *Dispatcher) RegisterTagListener(listeners ...TagListener)

RegisterTagListener registers listeners for tag push events.

func (*Dispatcher) RegisterVulnerabilityListener added in v3.0.1

func (d *Dispatcher) RegisterVulnerabilityListener(listeners ...VulnerabilityListener)

RegisterVulnerabilityListener registers listeners for vulnerability events.

func (*Dispatcher) RegisterWikiPageListener

func (d *Dispatcher) RegisterWikiPageListener(listeners ...WikiPageListener)

RegisterWikiPageListener registers listeners for wiki page events.

func (*Dispatcher) Use added in v3.1.0

func (d *Dispatcher) Use(middlewares ...Middleware)

Use appends middleware to the dispatcher.

Middleware is applied in registration order: the first middleware wraps the second, and so on, with listener dispatch as the final handler. Call Use before the dispatcher starts handling events; concurrent middleware registration and dispatch is not supported.

type EmojiListener added in v3.0.1

type EmojiListener interface {
	OnEmoji(ctx context.Context, event *gitlab.EmojiEvent) error
}

EmojiListener handles GitLab emoji webhook events.

type FeatureFlagListener

type FeatureFlagListener interface {
	OnFeatureFlag(ctx context.Context, event *gitlab.FeatureFlagEvent) error
}

FeatureFlagListener handles GitLab feature flag webhook events.

type GroupResourceAccessTokenListener

type GroupResourceAccessTokenListener interface {
	OnGroupResourceAccessToken(ctx context.Context, event *gitlab.GroupResourceAccessTokenEvent) error
}

GroupResourceAccessTokenListener handles GitLab group resource access token webhook events.

type HandlerFunc added in v3.1.0

type HandlerFunc func(ctx context.Context, event any) error

HandlerFunc handles a parsed GitLab webhook event.

The event argument is one of the concrete event pointer types returned by gitlab.ParseWebhook, such as *gitlab.PushEvent or *gitlab.MergeEvent.

type IssueCommentListener

type IssueCommentListener interface {
	OnIssueComment(ctx context.Context, event *gitlab.IssueCommentEvent) error
}

IssueCommentListener handles GitLab issue comment webhook events.

type IssueListener

type IssueListener interface {
	OnIssue(ctx context.Context, event *gitlab.IssueEvent) error
}

IssueListener handles GitLab issue webhook events.

type JobListener

type JobListener interface {
	OnJob(ctx context.Context, event *gitlab.JobEvent) error
}

JobListener handles GitLab job webhook events.

type MemberListener

type MemberListener interface {
	OnMember(ctx context.Context, event *gitlab.MemberEvent) error
}

MemberListener handles GitLab member webhook events.

type MergeCommentListener

type MergeCommentListener interface {
	OnMergeComment(ctx context.Context, event *gitlab.MergeCommentEvent) error
}

MergeCommentListener handles GitLab merge request comment webhook events.

type MergeListener

type MergeListener interface {
	OnMerge(ctx context.Context, event *gitlab.MergeEvent) error
}

MergeListener handles GitLab merge request webhook events.

type Middleware added in v3.1.0

type Middleware func(next HandlerFunc) HandlerFunc

Middleware wraps a HandlerFunc to run code before or after event dispatch.

A middleware can stop dispatch by returning an error without calling next.

func MiddlewareForEvent added in v3.1.0

func MiddlewareForEvent[E any](fn func(context.Context, E) error) Middleware

MiddlewareForEvent returns middleware that runs fn only for events assignable to E.

If fn returns an error, dispatch stops and that error is returned. Events of other types skip fn and continue to the next handler.

type MilestoneListener added in v3.0.1

type MilestoneListener interface {
	OnMilestone(ctx context.Context, event *gitlab.MilestoneWebhookEvent) error
}

MilestoneListener handles GitLab milestone webhook events.

type Option

type Option func(*Dispatcher)

Option configures a Dispatcher during construction.

func RegisterListeners

func RegisterListeners(listeners ...any) Option

RegisterListeners registers listeners during dispatcher construction.

Listener and middleware registration is intended to happen before the dispatcher starts handling events. Do not call registration methods concurrently with Dispatcher.Dispatch, Dispatcher.DispatchWebhook, or Dispatcher.DispatchRequest.

func WithMiddlewares added in v3.1.0

func WithMiddlewares(middlewares ...Middleware) Option

WithMiddlewares registers middleware during dispatcher construction.

Middleware runs once per parsed webhook event, before the event is dispatched to registered listeners. Register middleware before the dispatcher starts handling events; concurrent middleware registration and dispatch is not supported.

type PipelineListener

type PipelineListener interface {
	OnPipeline(ctx context.Context, event *gitlab.PipelineEvent) error
}

PipelineListener handles GitLab pipeline webhook events.

type ProjectListener added in v3.0.1

type ProjectListener interface {
	OnProject(ctx context.Context, event *gitlab.ProjectWebhookEvent) error
}

ProjectListener handles GitLab project webhook events.

type ProjectResourceAccessTokenListener

type ProjectResourceAccessTokenListener interface {
	OnProjectResourceAccessToken(ctx context.Context, event *gitlab.ProjectResourceAccessTokenEvent) error
}

ProjectResourceAccessTokenListener handles GitLab project resource access token webhook events.

type PushListener

type PushListener interface {
	OnPush(ctx context.Context, event *gitlab.PushEvent) error
}

PushListener handles GitLab push webhook events.

type ReleaseListener

type ReleaseListener interface {
	OnRelease(ctx context.Context, event *gitlab.ReleaseEvent) error
}

ReleaseListener handles GitLab release webhook events.

type SnippetCommentListener

type SnippetCommentListener interface {
	OnSnippetComment(ctx context.Context, event *gitlab.SnippetCommentEvent) error
}

SnippetCommentListener handles GitLab snippet comment webhook events.

type SubGroupListener

type SubGroupListener interface {
	OnSubGroup(ctx context.Context, event *gitlab.SubGroupEvent) error
}

SubGroupListener handles GitLab subgroup webhook events.

type TagListener

type TagListener interface {
	OnTag(ctx context.Context, event *gitlab.TagEvent) error
}

TagListener handles GitLab tag push webhook events.

type VulnerabilityListener added in v3.0.1

type VulnerabilityListener interface {
	OnVulnerability(ctx context.Context, event *gitlab.VulnerabilityEvent) error
}

VulnerabilityListener handles GitLab vulnerability webhook events.

type WikiPageListener

type WikiPageListener interface {
	OnWikiPage(ctx context.Context, event *gitlab.WikiPageEvent) error
}

WikiPageListener handles GitLab wiki page webhook events.

Jump to

Keyboard shortcuts

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