Skip to content

Repository files navigation

Gitlab Webhook Dispatcher πŸš€

Supported Go Versions Package Version GoDoc codecov 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

About

πŸš€ A lightweight Gitlab webhook dispatcher for efficient event handling

Topics

Resources

Contributing

Stars

6 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages