From 312631f0b57fe7bacc9fc2dbcea91a832180fe16 Mon Sep 17 00:00:00 2001 From: Piotr Dec Date: Sun, 2 Nov 2025 00:35:33 +0100 Subject: [PATCH] WoodpeckerRunner & some VCS changes --- app/core/woodpecker.py | 66 +++++++++++++++++++++++++++++++++--------- app/services/vcs.py | 23 ++------------- 2 files changed, 54 insertions(+), 35 deletions(-) diff --git a/app/core/woodpecker.py b/app/core/woodpecker.py index 9ba242d..ae8553b 100644 --- a/app/core/woodpecker.py +++ b/app/core/woodpecker.py @@ -12,23 +12,50 @@ logger = logging.getLogger(__name__) class WoodpeckerRunner(Process): - def __init__(self, event: WoodpeckerEvent): - super().__init__() + def __init__(self, git: GitService, docker: DockerService, success_callback=None, error_callback=None): + super().__init__(daemon=True) + self._git = git + self._docker = docker + self._success_callback = success_callback + self._error_callback = error_callback + self._event: WoodpeckerEvent | None = None + + def process_event(self, event: WoodpeckerEvent): self._event = event + self.start() 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) + try: + service = self.get_service(self._event.files) + if service is None: + logger.info("No service found.") + return self._success_callback() - """ + self._git.checkout(self._event.commit) + """ + TODO: + check for *.mo.* files + subs mo from pass + docker compose up -d -f service/docker-compose.yml + """ + + return self._success_callback() + except Exception as e: + return self._error_callback(e) + + def get_service(self, files: list[str]) -> str | None: + supported_files = [] + for f in files: + f_parts = f.split("/") + if f_parts[0] in ["compose", "files"]: + supported_files.append(f[1]) + match len(set(supported_files)): + case 0: + return None + case 1: + return supported_files[0] + case _: + raise Exception("Multiple services are not supported.") @injectable(singleton=True) @@ -52,7 +79,9 @@ class Woodpecker: self._start_runner(event) def _start_runner(self, event: WoodpeckerEvent): - pass + with self._lock: + self._runner = WoodpeckerRunner(self._git, self._docker, self._on_runner_completed) + self._runner.process_event(event) def _on_runner_completed(self): logger.info("Runner completed.") @@ -62,3 +91,12 @@ class Woodpecker: if len(self._pending) > 0: event = self._pending.popleft() self._start_runner(event) + + def _on_runner_error(self, t: Exception): + logger.error(f"Runner error: {t}", exc_info=True) + self._runner.join() + with self._lock: + self._runner = None + if len(self._pending) > 0: + event = self._pending.popleft() + self._start_runner(event) diff --git a/app/services/vcs.py b/app/services/vcs.py index abb5468..00ef3c2 100644 --- a/app/services/vcs.py +++ b/app/services/vcs.py @@ -13,14 +13,6 @@ class GitService: self._repo.git.checkout(self._settings.git.branch) self._origin: Remote = self._repo.remotes.origin - def get_modified_compose(self) -> str | None: - self._update() - return self._diff() - - def get_new_commit_hash(self) -> str: - self._update() - return self._repo.head.commit.hexsha - @staticmethod def _check_preconditions(config: GitConfig) -> Repo: def clone(): @@ -34,16 +26,5 @@ class GitService: return clone() return Repo(config.path) - def _update(self): - self._origin.pull() - - def _diff(self) -> str | None: - diff = self._repo.head.commit.diff("HEAD~1") - composes = [f for f in diff if f.a_path.endswith("docker-compose.yml")] - match len(composes): - case 0: - return None - case 1: - return composes[0].a_path - case _: - raise Exception("Multiple compose files modified") + def checkout(self, sha: str): + pass