diff --git a/docs/self-hosted/gitlab.md b/docs/self-hosted/gitlab.md index 94175bda..2488cfa0 100644 --- a/docs/self-hosted/gitlab.md +++ b/docs/self-hosted/gitlab.md @@ -44,6 +44,33 @@ Consult official CodeRabbitAI documentation for a detailed [guide](https://docs. - Issues events - Merge request events +We have a convenient [script](/code/gitlab-webhook.sh) to help you add webhooks to all projects in a GitLab instance. You can run it with the following command: + +```bash +# Make sure the script is executable: +chmod +x gitlab-webhook.sh + +# PAT example (header auto-detected) +export GITLAB_TOKEN="glpat-xxxxx" +./gitlab-add-webhook.sh \ + -h "gitlab.example.com" -u "http:///gitlab_webhooks" \ + -s "mySecret" -p 42 + +# PAT example (explicit header) +./gitlab-add-webhook.sh \ + -h "gitlab.example.com" -u "http:///gitlab_webhooks" \ + -s "mySecret" -g "mygroup/mysubgroup/myproject" \ + -t "glpat-xxxxx" \ + -A "PRIVATE-TOKEN" + +# OAuth token with explicit header +./gitlab-add-webhook.sh \ + -h "gitlab.example.com" -u "http:///gitlab_webhooks" \ + -s "mySecret" -g "company/backend" \ + -t "eyJhbGciOi..." \ + -A "Authorization: Bearer" +``` + ## Prepare a `.env` file Create a `.env` file with the following content: diff --git a/static/code/gitlab-webhook.sh b/static/code/gitlab-webhook.sh new file mode 100644 index 00000000..b217079e --- /dev/null +++ b/static/code/gitlab-webhook.sh @@ -0,0 +1,188 @@ +#!/usr/bin/env bash + +## gitlab-webhook.sh +# Add a webhook to one project, or every project in a subgroup tree. + +## Example usage: +# Make sure the script is executable: +# chmod +x gitlab-webhook.sh + +# PAT example (header auto-detected) +# export GITLAB_TOKEN="glpat-xxxxx" +# ./gitlab-add-webhook.sh \ +# -h "gitlab.example.com" -u "https://ci.example.com/gitlab-hook" \ +# -s "mySecret" -p 42 + +# PAT example (explicit header) +# ./gitlab-add-webhook.sh \ +# -h "gitlab.example.com" -u "https://ci.example.com/gitlab-hook" \ +# -s "mySecret" -g "mygroup/mysubgroup/myproject" \ +# -t "glpat-qj5s..." \ +# -A "PRIVATE-TOKEN" + +# OAuth token with explicit header +# ./gitlab-add-webhook.sh \ +# -h "gitlab.example.com" -u "https://ci.example.com/gitlab-hook" \ +# -s "mySecret" -g "company/backend" \ +# -t "eyJhbGciOi..." \ +# -A "Authorization: Bearer" + + +set -euo pipefail + +usage() { + cat < -u -s \\ + [-t ] [-A ] [-p | -g ] + +Required: + -h GitLab host (e.g. gitlab.example.com) + -u Webhook endpoint URL to receive POSTs + -s Webhook secret token (used for signature verification) + +Authentication (one of): + -t Access token (PAT, project, group or OAuth). If omitted, \$GITLAB_TOKEN is used + -A Auth header to use. Default detects: + PAT → "PRIVATE-TOKEN" + anything else → "Authorization: Bearer" + +Scope (choose one): + -p Project ID or full path (e.g. 42 or group/app) + -g Group ID or full path, recurse through all subgroups & projects +EOF + exit 1 +} + +HOST="" HOOK_URL="" HOOK_SECRET="" +TOKEN="${GITLAB_TOKEN:-}" AUTH_HEADER="" +PROJECT="" GROUP="" + +while getopts "h:u:s:t:A:p:g:" opt; do + case "$opt" in + h) HOST=$OPTARG ;; + u) HOOK_URL=$OPTARG ;; + s) HOOK_SECRET=$OPTARG ;; + t) TOKEN=$OPTARG ;; + A) AUTH_HEADER=$OPTARG ;; + p) PROJECT=$OPTARG ;; + g) GROUP=$OPTARG ;; + *) usage ;; + esac +done + +# Mandatory checks +[[ -z $HOST || -z $HOOK_URL || -z $HOOK_SECRET ]] && usage +[[ -n $PROJECT && -n $GROUP ]] && usage +[[ -z $PROJECT && -z $GROUP ]] && usage + +# Token handling +if [[ -z $TOKEN ]]; then + echo "❌ No access token provided. Use -t or set \$GITLAB_TOKEN" >&2 + exit 1 +fi + +# Choose header if not forced +if [[ -z $AUTH_HEADER ]]; then + if [[ $TOKEN == glpat-* || $TOKEN == "PAT-"* ]]; then + AUTH_HEADER="PRIVATE-TOKEN" + else + AUTH_HEADER="Authorization: Bearer" + fi +fi + +API="https://${HOST}/api/v4" +CURL_BASE=(curl -sSf --header "${AUTH_HEADER}: ${TOKEN}") + +# Track processed projects to avoid duplicates +declare -A PROCESSED_PROJECTS +# Track projects where webhooks were successfully added +WEBHOOK_PROJECTS=() + +############################################################################## +# Helpers +############################################################################## +url_encode() { + local string="$1" + # URL encode the string using printf and sed + printf '%s' "$string" | sed 's/\//%2F/g; s/ /%20/g; s/@/%40/g; s/:/%3A/g; s/#/%23/g; s/?/%3F/g; s/&/%26/g; s/=/%3D/g; s/+/%2B/g' +} + +create_hook() { + local pid=$1 + + # Skip if already processed + if [[ -n "${PROCESSED_PROJECTS[$pid]:-}" ]]; then + return 0 + fi + + # Mark as processed + PROCESSED_PROJECTS[$pid]=1 + + local encoded_pid + # URL encode if pid is not purely numeric + if [[ $pid =~ ^[0-9]+$ ]]; then + encoded_pid=$pid + else + encoded_pid=$(url_encode "$pid") + fi + + "${CURL_BASE[@]}" --request POST \ + --data-urlencode "url=${HOOK_URL}" \ + --data "token=${HOOK_SECRET}" \ + --data "push_events=true" \ + --data "note_events=true" \ + --data "issues_events=true" \ + --data "merge_requests_events=true" \ + --data "enable_ssl_verification=true" \ + "${API}/projects/${encoded_pid}/hooks" \ + >/dev/null + + # Track successful webhook creation + WEBHOOK_PROJECTS+=("$pid") +} + +traverse_group() { + local gid=$1 + local encoded_gid + # URL encode if gid is not purely numeric + if [[ $gid =~ ^[0-9]+$ ]]; then + encoded_gid=$gid + else + encoded_gid=$(url_encode "$gid") + fi + # projects (includes nested sub-groups) + while IFS= read -r pid; do + [[ -n "$pid" ]] && create_hook "$pid" + done < <( + "${CURL_BASE[@]}" \ + "${API}/groups/${encoded_gid}/projects?include_subgroups=true&per_page=100" | + jq -r '.[].id' + ) + # recurse explicit subgroups (older GitLab) + while IFS= read -r sg; do + [[ -n "$sg" ]] && traverse_group "$sg" + done < <( + "${CURL_BASE[@]}" "${API}/groups/${encoded_gid}/subgroups?per_page=100" | + jq -r '.[].id' + ) +} + +############################################################################## +# Main +############################################################################## +if [[ -n $PROJECT ]]; then + create_hook "$PROJECT" +else + traverse_group "$GROUP" +fi + +# Print final summary +if [[ ${#WEBHOOK_PROJECTS[@]} -eq 0 ]]; then + echo "❌ No webhooks were installed." +else + echo "✅ Webhooks installed successfully on ${#WEBHOOK_PROJECTS[@]} project(s):" + for pid in "${WEBHOOK_PROJECTS[@]}"; do + echo " - Project ID: $pid" + done +fi pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy