Example: Handling a GitLab Webhook
This example shows how to handle a webhook from GitLab. Unlike GitHub's signature-based approach, GitLab's webhooks typically use a static secret token for verification.
The Script: gitlab.sh
This script is designed to:
- Validate the Secret Token: It checks if the
X-Gitlab-Token
header sent by GitLab matches a pre-configured secret token. - Parse the Payload: It uses
jq
to parse the JSON payload and react to a specific event. In this case, it creates a notification for apush
event.
#!/bin/sh
# Functions
die() { echo "error: $1" 1>&2 ; exit 1; }
confDie() { echo "error: $1 Check the server configuration!" 1>&2 ; exit 2; }
debug() {
[ "$debug" = "true" ] && echo "debug: $1"
}
# Validate global configuration
[ -z "$GITLAB_TOKEN" ] && confDie "GITLAB_TOKEN not set."
# Validate Gitlab hook token
[ "$x_gitlab_token" != "$GITLAB_TOKEN" ] && die "bad hook token"
# Validate parameters
payload=$1
payload="$(echo "$payload"|tr -d '\n')"
[ -z "$payload" ] && die "missing request payload"
payload_type=$(echo $payload | jq type -r)
[ $? != 0 ] && die "bad body format: expecting JSON"
[ ! $payload_type = "object" ] && die "bad body format: expecting JSON object but having $payload_type"
debug "received payload: $payload"
# Extract values
object_kind=$(echo $payload | jq .object_kind -r)
[ $? != 0 -o "$object_kind" = "null" ] && die "unable to extract 'object_kind' from JSON payload"
# Do something with the payload:
# Here create a simple notification when a push has occurred
if [ "$object_kind" = "push" ]
then
username=$(echo $payload | jq .user_name -r)
git_ssh_url=$(echo $payload | jq .project.git_ssh_url -r)
total_commits_count=$(echo $payload | jq .total_commits_count -r)
echo "notify: $username push $total_commits_count commit(s) on $git_ssh_url"
fi
Setup Instructions
-
Place the Script: Save the script above as
scripts/gitlab.sh
and make it executable (chmod +x scripts/gitlab.sh
). -
Set the Secret Token: The script needs a secret token for validation. This should be passed to
webhookd
as an environment variable.File:
.env
GITLAB_WEBHOOK_TOKEN=a_very_long_and_random_secret_string
-
Configure Docker Compose: Use the
distrib
image to ensurejq
is available.File:
docker-compose.yml
version: "3.6" services: webhookd: image: ncarlier/webhookd:latest-distrib container_name: webhookd restart: always ports: - "8080:8080" env_file: - .env environment: # Pass the token from the .env file to the container environment - GITLAB_TOKEN=${GITLAB_WEBHOOK_TOKEN} - WHD_NOTIFICATION_URI=... # Your notification channel URI volumes: - ./scripts:/scripts
-
Configure GitLab Webhook:
- In your GitLab project, go to Settings > Webhooks.
- URL: Set this to your public
webhookd
URL, e.g.,http://your-server.com:8080/gitlab
. - Secret token: Enter the same secret string you defined in your
.env
file. - Trigger: Select the events you want to listen for, for example, Push events.
- Click Add webhook.
Now, when you push to your GitLab repository, a webhook will be sent to webhookd
, triggering the script and sending a notification with the push details.