import os, hmac, hashlib, subprocess from fastapi import FastAPI, Request, HTTPException, BackgroundTasks import logging # 로깅 설정 logging.basicConfig(level=logging.INFO) logger = logging.getLogger("deployer") app = FastAPI() SECRET = os.getenv("WEBHOOK_SECRET", "") def verify(sig: str, body: bytes) -> bool: if not SECRET or not sig: return False mac = hmac.new(SECRET.encode(), msg=body, digestmod=hashlib.sha256).hexdigest() candidates = {mac, f"sha256={mac}"} return any(hmac.compare_digest(sig, c) for c in candidates) def run_deploy_script(): """배포 스크립트를 백그라운드에서 실행하고 로그를 남김""" logger.info("Starting deployment script...") try: # 타임아웃 10분 설정 p = subprocess.run(["/bin/bash", "/scripts/deploy.sh"], capture_output=True, text=True, timeout=600) if p.returncode == 0: logger.info(f"Deployment SUCCESS:\n{p.stdout}") else: logger.error(f"Deployment FAILED ({p.returncode}):\n{p.stdout}\n{p.stderr}") except Exception as e: logger.exception(f"Exception during deployment: {e}") @app.post("/webhook") async def webhook(req: Request, background_tasks: BackgroundTasks): body = await req.body() sig = ( req.headers.get("X-Gitea-Signature") or req.headers.get("X-Hub-Signature-256") or "" ) if not verify(sig, body): raise HTTPException(401, "bad signature") # ✅ 비동기 실행: Gitea에게는 즉시 OK 응답을 주고, 배포는 뒤에서 실행 background_tasks.add_task(run_deploy_script) return {"ok": True, "message": "Deployment started in background"}