Webhooky
Sprievodca konfiguráciou GitLab webhookov pre real-time notifikácie.
Prehľad
sequenceDiagram
participant Dev as Developer
participant GL as GitLab
participant GP as GitPulse Webhook
participant Q as Queue
participant W as Worker
Dev->>GL: git push
GL->>GL: Process push
GL->>GP: POST /webhooks/gitlab
Note over GP: Verify signature
GP->>Q: Enqueue event
GP-->>GL: 200 OK (fast)
W->>Q: Dequeue
W->>W: Process & store
Konfigurácia v GitLab
Na úrovni projektu
- Prejdite do projektu v GitLab
- Settings -> Webhooks
- Vyplňte konfiguráciu:
| Pole | Hodnota |
| URL | https://gitpulse.kpi.fei.tuke.sk/api/v1/webhooks/gitlab |
| Secret token | Vygenerovaný secret (pozri nižšie) |
| Trigger | Push, MR, Issues, Pipelines |
| SSL verification | Yes Enabled |
Na úrovni skupiny
Pre hromadnú konfiguráciu všetkých projektov:
- Prejdite do skupiny
- Settings -> Webhooks
- Rovnaká konfigurácia ako vyššie
Group webhooks
Group webhooky automaticky platia pre všetky projekty v skupine.
Generovanie webhook secret
| Bash |
|---|
| # Vygenerovanie bezpečného secret
WEBHOOK_SECRET=$(openssl rand -hex 32)
echo "GITLAB_WEBHOOK_SECRET=${WEBHOOK_SECRET}"
# Pridajte do .env
echo "GITLAB_WEBHOOK_SECRET=${WEBHOOK_SECRET}" >> .env
|
Trigger events
Push Events
| JSON |
|---|
| {
"object_kind": "push",
"event_name": "push",
"before": "abc123...",
"after": "def456...",
"ref": "refs/heads/main",
"checkout_sha": "def456...",
"user_name": "John Doe",
"user_email": "john@example.com",
"project": {
"id": 123,
"name": "my-project",
"path_with_namespace": "group/my-project"
},
"commits": [
{
"id": "def456...",
"message": "feat: add feature X",
"timestamp": "2024-01-15T10:30:00Z",
"author": {
"name": "John Doe",
"email": "john@example.com"
},
"added": ["new_file.py"],
"modified": ["existing.py"],
"removed": []
}
],
"total_commits_count": 1
}
|
Spracované metriky: - Počet commitov - Autor (mapovanie na člena tímu) - Pridané/modifikované/odstránené súbory - Časové rozloženie
Merge Request Events
| JSON |
|---|
| {
"object_kind": "merge_request",
"event_type": "merge_request",
"user": {
"id": 1,
"username": "johndoe"
},
"object_attributes": {
"iid": 42,
"title": "Feature: User authentication",
"description": "Implements OAuth2 login",
"state": "merged",
"source_branch": "feature/auth",
"target_branch": "main",
"author_id": 1,
"assignee_id": 2,
"created_at": "2024-01-10T10:00:00Z",
"updated_at": "2024-01-15T14:30:00Z",
"action": "merge"
},
"changes": {
"state": {
"previous": "opened",
"current": "merged"
}
}
}
|
Spracované metriky: - MR creation/merge rate - Time to merge - Review participation - Branch activity
Issue Events
| JSON |
|---|
| {
"object_kind": "issue",
"event_type": "issue",
"user": {
"id": 1,
"username": "johndoe"
},
"object_attributes": {
"iid": 15,
"title": "Bug: Login fails on mobile",
"state": "closed",
"action": "close",
"labels": [
{"title": "bug"},
{"title": "priority:high"}
]
}
}
|
Pipeline Events
| JSON |
|---|
| {
"object_kind": "pipeline",
"object_attributes": {
"id": 789,
"status": "success",
"duration": 245,
"created_at": "2024-01-15T10:00:00Z",
"finished_at": "2024-01-15T10:04:05Z"
},
"builds": [
{
"id": 1001,
"stage": "build",
"name": "compile",
"status": "success",
"duration": 60
},
{
"id": 1002,
"stage": "test",
"name": "unit-tests",
"status": "success",
"duration": 120
}
]
}
|
Verifikácia webhook signature
GitPulse verifikuje každý webhook pomocou secret token:
| Python |
|---|
| # src/app/api/webhooks.py
import hmac
import hashlib
def verify_gitlab_signature(payload: bytes, signature: str, secret: str) -> bool:
"""Verify GitLab webhook signature."""
expected = hmac.new(
secret.encode(),
payload,
hashlib.sha256
).hexdigest()
return hmac.compare_digest(f"sha256={expected}", signature)
|
GitLab posiela signature v hlavičke:
Webhook handler
| Python |
|---|
| # src/app/api/webhooks.py
from fastapi import APIRouter, Request, HTTPException, Header
from app.config import settings
from app.workers.event_processor import process_gitlab_event
router = APIRouter()
@router.post("/webhooks/gitlab")
async def gitlab_webhook(
request: Request,
x_gitlab_token: str = Header(None),
x_gitlab_event: str = Header(None),
):
"""Handle GitLab webhook events."""
# 1. Verify token
if x_gitlab_token != settings.GITLAB_WEBHOOK_SECRET:
raise HTTPException(status_code=401, detail="Invalid token")
# 2. Parse payload
payload = await request.json()
# 3. Enqueue for async processing
job = process_gitlab_event.delay(
event_type=x_gitlab_event,
payload=payload
)
# 4. Return immediately
return {"status": "accepted", "job_id": str(job.id)}
|
Testovanie webhookov
Manuálny test
| Bash |
|---|
| # Simulácia push event
curl -X POST http://localhost:8000/api/v1/webhooks/gitlab \
-H "Content-Type: application/json" \
-H "X-Gitlab-Token: ${GITLAB_WEBHOOK_SECRET}" \
-H "X-Gitlab-Event: Push Hook" \
-d '{
"object_kind": "push",
"ref": "refs/heads/main",
"commits": [{
"id": "test123",
"message": "Test commit",
"author": {"name": "Test", "email": "test@example.com"}
}]
}'
|
GitLab test webhook
- V GitLab webhooks settings
- Kliknite Test pri uloženom webhook
- Vyberte event type
- Skontrolujte response a GitPulse logy
Ngrok pre lokálny vývoj
| Bash |
|---|
| # Spustenie ngrok tunela
ngrok http 8000
# Použite vygenerovanú URL v GitLab
# https://abc123.ngrok.io/api/v1/webhooks/gitlab
|
Troubleshooting
Webhook nedoručený
| Bash |
|---|
| # 1. Skontrolujte GitLab webhook logy
# Project -> Settings -> Webhooks -> Recent deliveries
# 2. Overte dostupnosť GitPulse
curl -I https://gitpulse.kpi.fei.tuke.sk/api/v1/health
# 3. Skontrolujte firewall
sudo ufw status
|
401 Unauthorized
| Bash |
|---|
| # Token nesedí
# 1. Overte GITLAB_WEBHOOK_SECRET v .env
# 2. Overte Secret token v GitLab webhook settings
# 3. Reštartujte GitPulse
docker compose restart api
|
500 Server Error
| Bash |
|---|
| # Pozrite GitPulse logy
docker compose logs api | grep webhook
# Bežné príčiny:
# - Malformed JSON payload
# - Database connection error
# - Redis unavailable
|
Duplicitné eventy
| Python |
|---|
| # GitPulse používa idempotency key
# Event s rovnakým ID je spracovaný len raz
# Ak vidíte duplicity, skontrolujte:
# 1. Či nie sú nakonfigurované webhooky na project aj group úrovni
# 2. Retry logic v GitLab
|
Monitoring webhookov
Prometheus metriky
| PromQL |
|---|
| # Webhook request rate
rate(gitlab_webhook_requests_total[5m])
# Error rate
sum(rate(gitlab_webhook_requests_total{status="error"}[5m])) /
sum(rate(gitlab_webhook_requests_total[5m]))
# Processing latency
histogram_quantile(0.99,
rate(gitlab_webhook_duration_seconds_bucket[5m])
)
|
Alerting
| YAML |
|---|
| # monitoring/prometheus/alerts/webhooks.yml
groups:
- name: webhooks
rules:
- alert: WebhookHighErrorRate
expr: |
sum(rate(gitlab_webhook_requests_total{status="error"}[5m])) /
sum(rate(gitlab_webhook_requests_total[5m])) > 0.1
for: 5m
labels:
severity: warning
annotations:
summary: "High webhook error rate"
|
Bezpečnosť
IP Whitelist
| Nginx Configuration File |
|---|
| # Caddy/Nginx - povoliť len GitLab IP
location /api/v1/webhooks/ {
allow 10.0.0.0/8; # GitLab server IP range
deny all;
proxy_pass http://api:8000;
}
|
Rate limiting
| Python |
|---|
| # src/app/api/webhooks.py
from slowapi import Limiter
from slowapi.util import get_remote_address
limiter = Limiter(key_func=get_remote_address)
@router.post("/webhooks/gitlab")
@limiter.limit("100/minute")
async def gitlab_webhook(...):
...
|
Ďalšie čítanie