Replace manual HTTP/JSON RPC implementation with generated gRPC/Connect client, providing type-safe plugin communication. Code Generation: - Generate plugin.pb.go and pluginv1connect/plugin.connect.go from plugin.proto - Add generate-plugin-proto Makefile target - Delete hand-written types.go (replaced by generated code) ExternalPluginManager Refactoring: - Replace httpClient with pluginv1connect.PluginServiceClient - Use h2c (cleartext HTTP/2) transport for gRPC without TLS - Replace all manual callRPC/callRPCWithContext calls with typed Connect methods - Remove JSON serialization/deserialization code - Simplify error handling with native gRPC status codes Benefits: - Type safety: compile-time verification of request/response types - Protocol compatibility: standard gRPC wire format - Reduced code: ~100 lines of manual RPC code removed - Better errors: structured gRPC status codes instead of string parsing - Matches existing Actions runner pattern (Connect RPC over HTTP/2) This completes the plugin framework migration to production-grade RPC transport.
98 lines
2.5 KiB
Protocol Buffer
98 lines
2.5 KiB
Protocol Buffer
syntax = "proto3";
|
|
|
|
package plugin.v1;
|
|
|
|
option go_package = "code.gitcaddy.com/server/v3/modules/plugins/pluginv1;pluginv1";
|
|
|
|
import "google/protobuf/struct.proto";
|
|
import "google/protobuf/timestamp.proto";
|
|
|
|
// PluginService is the RPC interface that external plugins must implement.
|
|
// The server calls these methods to manage the plugin's lifecycle and dispatch events.
|
|
service PluginService {
|
|
// Initialize is called when the server starts or the plugin is loaded
|
|
rpc Initialize(InitializeRequest) returns (InitializeResponse);
|
|
// Shutdown is called when the server is shutting down
|
|
rpc Shutdown(ShutdownRequest) returns (ShutdownResponse);
|
|
// HealthCheck checks if the plugin is healthy
|
|
rpc HealthCheck(HealthCheckRequest) returns (HealthCheckResponse);
|
|
// GetManifest returns the plugin's manifest describing its capabilities
|
|
rpc GetManifest(GetManifestRequest) returns (PluginManifest);
|
|
// OnEvent is called when an event the plugin is subscribed to occurs
|
|
rpc OnEvent(PluginEvent) returns (EventResponse);
|
|
// HandleHTTP proxies an HTTP request to the plugin
|
|
rpc HandleHTTP(HTTPRequest) returns (HTTPResponse);
|
|
}
|
|
|
|
message InitializeRequest {
|
|
string server_version = 1;
|
|
map<string, string> config = 2;
|
|
}
|
|
|
|
message InitializeResponse {
|
|
bool success = 1;
|
|
string error = 2;
|
|
PluginManifest manifest = 3;
|
|
}
|
|
|
|
message ShutdownRequest {
|
|
string reason = 1;
|
|
}
|
|
|
|
message ShutdownResponse {
|
|
bool success = 1;
|
|
}
|
|
|
|
message HealthCheckRequest {}
|
|
|
|
message HealthCheckResponse {
|
|
bool healthy = 1;
|
|
string status = 2;
|
|
map<string, string> details = 3;
|
|
}
|
|
|
|
message GetManifestRequest {}
|
|
|
|
message PluginManifest {
|
|
string name = 1;
|
|
string version = 2;
|
|
string description = 3;
|
|
repeated string subscribed_events = 4;
|
|
repeated PluginRoute routes = 5;
|
|
repeated string required_permissions = 6;
|
|
string license_tier = 7;
|
|
}
|
|
|
|
message PluginRoute {
|
|
string method = 1;
|
|
string path = 2;
|
|
string description = 3;
|
|
}
|
|
|
|
message PluginEvent {
|
|
string event_type = 1;
|
|
google.protobuf.Struct payload = 2;
|
|
google.protobuf.Timestamp timestamp = 3;
|
|
int64 repo_id = 4;
|
|
int64 org_id = 5;
|
|
}
|
|
|
|
message EventResponse {
|
|
bool handled = 1;
|
|
string error = 2;
|
|
}
|
|
|
|
message HTTPRequest {
|
|
string method = 1;
|
|
string path = 2;
|
|
map<string, string> headers = 3;
|
|
bytes body = 4;
|
|
map<string, string> query_params = 5;
|
|
}
|
|
|
|
message HTTPResponse {
|
|
int32 status_code = 1;
|
|
map<string, string> headers = 2;
|
|
bytes body = 3;
|
|
}
|