mirror of
https://github.com/allaunthefox/SilverSight.git
synced 2026-07-31 01:25:21 +00:00
- Port NUVMAP projection engine from Research Stack to SilverSight with Q16_16 fixed-point (zero Float) and CBOR serialization - Add Rotational Wave — Braid Correspondence formalization at boundary (ChiralLabel, RossbyDrift, rossby_convergence_bound stubbed, kelvin_wave_eigensolid proven) - Add auto-pipeline CI workflow, webhook receiver, Forgejo MCP server - Add SOPS/Age encryption config - Add stack compose for portable deployment - Add rotational wave design doc
52 lines
1.9 KiB
Python
52 lines
1.9 KiB
Python
#!/usr/bin/env python3
|
|
"""Webhook receiver — listens for Forgejo push events and runs the auto-pipeline."""
|
|
import json, os, subprocess, hmac, hashlib, logging
|
|
from http.server import HTTPServer, BaseHTTPRequestHandler
|
|
from pathlib import Path
|
|
|
|
ROOT = Path(__file__).resolve().parent.parent.parent
|
|
PIPELINE = ROOT / "scripts/auto/auto_pipeline.py"
|
|
SECRET = os.environ.get("WEBHOOK_SECRET", "")
|
|
PORT = int(os.environ.get("WEBHOOK_PORT", "8080"))
|
|
|
|
logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s")
|
|
|
|
class WebhookHandler(BaseHTTPRequestHandler):
|
|
def do_POST(self):
|
|
length = int(self.headers.get("Content-Length", 0))
|
|
body = self.rfile.read(length)
|
|
sig = self.headers.get("X-Forgejo-Signature", "")
|
|
|
|
# Validate signature
|
|
if SECRET:
|
|
expected = hmac.new(SECRET.encode(), body, hashlib.sha256).hexdigest()
|
|
if not hmac.compare_digest(f"sha256={expected}", sig):
|
|
self.send_error(401, "Invalid signature")
|
|
return
|
|
|
|
event = json.loads(body)
|
|
ref = event.get("ref", "")
|
|
repo = event.get("repository", {}).get("full_name", "unknown")
|
|
logging.info(f"Push to {repo} {ref}")
|
|
|
|
# Run the auto-pipeline
|
|
try:
|
|
r = subprocess.run(
|
|
["python3", str(PIPELINE), "--ci"],
|
|
capture_output=True, text=True, timeout=600
|
|
)
|
|
logging.info(f"Pipeline exit={r.returncode}: {r.stdout[-200:]}")
|
|
except subprocess.TimeoutExpired:
|
|
logging.warning("Pipeline timed out")
|
|
|
|
self.send_response(200)
|
|
self.end_headers()
|
|
self.wfile.write(b'{"status":"ok"}')
|
|
|
|
def log_message(self, fmt, *args):
|
|
logging.info(fmt % args)
|
|
|
|
if __name__ == "__main__":
|
|
server = HTTPServer(("0.0.0.0", PORT), WebhookHandler)
|
|
logging.info(f"Webhook receiver on :{PORT}")
|
|
server.serve_forever()
|