CI/CD
This commit is contained in:
@@ -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
|
||||
|
||||
27
scripts/deploy_from_git.sh
Normal file
27
scripts/deploy_from_git.sh
Normal 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
95
scripts/webhook_listener.py
Executable 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()
|
||||
Reference in New Issue
Block a user