Support Gitea webhooks in deploy listener
Some checks failed
Deploy Staging / Build backend (Nitro) (push) Has been cancelled
Deploy Staging / Deploy zu Hetzner (push) Has been cancelled
ci/woodpecker/push/woodpecker Pipeline was canceled

This commit is contained in:
chahinebrini 2026-06-18 08:46:20 +02:00
parent 2475c082de
commit 97206b7865

View File

@ -1,8 +1,8 @@
#!/usr/bin/env node
/**
* Rebreak GitHub Webhook Listener
* Rebreak GitHub + Gitea Webhook Listener
*
* Empfängt GitHub push-Events, validiert HMAC-SHA256-Signatur,
* Empfängt GitHub- und Gitea-push-Events, validiert HMAC-SHA256-Signatur,
* und triggert das deploy.sh Script im Hintergrund.
*
* Port: 9000 (intern, wird von nginx reverse-proxied)
@ -40,7 +40,7 @@ if (!WEBHOOK_SECRET) {
process.exit(1);
}
function verifySignature(secret, signature, payload) {
function verifyGitHubSignature(secret, signature, payload) {
const hmac = crypto.createHmac("sha256", secret);
hmac.update(payload, "utf-8");
const digest = `sha256=${hmac.digest("hex")}`;
@ -54,6 +54,20 @@ function verifySignature(secret, signature, payload) {
}
}
function verifyGiteaSignature(secret, signature, payload) {
const hmac = crypto.createHmac("sha256", secret);
hmac.update(payload, "utf-8");
const digest = hmac.digest("hex");
try {
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(digest),
);
} catch {
return false;
}
}
// Deploy-Queue: verhindert parallele Builds (OOM-Schutz auf 4 GB RAM)
let deployRunning = false;
let pendingDeploy = false;
@ -107,19 +121,33 @@ const server = http.createServer((req, res) => {
let body = "";
req.on("data", (chunk) => (body += chunk));
req.on("end", () => {
const sig = req.headers["x-hub-signature-256"];
if (!sig) {
const githubSig = req.headers["x-hub-signature-256"];
const giteaSig = req.headers["x-gitea-signature"];
const event = req.headers["x-github-event"] || req.headers["x-gitea-event"];
if (!githubSig && !giteaSig) {
res.writeHead(401);
res.end(JSON.stringify({ error: "Missing signature" }));
return;
}
if (!verifySignature(WEBHOOK_SECRET, sig, body)) {
const valid = githubSig
? verifyGitHubSignature(WEBHOOK_SECRET, githubSig, body)
: verifyGiteaSignature(WEBHOOK_SECRET, giteaSig, body);
if (!valid) {
res.writeHead(401);
res.end(JSON.stringify({ error: "Invalid signature" }));
return;
}
if (event && event !== "push") {
console.log(`[Webhook] Ignoring non-push event: ${event}`);
res.writeHead(200);
res.end(JSON.stringify({ ok: false, reason: "Not a push event", event }));
return;
}
let payload;
try {
payload = JSON.parse(body);