#!/usr/bin/env python3 """GitHub Webhook Listener for Auto-Pull on Push.""" import hmac import hashlib import json import os import subprocess from http.server import BaseHTTPRequestHandler, HTTPServer PORT = int(os.environ.get("WEBHOOK_PORT", 9000)) SECRET = os.environ.get("WEBHOOK_SECRET", "").encode("utf-8") REPO_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) class WebhookHandler(BaseHTTPRequestHandler): def do_POST(self): if self.path != "/webhook": self.send_response(404) self.end_headers() return content_length = int(self.headers.get("Content-Length", 0)) body = self.rfile.read(content_length) if SECRET: signature = self.headers.get("X-Hub-Signature-256", "") expected = "sha256=" + hmac.new(SECRET, body, hashlib.sha256).hexdigest() if not hmac.compare_digest(signature, expected): self.send_response(403) self.end_headers() self.wfile.write(b"Invalid signature\n") return event = self.headers.get("X-GitHub-Event", "push") if event == "push": print("[Webhook] Received push event. Pulling latest code...") try: result = subprocess.run( ["git", "pull", "origin", "main"], cwd=REPO_DIR, capture_output=True, text=True, check=True, ) output = result.stdout print(f"[Webhook] Git pull success:\n{output}") self.send_response(200) self.end_headers() self.wfile.write(f"Updated successfully:\n{output}".encode("utf-8")) except subprocess.CalledProcessError as err: error_msg = f"Git pull failed:\n{err.stderr}" print(f"[Webhook] {error_msg}") self.send_response(500) self.end_headers() self.wfile.write(error_msg.encode("utf-8")) else: self.send_response(200) self.end_headers() self.wfile.write(f"Ignored event: {event}\n".encode("utf-8")) def main(): server = HTTPServer(("0.0.0.0", PORT), WebhookHandler) print(f"🚀 GitHub Webhook listener running on http://0.0.0.0:{PORT}/webhook") server.serve_forever() if __name__ == "__main__": main()