fix(wfe-core): sub-workflow inherits parent workflow data
SubWorkflowStep was hard-coding `inputs: serde_json::Value::Null` from the YAML compiler, so every `type: workflow` step kicked off a child instance with an empty data object. Scripts in child workflows then saw empty `$REPO_URL`, `$COMMIT_SHA`, etc. and failed immediately. Now: when no explicit inputs are set, the child inherits the parent workflow's data (when it's an object). Scripts in child workflows can reference the same top-level inputs the parent was started with without every `type: workflow` step needing to re-declare them.
This commit is contained in:
@@ -1,8 +1,8 @@
|
|||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use chrono::Utc;
|
use chrono::Utc;
|
||||||
|
|
||||||
use crate::models::schema::WorkflowSchema;
|
|
||||||
use crate::models::ExecutionResult;
|
use crate::models::ExecutionResult;
|
||||||
|
use crate::models::schema::WorkflowSchema;
|
||||||
use crate::traits::step::{StepBody, StepExecutionContext};
|
use crate::traits::step::{StepBody, StepExecutionContext};
|
||||||
|
|
||||||
/// A step that starts a child workflow and waits for its completion.
|
/// A step that starts a child workflow and waits for its completion.
|
||||||
@@ -110,12 +110,18 @@ impl StepBody for SubWorkflowStep {
|
|||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
// Use inputs if set, otherwise pass an empty object so the child
|
// Use explicit inputs if set; otherwise inherit the parent workflow's
|
||||||
// workflow has a valid JSON object for storing step outputs.
|
// data so child steps can reference the same top-level fields (e.g.
|
||||||
let child_data = if self.inputs.is_null() {
|
// REPO_URL, COMMIT_SHA) without every `type: workflow` step having to
|
||||||
serde_json::json!({})
|
// re-declare them. Fall back to an empty object when the parent has
|
||||||
} else {
|
// no data either so the child still has a valid JSON object for
|
||||||
|
// storing step outputs.
|
||||||
|
let child_data = if !self.inputs.is_null() {
|
||||||
self.inputs.clone()
|
self.inputs.clone()
|
||||||
|
} else if context.workflow.data.is_object() {
|
||||||
|
context.workflow.data.clone()
|
||||||
|
} else {
|
||||||
|
serde_json::json!({})
|
||||||
};
|
};
|
||||||
let child_instance_id = host
|
let child_instance_id = host
|
||||||
.start_workflow(&self.workflow_id, self.version, child_data)
|
.start_workflow(&self.workflow_id, self.version, child_data)
|
||||||
@@ -132,8 +138,8 @@ impl StepBody for SubWorkflowStep {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::models::schema::SchemaType;
|
|
||||||
use crate::models::ExecutionPointer;
|
use crate::models::ExecutionPointer;
|
||||||
|
use crate::models::schema::SchemaType;
|
||||||
use crate::primitives::test_helpers::*;
|
use crate::primitives::test_helpers::*;
|
||||||
use crate::traits::step::HostContext;
|
use crate::traits::step::HostContext;
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
@@ -170,10 +176,7 @@ mod tests {
|
|||||||
let def_id = definition_id.to_string();
|
let def_id = definition_id.to_string();
|
||||||
let result_id = self.result_id.clone();
|
let result_id = self.result_id.clone();
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
self.started
|
self.started.lock().unwrap().push((def_id, version, data));
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.push((def_id, version, data));
|
|
||||||
Ok(result_id)
|
Ok(result_id)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -265,10 +268,7 @@ mod tests {
|
|||||||
|
|
||||||
let result = step.run(&ctx).await.unwrap();
|
let result = step.run(&ctx).await.unwrap();
|
||||||
assert!(result.proceed);
|
assert!(result.proceed);
|
||||||
assert_eq!(
|
assert_eq!(result.output_data, Some(json!({"result": "success"})));
|
||||||
result.output_data,
|
|
||||||
Some(json!({"result": "success"}))
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
@@ -292,10 +292,7 @@ mod tests {
|
|||||||
|
|
||||||
let result = step.run(&ctx).await.unwrap();
|
let result = step.run(&ctx).await.unwrap();
|
||||||
assert!(result.proceed);
|
assert!(result.proceed);
|
||||||
assert_eq!(
|
assert_eq!(result.output_data, Some(json!({"a": 1, "b": 2})));
|
||||||
result.output_data,
|
|
||||||
Some(json!({"a": 1, "b": 2}))
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
|
|||||||
Reference in New Issue
Block a user