From 6dffb91626a775e03530d2c69915e69a4fcbbae8 Mon Sep 17 00:00:00 2001 From: Sienna Meridian Satterwhite Date: Wed, 1 Apr 2026 14:35:57 +0100 Subject: [PATCH] feat(wfe-server-protos): add gRPC service definitions for workflow server 13 RPCs in wfe.v1.Wfe service: RegisterWorkflow, StartWorkflow, GetWorkflow, CancelWorkflow, SuspendWorkflow, ResumeWorkflow, SearchWorkflows, PublishEvent, WatchLifecycle (stream), StreamLogs (stream), SearchLogs, ListDefinitions. --- wfe-server-protos/Cargo.toml | 19 ++ wfe-server-protos/build.rs | 17 ++ wfe-server-protos/proto/wfe/v1/wfe.proto | 263 +++++++++++++++++++++++ wfe-server-protos/src/lib.rs | 17 ++ 4 files changed, 316 insertions(+) create mode 100644 wfe-server-protos/Cargo.toml create mode 100644 wfe-server-protos/build.rs create mode 100644 wfe-server-protos/proto/wfe/v1/wfe.proto create mode 100644 wfe-server-protos/src/lib.rs diff --git a/wfe-server-protos/Cargo.toml b/wfe-server-protos/Cargo.toml new file mode 100644 index 0000000..ae55020 --- /dev/null +++ b/wfe-server-protos/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "wfe-server-protos" +version.workspace = true +edition.workspace = true +license.workspace = true +repository.workspace = true +homepage.workspace = true +description = "gRPC service definitions for the WFE workflow server" + +[dependencies] +tonic = "0.14" +tonic-prost = "0.14" +prost = "0.14" +prost-types = "0.14" + +[build-dependencies] +tonic-build = "0.14" +tonic-prost-build = "0.14" +prost-build = "0.14" diff --git a/wfe-server-protos/build.rs b/wfe-server-protos/build.rs new file mode 100644 index 0000000..613474e --- /dev/null +++ b/wfe-server-protos/build.rs @@ -0,0 +1,17 @@ +fn main() -> Result<(), Box> { + let proto_files = vec!["proto/wfe/v1/wfe.proto"]; + + let mut prost_config = prost_build::Config::new(); + prost_config.include_file("mod.rs"); + + tonic_prost_build::configure() + .build_server(true) + .build_client(true) + .compile_with_config( + prost_config, + &proto_files, + &["proto"], + )?; + + Ok(()) +} diff --git a/wfe-server-protos/proto/wfe/v1/wfe.proto b/wfe-server-protos/proto/wfe/v1/wfe.proto new file mode 100644 index 0000000..cc2f71b --- /dev/null +++ b/wfe-server-protos/proto/wfe/v1/wfe.proto @@ -0,0 +1,263 @@ +syntax = "proto3"; +package wfe.v1; + +import "google/protobuf/timestamp.proto"; +import "google/protobuf/struct.proto"; + +service Wfe { + // === Definitions === + rpc RegisterWorkflow(RegisterWorkflowRequest) returns (RegisterWorkflowResponse); + rpc ListDefinitions(ListDefinitionsRequest) returns (ListDefinitionsResponse); + + // === Instances === + rpc StartWorkflow(StartWorkflowRequest) returns (StartWorkflowResponse); + rpc GetWorkflow(GetWorkflowRequest) returns (GetWorkflowResponse); + rpc CancelWorkflow(CancelWorkflowRequest) returns (CancelWorkflowResponse); + rpc SuspendWorkflow(SuspendWorkflowRequest) returns (SuspendWorkflowResponse); + rpc ResumeWorkflow(ResumeWorkflowRequest) returns (ResumeWorkflowResponse); + rpc SearchWorkflows(SearchWorkflowsRequest) returns (SearchWorkflowsResponse); + + // === Events === + rpc PublishEvent(PublishEventRequest) returns (PublishEventResponse); + + // === Streaming === + rpc WatchLifecycle(WatchLifecycleRequest) returns (stream LifecycleEvent); + rpc StreamLogs(StreamLogsRequest) returns (stream LogEntry); + + // === Search === + rpc SearchLogs(SearchLogsRequest) returns (SearchLogsResponse); +} + +// ─── Definitions ───────────────────────────────────────────────────── + +message RegisterWorkflowRequest { + // Raw YAML content. The server compiles it via wfe-yaml. + string yaml = 1; + // Optional config map for ((variable)) interpolation. + map config = 2; +} + +message RegisterWorkflowResponse { + repeated RegisteredDefinition definitions = 1; +} + +message RegisteredDefinition { + string definition_id = 1; + uint32 version = 2; + uint32 step_count = 3; +} + +message ListDefinitionsRequest {} + +message ListDefinitionsResponse { + repeated DefinitionSummary definitions = 1; +} + +message DefinitionSummary { + string id = 1; + uint32 version = 2; + string description = 3; + uint32 step_count = 4; +} + +// ─── Instances ─────────────────────────────────────────────────────── + +message StartWorkflowRequest { + string definition_id = 1; + uint32 version = 2; + google.protobuf.Struct data = 3; +} + +message StartWorkflowResponse { + string workflow_id = 1; +} + +message GetWorkflowRequest { + string workflow_id = 1; +} + +message GetWorkflowResponse { + WorkflowInstance instance = 1; +} + +message CancelWorkflowRequest { + string workflow_id = 1; +} + +message CancelWorkflowResponse {} + +message SuspendWorkflowRequest { + string workflow_id = 1; +} + +message SuspendWorkflowResponse {} + +message ResumeWorkflowRequest { + string workflow_id = 1; +} + +message ResumeWorkflowResponse {} + +message SearchWorkflowsRequest { + string query = 1; + WorkflowStatus status_filter = 2; + uint64 skip = 3; + uint64 take = 4; +} + +message SearchWorkflowsResponse { + repeated WorkflowSearchResult results = 1; + uint64 total = 2; +} + +// ─── Events ────────────────────────────────────────────────────────── + +message PublishEventRequest { + string event_name = 1; + string event_key = 2; + google.protobuf.Struct data = 3; +} + +message PublishEventResponse { + string event_id = 1; +} + +// ─── Lifecycle streaming ───────────────────────────────────────────── + +message WatchLifecycleRequest { + // Empty = all workflows. Set to filter to one. + string workflow_id = 1; +} + +message LifecycleEvent { + google.protobuf.Timestamp event_time = 1; + string workflow_id = 2; + string definition_id = 3; + uint32 version = 4; + LifecycleEventType event_type = 5; + // Populated for step events. + uint32 step_id = 6; + string step_name = 7; + // Populated for error events. + string error_message = 8; +} + +// ─── Log streaming ────────────────────────────────────────────────── + +message StreamLogsRequest { + string workflow_id = 1; + // Filter to a specific step. Empty = all steps. + string step_name = 2; + // If true, keep streaming as new logs arrive (tail -f). + bool follow = 3; +} + +message LogEntry { + string workflow_id = 1; + string step_name = 2; + uint32 step_id = 3; + LogStream stream = 4; + bytes data = 5; + google.protobuf.Timestamp timestamp = 6; +} + +// ─── Log search ───────────────────────────────────────────────────── + +message SearchLogsRequest { + // Full-text search query. + string query = 1; + // Optional filters. + string workflow_id = 2; + string step_name = 3; + LogStream stream_filter = 4; + uint64 skip = 5; + uint64 take = 6; +} + +message SearchLogsResponse { + repeated LogSearchResult results = 1; + uint64 total = 2; +} + +message LogSearchResult { + string workflow_id = 1; + string definition_id = 2; + string step_name = 3; + string line = 4; + LogStream stream = 5; + google.protobuf.Timestamp timestamp = 6; +} + +// ─── Shared types ─────────────────────────────────────────────────── + +message WorkflowInstance { + string id = 1; + string definition_id = 2; + uint32 version = 3; + string description = 4; + string reference = 5; + WorkflowStatus status = 6; + google.protobuf.Struct data = 7; + google.protobuf.Timestamp create_time = 8; + google.protobuf.Timestamp complete_time = 9; + repeated ExecutionPointer execution_pointers = 10; +} + +message ExecutionPointer { + string id = 1; + uint32 step_id = 2; + string step_name = 3; + PointerStatus status = 4; + google.protobuf.Timestamp start_time = 5; + google.protobuf.Timestamp end_time = 6; + uint32 retry_count = 7; + bool active = 8; +} + +message WorkflowSearchResult { + string id = 1; + string definition_id = 2; + uint32 version = 3; + WorkflowStatus status = 4; + string reference = 5; + string description = 6; + google.protobuf.Timestamp create_time = 7; +} + +enum WorkflowStatus { + WORKFLOW_STATUS_UNSPECIFIED = 0; + WORKFLOW_STATUS_RUNNABLE = 1; + WORKFLOW_STATUS_SUSPENDED = 2; + WORKFLOW_STATUS_COMPLETE = 3; + WORKFLOW_STATUS_TERMINATED = 4; +} + +enum PointerStatus { + POINTER_STATUS_UNSPECIFIED = 0; + POINTER_STATUS_PENDING = 1; + POINTER_STATUS_RUNNING = 2; + POINTER_STATUS_COMPLETE = 3; + POINTER_STATUS_SLEEPING = 4; + POINTER_STATUS_WAITING_FOR_EVENT = 5; + POINTER_STATUS_FAILED = 6; + POINTER_STATUS_SKIPPED = 7; + POINTER_STATUS_CANCELLED = 8; +} + +enum LifecycleEventType { + LIFECYCLE_EVENT_TYPE_UNSPECIFIED = 0; + LIFECYCLE_EVENT_TYPE_STARTED = 1; + LIFECYCLE_EVENT_TYPE_COMPLETED = 2; + LIFECYCLE_EVENT_TYPE_TERMINATED = 3; + LIFECYCLE_EVENT_TYPE_SUSPENDED = 4; + LIFECYCLE_EVENT_TYPE_RESUMED = 5; + LIFECYCLE_EVENT_TYPE_ERROR = 6; + LIFECYCLE_EVENT_TYPE_STEP_STARTED = 7; + LIFECYCLE_EVENT_TYPE_STEP_COMPLETED = 8; +} + +enum LogStream { + LOG_STREAM_UNSPECIFIED = 0; + LOG_STREAM_STDOUT = 1; + LOG_STREAM_STDERR = 2; +} diff --git a/wfe-server-protos/src/lib.rs b/wfe-server-protos/src/lib.rs new file mode 100644 index 0000000..390a0d6 --- /dev/null +++ b/wfe-server-protos/src/lib.rs @@ -0,0 +1,17 @@ +//! Generated gRPC stubs for the WFE workflow server API. +//! +//! Built from `proto/wfe/v1/wfe.proto`. Includes both server and client code. +//! +//! ```rust,ignore +//! use wfe_server_protos::wfe::v1::wfe_server::WfeServer; +//! use wfe_server_protos::wfe::v1::wfe_client::WfeClient; +//! ``` + +#![allow(clippy::all)] +#![allow(warnings)] + +include!(concat!(env!("OUT_DIR"), "/mod.rs")); + +pub use prost; +pub use prost_types; +pub use tonic;