This commit is contained in:
Stanislav Hubacek
2026-04-07 20:16:22 +02:00
parent a133a8d41c
commit a75d9b4d34
3 changed files with 129 additions and 1 deletions

View File

@@ -21,7 +21,13 @@ fi
cp "$WRAPPER" "$TARGET_CADDYFILE"
echo "[4/5] Validating Caddy config..."
caddy validate --config "$TARGET_CADDYFILE"
if ! caddy validate --config "$TARGET_CADDYFILE"; then
echo "[ERROR] Validation failed, restoring backup..."
if [[ -f "$BACKUP_CADDYFILE" ]]; then
cp "$BACKUP_CADDYFILE" "$TARGET_CADDYFILE"
fi
exit 1
fi
echo "[5/5] Reloading Caddy..."
systemctl reload caddy

View File

@@ -0,0 +1,27 @@
#!/usr/bin/env bash
set -euo pipefail
REPO_DIR="/opt/homelab"
BRANCH="main"
echo "[1/4] Switching to repo..."
cd "$REPO_DIR"
echo "[2/4] Fetching changes..."
git fetch origin "$BRANCH"
LOCAL="$(git rev-parse HEAD)"
REMOTE="$(git rev-parse origin/$BRANCH)"
if [[ "$LOCAL" == "$REMOTE" ]]; then
echo "[3/4] No changes to deploy."
exit 0
fi
echo "[3/4] Pulling latest changes..."
git pull --ff-only origin "$BRANCH"
echo "[4/4] Running Caddy deployment..."
"$REPO_DIR/scripts/deploy_caddy.sh"
echo "[Done] Git-based deployment completed."

95
scripts/webhook_listener.py Executable file
View File

@@ -0,0 +1,95 @@
#!/usr/bin/env python3
import hashlib
import hmac
import json
import os
import subprocess
from http.server import BaseHTTPRequestHandler, HTTPServer
HOST = "127.0.0.1"
PORT = 9001
SECRET = os.environ.get("GITEA_WEBHOOK_SECRET", "e250429f3c716721c5c37c61c5032e916e98756523bc99a9cb7949854d2810da")
DEPLOY_SCRIPT = "/opt/homelab/scripts/deploy_from_git.sh"
BRANCH = "refs/heads/main"
class Handler(BaseHTTPRequestHandler):
def do_POST(self):
if self.path != "/deploy":
self.send_response(404)
self.end_headers()
self.wfile.write(b"Not found")
return
content_length = int(self.headers.get("Content-Length", "0"))
body = self.rfile.read(content_length)
signature = self.headers.get("X-Gitea-Signature", "")
if not SECRET:
self.send_response(500)
self.end_headers()
self.wfile.write(b"Missing server secret")
return
expected = hmac.new(
SECRET.encode("utf-8"),
body,
hashlib.sha256
).hexdigest()
if not hmac.compare_digest(signature, expected):
self.send_response(403)
self.end_headers()
self.wfile.write(b"Invalid signature")
return
try:
payload = json.loads(body.decode("utf-8"))
except Exception:
self.send_response(400)
self.end_headers()
self.wfile.write(b"Invalid JSON")
return
ref = payload.get("ref", "")
if ref != BRANCH:
self.send_response(200)
self.end_headers()
self.wfile.write(f"Ignored ref: {ref}".encode("utf-8"))
return
try:
result = subprocess.run(
[DEPLOY_SCRIPT],
capture_output=True,
text=True,
check=True,
)
output = (result.stdout or "") + (result.stderr or "")
self.send_response(200)
self.end_headers()
self.wfile.write(output.encode("utf-8"))
except subprocess.CalledProcessError as exc:
output = (exc.stdout or "") + (exc.stderr or "")
self.send_response(500)
self.end_headers()
self.wfile.write(output.encode("utf-8"))
def do_GET(self):
if self.path == "/health":
self.send_response(200)
self.end_headers()
self.wfile.write(b"ok")
return
self.send_response(404)
self.end_headers()
self.wfile.write(b"Not found")
def log_message(self, fmt, *args):
return
if __name__ == "__main__":
server = HTTPServer((HOST, PORT), Handler)
server.serve_forever()