69 lines
2.3 KiB
Python
69 lines
2.3 KiB
Python
"""
|
|
Forgejo integration — webhook handler for push events.
|
|
|
|
Kicks off a build when a push event arrives. The actual webhook endpoint
|
|
should live in main.py (or a dedicated webhooks router); this function
|
|
encapsulates the "convert push → BuildBody → start build" logic.
|
|
"""
|
|
|
|
from typing import Any, Dict, Optional
|
|
|
|
|
|
def on_push_event(project: str, repo: str, ref: str = "main",
|
|
runner=None) -> Dict[str, Any]:
|
|
"""Handle a Forgejo push webhook.
|
|
|
|
Args:
|
|
project: project name (e.g. "linux-tool")
|
|
repo: full clone URL
|
|
ref: git ref that was pushed (e.g. "main", "refs/tags/v1.0")
|
|
runner: BuildRunner instance (if None, returns the BuildBody
|
|
that would have been dispatched)
|
|
|
|
Returns:
|
|
dict with build_id + status, OR the BuildBody if no runner.
|
|
"""
|
|
# Build a project spec for the engine
|
|
body = {
|
|
"cmd": f"git fetch && git checkout {ref} && make -j$(nproc)",
|
|
"dir": f"/home/user/builds/{project}",
|
|
"project": project,
|
|
"arch": "x86_64",
|
|
"target": "linux-gnu",
|
|
"toolchain": "gcc",
|
|
}
|
|
|
|
if runner is None:
|
|
return {"status": "no_runner", "body": body}
|
|
|
|
# Dispatch through the runner (async, but we can't await from sync)
|
|
import asyncio
|
|
try:
|
|
loop = asyncio.get_running_loop()
|
|
except RuntimeError:
|
|
loop = None
|
|
|
|
if loop:
|
|
# We're inside an async context — schedule the build
|
|
task = loop.create_task(runner.start(_BuildBodyShim(**body)))
|
|
return {"status": "scheduled", "body": body}
|
|
else:
|
|
# Sync context — run in a new loop (blocks)
|
|
async def _start():
|
|
return await runner.start(_BuildBodyShim(**body))
|
|
build_id = asyncio.run(_start())
|
|
return {"status": "started", "build_id": build_id, "body": body}
|
|
|
|
|
|
class _BuildBodyShim:
|
|
"""Tiny shim so we can pass a body-like object to BuildRunner.start
|
|
without importing pydantic (which would create a circular import)."""
|
|
def __init__(self, cmd, dir, project=None, arch="x86_64",
|
|
target="linux-gnu", toolchain="gcc"):
|
|
self.cmd = cmd
|
|
self.dir = dir
|
|
self.project = project
|
|
self.arch = arch
|
|
self.target = target
|
|
self.toolchain = toolchain
|