Ein Plugin erstellen
Das Plugin-System von SourceAnt ermöglicht es Ihnen, die Plattform mit benutzerdefinierten Integrationen, Authentifizierungsanbietern, LLM-Backends und mehr zu erweitern.
Übersicht
Plugins sind Python-Klassen, die von BasePlugin. erben. Jedes Plugin deklariert seinen Typ, Metadaten und Lifecycle-Hooks. Der Plugin-Manager übernimmt automatisch Discovery, Abhängigkeitsauflösung und Lifecycle-Verwaltung.
Plugin-Typen
Jedes Plugin muss einen der folgenden Typen über das PluginType Enum deklarieren:
- INTEGRATION. Integrationen externer Dienste (GitHub, GitLab usw.)
- AUTHENTICATION. Authentifizierungsanbieter (OAuth, SAML usw.)
- LLM. Sprachmodell-Backends
- WEBHOOK. Webhook-Handler
- NOTIFICATION. Benachrichtigungskanäle (Slack, E-Mail usw.)
- UTILITY. Hilfsprogramme
Schnellstart
Erstellen Sie ein neues Verzeichnis unter src/plugins/ mit einer plugin.py Datei:
src/plugins/
my_plugin/
plugin.py
__init__.py Hier ist ein minimales Plugin:
from src.core.plugins import BasePlugin, PluginMetadata, PluginType
class MyPlugin(BasePlugin):
@property
def metadata(self) -> PluginMetadata:
return PluginMetadata(
name="my_plugin",
version="1.0.0",
description="A custom plugin",
author="Your Name",
plugin_type=PluginType.UTILITY,
)
async def _initialize(self) -> None:
# One-time setup: register routes, connect to services
pass
async def _start(self) -> None:
# Called after all plugins are initialized
pass
async def _stop(self) -> None:
# Graceful shutdown
pass
async def _cleanup(self) -> None:
# Final cleanup before unload
pass Plugin-Metadaten
Der PluginMetadata dataclass definiert die Identität und Konfiguration Ihres Plugins:
| Feld | Typ | Beschreibung |
|---|---|---|
name | str | Eindeutiger Plugin-Bezeichner |
version | str | Semantische Version (z. B. "1.0.0") |
description | str | Kurze Beschreibung |
author | str | Plugin-Autor |
plugin_type | PluginType | Einer der Enum-Werte des Plugin-Typs |
dependencies | List[str] | Namen der Plugins, von denen dieses abhängt (Standard: []) |
config_schema | Dict | JSON Schema für die Konfigurationsvalidierung (Standard: None) |
enabled | bool | Ob das Plugin aktiv ist (Standard: True) |
priority | int | Ladepriorität, niedriger = früher (Standard: 100) |
Lifecycle-Hooks
Plugins folgen einem strikten Lifecycle, der von der PluginManager:
- Discovery. Der Manager durchsucht Plugin-Verzeichnisse nach
plugin.pyoder__init__.py - Loading. Plugin-Klassen werden importiert und instanziiert
- Registration. Metadaten werden validiert und das Plugin wird registriert
- Initialization.
_initialize()wird in Abhängigkeitsreihenfolge aufgerufen - Startup.
_start()wird aufgerufen, nachdem alle Plugins initialisiert wurden - Shutdown.
_stop()wird in umgekehrter Abhängigkeitsreihenfolge aufgerufen - Cleanup.
_cleanup()wird ausgeführt, bevor das Plugin entladen wird
Überschreiben _initialize, _start, _stop, und _cleanup in Ihrem Plugin. Die Methoden der Basisklasse (initialize, start, usw.) übernehmen die Zustandsverfolgung und rufen Ihre Implementierungen auf.
Ereignissystem
Plugins interagieren mit SourceAnt über Hook-Punkte und Ereignis-Abonnements.
Hook-Punkte
Registrieren Sie Callbacks für integrierte Lifecycle-Ereignisse:
from src.core.plugins import event_hooks, HookPriority
# In your _initialize method:
event_hooks.register_hook(
hook_name="before_review_generation",
callback=self._on_before_review,
plugin_name=self.metadata.name,
priority=HookPriority.NORMAL,
) Verfügbare Hook-Punkte:
- App-Lifecycle.
app_startup,app_shutdown - Webhooks.
before_webhook_processing,after_webhook_processing - Code-Reviews.
before_review_generation,after_review_generation,before_review_posting,after_review_posting - Authentifizierung.
before_user_authentication,after_user_authentication,before_user_logout,after_user_logout - Repositories.
before_repository_authorization,after_repository_authorization,before_webhook_setup,after_webhook_setup - Fehler.
on_error,on_plugin_error
Ereignis-Abonnements
Abonnieren Sie domänenspezifische Ereignisse für eine granularere Steuerung:
event_hooks.subscribe_to_events(
plugin_name=self.metadata.name,
callback=self._handle_event,
event_types=[
"pull_request.opened",
"pull_request.synchronize",
],
) Hook-Priorität
Steuern Sie die Ausführungsreihenfolge von Hooks mit HookPriority:
| Ebene | Wert | Anwendungsfall |
|---|---|---|
HIGHEST | 0 | Sicherheitsprüfungen, Validierung |
HIGH | 25 | Vorverarbeitung, Anreicherung |
NORMAL | 50 | Standardverarbeitung (Standard) |
LOW | 75 | Nachverarbeitung, Protokollierung |
LOWEST | 100 | Bereinigung, Analytik |
Plugin-Discovery
Der PluginManager entdeckt Plugins automatisch durch Scannen registrierter Verzeichnisse. Damit ein Plugin entdeckt wird, muss es:
- sich in einem Unterverzeichnis eines registrierten Plugin-Verzeichnisses befinden
- entweder eine
plugin.pyoder__init__.pyDatei - Exportieren Sie eine Klasse, die erbt von
BasePlugin
Verzeichnisse, die mit einem Unterstrich beginnen, werden übersprungen.
Abhängigkeiten
Deklarieren Sie Abhängigkeiten in Ihren Metadaten, um eine korrekte Ladereihenfolge sicherzustellen:
PluginMetadata(
name="my_plugin",
version="1.0.0",
description="Depends on GitHub OAuth",
author="Your Name",
plugin_type=PluginType.INTEGRATION,
dependencies=["github_oauth"],
) Die Plugin-Registry verwendet topologische Sortierung, um den Abhängigkeitsgraphen aufzulösen. Zirkuläre Abhängigkeiten werden erkannt und führen beim Laden zu einem Fehler. Die _initialize Methode eines Plugins wird erst aufgerufen, nachdem alle seine Abhängigkeiten initialisiert wurden.
Konfigurationsvalidierung
Definieren Sie ein JSON Schema in config_schema um die Plugin-Konfiguration beim Laden zu validieren:
PluginMetadata(
name="my_notifier",
version="1.0.0",
description="Slack notifications",
author="Your Name",
plugin_type=PluginType.NOTIFICATION,
config_schema={
"type": "object",
"properties": {
"webhook_url": {"type": "string"},
"channel": {"type": "string"},
},
"required": ["webhook_url"],
},
) Greifen Sie in Ihrem Plugin mit auf validierte Konfigurationswerte zu self.get_config("webhook_url").