feat: install plugins from approved source commits
CI / php-store (push) Waiting to run
CI / python-components (push) Waiting to run

This commit is contained in:
2026-08-24 21:37:17 +02:00
parent f36d6be511
commit 26aea40e6a
27 changed files with 414 additions and 47 deletions
@@ -77,6 +77,8 @@ class Release:
approved: bool
immutable: bool
approved_payload_sha256: str
artifact_kind: str = "wheel"
artifact_filename: str = ""
@classmethod
def from_mapping(cls, value: dict[str, Any]) -> "Release":
@@ -104,6 +106,8 @@ class Release:
approved=value.get("approved") is True or value.get("status") == "approved",
immutable=value.get("immutable") is True,
approved_payload_sha256=approved_payload_sha256,
artifact_kind=str(value.get("artifact_kind") or "wheel").strip(),
artifact_filename=str(value.get("artifact_filename") or "").strip(),
)
def supports(self, netbox_version: str, plugin: "CatalogPlugin") -> bool:
@@ -235,6 +235,8 @@ class LifecycleService:
raise LifecycleError("Approved release has no artifact URL.")
if not release.sha256:
raise LifecycleError("Approved release has no artifact SHA-256. Commit hashes are not accepted.")
if release.artifact_kind not in {"wheel", "source_archive"}:
raise LifecycleError("Approved release has an unsupported artifact type.")
@staticmethod
def _assert_state(action: str, installed: str, enabled: bool, runtime_active: bool) -> None:
@@ -287,6 +289,8 @@ class LifecycleService:
return suffix if re.fullmatch(r"\.[A-Za-z0-9.]{1,16}", suffix) else ".artifact"
def _download(self, release: Release, directory: Path) -> Path:
if release.artifact_kind == "source_archive":
raise LifecycleError("Source archives require execution_mode='agent' for a verified local wheel build.")
artifact = directory / f"artifact{self._artifact_suffix(release)}"
self.client.download_artifact(
release.download_url,