CI events flow simplified

This commit is contained in:
Piotr Dec 2025-11-01 23:02:28 +01:00
parent 29dfc13a48
commit 34ee5f8754
Signed by: stawros
GPG key ID: 74B18A3F0F1E99C0
7 changed files with 59 additions and 174 deletions

View file

@ -1,51 +0,0 @@
import logging
import uuid
from typing import Annotated, List
from injectable import injectable, autowired, Autowired
from typing_extensions import deprecated
from app.core.queue import EnqueuedProcessor, ProcessQueue, Task, Result
from app.model.healthcheck import HealthCheck
from app.model.webhook import WebhookEvent
from app.services import DockerService, GitService, Passwords
logger = logging.getLogger(__name__)
@deprecated("Use event bus instead.")
@injectable(singleton=True)
class WebhookProcessor:
@autowired
def __init__(self, docker: Annotated[DockerService, Autowired],
git: Annotated[GitService, Autowired],
keepass: Annotated[Passwords, Autowired]):
self._docker = docker
self._git = git
self._keepass = keepass
def enqueue(self, event: WebhookEvent):
pass
def _process(self, task: Task[WebhookEvent]) -> Result:
event: WebhookEvent = task.payload
# TODO: persist event data
commit_hash = self._git.get_new_commit_hash()
if commit_hash != event.commit:
logger.warning(f"Commit hash mismatch: {commit_hash} != {event.commit}")
return Result(task.id, False, "Commit hash mismatch")
# TODO: persist commit data
service = self._get_service(event.files)
return Result(task.id, True)
def _get_service(self, files: List[str]) -> str:
pass
@property
def health(self) -> HealthCheck:
return HealthCheck(
self._docker is not None and self._git is not None and self._keepass is not None,
f"Docker: {self._docker is not None}, Git: {self._git is not None}, KeePass: {self._keepass is not None}"
)

View file

@ -1,15 +1,10 @@
from injectable import inject
from app.core.core import WebhookProcessor
from app.events import SimpleEventBus
from app.core.woodpecker import Woodpecker
class AutowireSupport:
@staticmethod
def webhook_processor():
return inject(WebhookProcessor)
@staticmethod
def event_bus():
return inject(SimpleEventBus)
def woodpecker():
return inject(Woodpecker)

View file

@ -1,52 +0,0 @@
import time
import uuid
from abc import ABC, abstractmethod
from dataclasses import dataclass
from multiprocessing import Queue, Process
from typing import TypeVar
from injectable import injectable
T = TypeVar('T')
@dataclass
class Task[T]:
id: uuid.UUID
processor: 'EnqueuedProcessor'
payload: T
@dataclass
class Result:
_id: uuid.UUID
success: bool
error: str | None = None
@injectable(singleton=True)
class ProcessQueue:
def __init__(self):
self._q = Queue()
self._process_thread = Process(target=self._run, args=(self._q,))
self._process_thread.start()
def put(self, task: Task):
self._q.put(task)
def _run(self, queue: Queue):
while True:
if queue.empty():
time.sleep(10)
continue
task = queue.get()
task.processor._process(task.payload)
class EnqueuedProcessor(ABC):
def __init__(self, queue: ProcessQueue):
self._queue = queue
def _enqueue(self, task: Task):
self._queue.put(task)
@abstractmethod
def _process(self, task: Task) -> Result:
pass

View file

@ -1,25 +1,64 @@
import logging
from collections import deque
from multiprocessing import Process, Lock
from typing import Annotated
from injectable import injectable, Autowired, autowired, inject, injectable_factory
from injectable import injectable, Autowired, autowired
from app.events import SimpleEventBus
from app.model.webhook import WebhookEvent
from app.model.webhook import WoodpeckerEvent
from app.services import Passwords, GitService, DockerService
logger = logging.getLogger(__name__)
class WoodpeckerRunner(Process):
def __init__(self, event: WoodpeckerEvent):
super().__init__()
self._event = event
def run(self):
super().run()
"""
event: WebhookEvent = task.payload
# TODO: persist event data
commit_hash = self._git.get_new_commit_hash()
if commit_hash != event.commit:
logger.warning(f"Commit hash mismatch: {commit_hash} != {event.commit}")
return Result(task.id, False, "Commit hash mismatch")
# TODO: persist commit data
service = self._get_service(event.files)
"""
@injectable(singleton=True)
class Woodpecker:
@autowired
def __init__(self, event_bus: Annotated[SimpleEventBus, Autowired]):
def __init__(self, passwords: Annotated[Passwords, Autowired]):
self._passwords = passwords
self._git = GitService()
self._docker = DockerService()
self._runner: WoodpeckerRunner | None = None
self._pending = deque()
self._lock = Lock()
logger.info("Woodpecker initialized.")
event_bus.subscribe(WebhookEvent, self.on_ci_event)
def on_ci_event(self, event):
def on_ci_event(self, event: WoodpeckerEvent):
logger.info(f"Received event: {event}")
with self._lock:
if len(self._pending) > 0 or self._runner is not None:
self._pending.append(event)
return
self._start_runner(event)
def _start_runner(self, event: WoodpeckerEvent):
pass
instance = Woodpecker(inject(SimpleEventBus))
injectable_factory(Woodpecker)(lambda: instance)
def _on_runner_completed(self):
logger.info("Runner completed.")
self._runner.join()
with self._lock:
self._runner = None
if len(self._pending) > 0:
event = self._pending.popleft()
self._start_runner(event)