feat: Oracle Canvas Component Schema and Qwen 3.6 integration (#31)
Co-authored-by: Sagnik <sagnik7896@gmail.com> Reviewed-on: #31
This commit was merged in pull request #31.
This commit is contained in:
@@ -0,0 +1,122 @@
|
||||
#!/usr/bin/env python3
|
||||
import hashlib
|
||||
import hmac
|
||||
import json
|
||||
import os
|
||||
import subprocess
|
||||
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
|
||||
|
||||
HOST = os.getenv("WEBHOOK_BIND_HOST", "127.0.0.1")
|
||||
PORT = int(os.getenv("WEBHOOK_BIND_PORT", "8788"))
|
||||
PATH = os.getenv("WEBHOOK_PATH", "/hooks/gitea/project-velocity")
|
||||
SECRET = os.getenv("GITEA_WEBHOOK_SECRET", "")
|
||||
EXPECTED_REF = os.getenv("GITEA_EXPECTED_REF", "refs/heads/main")
|
||||
EXPECTED_REPO = os.getenv("GITEA_REPO_FULL_NAME", "sagnik/Project_Velocity")
|
||||
LOCK_FILE = os.getenv("DEPLOY_LOCK_FILE", "/tmp/desineuron-velocity-deploy.lock")
|
||||
DEPLOY_CMD = os.getenv("DEPLOY_COMMAND", "/usr/local/bin/deploy_velocity_site.sh")
|
||||
|
||||
|
||||
def verify_signature(secret: str, body: bytes, signature: str) -> bool:
|
||||
if not secret:
|
||||
return False
|
||||
digest = hmac.new(secret.encode("utf-8"), body, hashlib.sha256).hexdigest()
|
||||
return hmac.compare_digest(digest, signature or "")
|
||||
|
||||
|
||||
class Handler(BaseHTTPRequestHandler):
|
||||
server_version = "VelocityWebhook/1.0"
|
||||
|
||||
def _respond(self, code: int, payload: dict) -> None:
|
||||
body = json.dumps(payload).encode("utf-8")
|
||||
self.send_response(code)
|
||||
self.send_header("Content-Type", "application/json")
|
||||
self.send_header("Content-Length", str(len(body)))
|
||||
self.end_headers()
|
||||
self.wfile.write(body)
|
||||
|
||||
def log_message(self, fmt: str, *args) -> None:
|
||||
print("%s - - [%s] %s" % (self.address_string(), self.log_date_time_string(), fmt % args))
|
||||
|
||||
def do_GET(self) -> None:
|
||||
if self.path == "/health":
|
||||
self._respond(200, {"ok": True, "service": "desineuron-velocity-gitea-webhook"})
|
||||
return
|
||||
self._respond(404, {"error": "not_found"})
|
||||
|
||||
def do_POST(self) -> None:
|
||||
if self.path != PATH:
|
||||
self._respond(404, {"error": "not_found"})
|
||||
return
|
||||
|
||||
length = int(self.headers.get("Content-Length", "0"))
|
||||
body = self.rfile.read(length)
|
||||
signature = self.headers.get("X-Gitea-Signature", "")
|
||||
event = self.headers.get("X-Gitea-Event", "")
|
||||
|
||||
if not verify_signature(SECRET, body, signature):
|
||||
self._respond(401, {"error": "invalid_signature"})
|
||||
return
|
||||
|
||||
try:
|
||||
payload = json.loads(body.decode("utf-8"))
|
||||
except json.JSONDecodeError:
|
||||
self._respond(400, {"error": "invalid_json"})
|
||||
return
|
||||
|
||||
if event == "ping":
|
||||
self._respond(200, {"ok": True, "message": "ping_received"})
|
||||
return
|
||||
|
||||
if event != "push":
|
||||
self._respond(202, {"ok": True, "ignored": True, "reason": f"unsupported_event:{event}"})
|
||||
return
|
||||
|
||||
ref = payload.get("ref")
|
||||
repo_full_name = ((payload.get("repository") or {}).get("full_name")) or ""
|
||||
|
||||
if ref != EXPECTED_REF:
|
||||
self._respond(202, {"ok": True, "ignored": True, "reason": f"unexpected_ref:{ref}"})
|
||||
return
|
||||
|
||||
if EXPECTED_REPO and repo_full_name != EXPECTED_REPO:
|
||||
self._respond(202, {"ok": True, "ignored": True, "reason": f"unexpected_repo:{repo_full_name}"})
|
||||
return
|
||||
|
||||
cmd = ["/usr/bin/flock", "-n", LOCK_FILE, "/bin/bash", "-lc", DEPLOY_CMD]
|
||||
proc = subprocess.run(cmd, capture_output=True, text=True)
|
||||
|
||||
if proc.returncode == 0:
|
||||
self._respond(
|
||||
202,
|
||||
{
|
||||
"ok": True,
|
||||
"deployed": True,
|
||||
"ref": ref,
|
||||
"repository": repo_full_name,
|
||||
"stdout_tail": proc.stdout.strip().splitlines()[-10:],
|
||||
},
|
||||
)
|
||||
return
|
||||
|
||||
self._respond(
|
||||
500,
|
||||
{
|
||||
"ok": False,
|
||||
"deployed": False,
|
||||
"ref": ref,
|
||||
"repository": repo_full_name,
|
||||
"returncode": proc.returncode,
|
||||
"stdout_tail": proc.stdout.strip().splitlines()[-10:],
|
||||
"stderr_tail": proc.stderr.strip().splitlines()[-10:],
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
server = ThreadingHTTPServer((HOST, PORT), Handler)
|
||||
print(f"Velocity Gitea webhook listening on http://{HOST}:{PORT}{PATH}")
|
||||
server.serve_forever()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user