This is a simple webhook dispatcher for Gitlab. It listens for incoming webhooks and dispatches them to the appropriate handler.
- π 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
go get github.com/flc1125/go-gitlab-webhook/v3| 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 |
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)
}
}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.
MIT License. See LICENSE for the full license text.
- gitlab-org/api/client-go(Formerly known as: xanzy/go-gitlab): Go library for accessing the GitLab API
- stretchr/testify: A toolkit with common assertions and mocks that plays nicely with the standard library