feat(wfe-core): root_workflow_id, SharedVolume, configurable shell, StepExecutionContext.definition

This commit is contained in:
2026-04-09 15:44:59 +01:00
parent 7214d0ab5d
commit 2aaf3c16c9
14 changed files with 137 additions and 3 deletions

View File

@@ -47,6 +47,13 @@ pub fn compile(spec: &WorkflowSpec) -> Result<CompiledWorkflow, YamlWorkflowErro
let mut definition = WorkflowDefinition::new(&spec.id, spec.version);
definition.name = spec.name.clone();
definition.description = spec.description.clone();
definition.shared_volume =
spec.shared_volume
.as_ref()
.map(|v| wfe_core::models::SharedVolume {
mount_path: v.mount_path.clone(),
size: v.size.clone(),
});
if let Some(ref eb) = spec.error_behavior {
definition.default_error_behavior = map_error_behavior(eb)?;
@@ -883,6 +890,7 @@ fn build_kubernetes_config(
image,
command: config.command.clone(),
run: config.run.clone(),
shell: config.shell.clone(),
env: config.env.clone(),
working_dir: config.working_dir.clone(),
memory: config.memory.clone(),

View File

@@ -108,12 +108,37 @@ pub struct WorkflowSpec {
/// Infrastructure services required by this workflow (databases, caches, etc.).
#[serde(default)]
pub services: HashMap<String, YamlService>,
/// Optional persistent volume shared across every step in this workflow
/// run, including sub-workflows. Declared once on the top-level
/// orchestrator (e.g. `ci`); ignored on non-root workflows. The Kubernetes
/// executor provisions a single PVC per top-level run and mounts it on
/// every step container at `mount_path` so steps like `git clone` in one
/// sub-workflow are visible to `cargo fmt --check` in another.
#[serde(default)]
pub shared_volume: Option<YamlSharedVolume>,
/// Allow unknown top-level keys (e.g. `_templates`) for YAML anchors.
#[serde(flatten)]
#[schemars(skip)]
pub _extra: HashMap<String, serde_yaml::Value>,
}
/// Shared volume declaration, YAML form.
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct YamlSharedVolume {
/// Absolute path to mount the volume at inside every step container.
/// Defaults to `/workspace` when unset.
#[serde(default = "default_shared_volume_mount")]
pub mount_path: String,
/// Optional size (e.g. `"20Gi"`). When unset the backend falls back
/// to its configured default.
#[serde(default)]
pub size: Option<String>,
}
fn default_shared_volume_mount() -> String {
"/workspace".to_string()
}
/// A service definition in YAML format.
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
pub struct YamlService {

View File

@@ -1092,6 +1092,7 @@ workflows:
_def: &str,
_ver: u32,
_data: serde_json::Value,
_parent_root_workflow_id: Option<String>,
) -> Pin<Box<dyn Future<Output = wfe_core::Result<String>> + Send + '_>> {
*self.called.lock().unwrap() = true;
Box::pin(async { Ok("child-instance-id".to_string()) })
@@ -1105,6 +1106,7 @@ workflows:
let wf_step = WfStep::new(0, &factory_key);
let workflow = WorkflowInstance::new("parent", 1, serde_json::json!({}));
let ctx = StepExecutionContext {
definition: None,
item: None,
execution_pointer: &pointer,
persistence_data: None,

View File

@@ -35,6 +35,7 @@ fn make_context<'a>(
pointer: &'a ExecutionPointer,
) -> StepExecutionContext<'a> {
StepExecutionContext {
definition: None,
item: None,
execution_pointer: pointer,
persistence_data: None,