2
0
Files
gitcaddy-server/modules/plugins/pluginv1/plugin.proto
logikonline de7d6a719e
All checks were successful
Build and Release / Create Release (push) Successful in 0s
Build and Release / Unit Tests (push) Successful in 6m51s
Build and Release / Integration Tests (PostgreSQL) (push) Successful in 7m6s
Build and Release / Lint (push) Successful in 7m42s
Build and Release / Build Binaries (amd64, linux, linux-latest) (push) Successful in 3m9s
Build and Release / Build Binaries (amd64, darwin, macos) (push) Successful in 6m31s
Build and Release / Build Binaries (arm64, darwin, macos) (push) Successful in 5m54s
Build and Release / Build Binary (linux/arm64) (push) Successful in 9m40s
Build and Release / Build Binaries (amd64, windows, windows-latest) (push) Successful in 9h5m9s
feat(plugins): implement protocol version negotiation in server
Complete protocol versioning implementation on the server side, enabling forward-compatible plugin protocol evolution.

Server Changes:
- Send ProtocolVersion = 1 in InitializeRequest
- Store plugin's reported protocol version in ManagedPlugin
- Treat version 0 (pre-versioning plugins) as version 1
- Add SupportsProtocol() method to check before calling version-gated RPCs
- Log plugin's protocol version during initialization

Generated Code:
- Regenerate plugin.pb.go with protocol_version fields
- Add getter methods for new fields

Documentation:
- Add Protocol Versioning section to PLUGINS.md
- Explain version negotiation flow
- Document when plugins need to update vs. when they don't
- Add version history table (currently only v1)
- Update all example code to return protocol_version = 1

Benefits:
- Server can safely add new RPCs in future versions without breaking old plugins
- Plugins can detect newer servers and opt into advanced features
- Zero-value (0) provides backwards compatibility with pre-versioning plugins
- Clear upgrade path documented for plugin developers

This completes the protocol versioning feature started in the previous commit.
2026-02-13 02:18:20 -05:00

107 lines
3.1 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;
// protocol_version is the plugin protocol version the server supports.
// The current version is 1. Plugins should check this to know what RPCs
// the server may call. A value of 0 means the server predates versioning.
int32 protocol_version = 3;
}
message InitializeResponse {
bool success = 1;
string error = 2;
PluginManifest manifest = 3;
// protocol_version is the plugin protocol version the plugin supports.
// The current version is 1. The server uses this to avoid calling RPCs
// that the plugin doesn't implement. A value of 0 means the plugin
// predates versioning and is treated as protocol version 1.
int32 protocol_version = 4;
}
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;
}