Skip to content

Commit 6afd975

Browse files
authored
chore(release): v0.6.17 — detached run_workflow dispatch fix (#283)
* fix(workflow): carry subject in reattach execute request so detached run_workflow dispatches The detached 'workflow run' / run_workflow path bootstraps a Running record then re-attaches a workflow_runner via 'workflow run --sync --workflow-id <id>'. workflow_execute_request_for_existing() built that request with all subject fields None (workflow_id only), so the runner plugin could not resolve subject context and workflow/execute failed (exit 1) — every detached dispatch sat Running then got zombie-cancelled. Only this reattach path was affected: the queue/trigger path carries the subject via build_runner_command, and the --sync --task-id path passes task_id directly (both work). Populate task_id/requirement_id from the persisted record's subject, mirroring the proven fresh-dispatch request. Adds a regression test. * chore(release): v0.6.17 Includes: detached run_workflow / 'animus workflow run' now dispatches — the reattach execute request carries the subject so the runner plugin can resolve subject context (was workflow_id-only → workflow/execute failed).
1 parent 3bbff02 commit 6afd975

3 files changed

Lines changed: 41 additions & 6 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/orchestrator-cli/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "orchestrator-cli"
3-
version = "0.6.16"
3+
version = "0.6.17"
44
edition = "2021"
55
license = "Elastic-2.0"
66
default-run = "animus"

crates/orchestrator-cli/src/services/operations/ops_workflow/phases.rs

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,17 +69,23 @@ pub(crate) fn ensure_workflow_runner_plugin(project_root: &Path) -> Result<()> {
6969
}
7070

7171
/// Build the `workflow/execute` request that re-attaches the workflow_runner
72-
/// plugin to an already-persisted workflow record. Subject fields stay empty:
73-
/// the persisted record is authoritative for subject, input, and vars.
72+
/// plugin to an already-persisted workflow record. The persisted record is
73+
/// authoritative for input and vars, but the subject MUST be carried in the
74+
/// request: the runner plugin resolves subject context from
75+
/// `subject_ref`/`task_id`/`requirement_id`, not from `workflow_id` alone, so
76+
/// an empty subject made `workflow/execute` fail to resolve subject context
77+
/// for every detached `workflow run` / `run_workflow` dispatch (the
78+
/// queue/trigger path carries the subject via `build_runner_command`, which is
79+
/// why only this reattach path was affected).
7480
pub(crate) fn workflow_execute_request_for_existing(
7581
workflow: &OrchestratorWorkflow,
7682
) -> workflow_proto::WorkflowExecuteRequest {
7783
workflow_proto::WorkflowExecuteRequest {
7884
workflow_id: Some(workflow.id.clone()),
7985
subject_dispatch: None,
8086
subject_ref: None,
81-
task_id: None,
82-
requirement_id: None,
87+
task_id: workflow.subject.task_id().map(str::to_string),
88+
requirement_id: workflow.subject.requirement_id().map(str::to_string),
8389
title: None,
8490
description: None,
8591
workflow_ref: workflow.workflow_ref.clone(),
@@ -1150,6 +1156,35 @@ workflows:
11501156
);
11511157
}
11521158

1159+
#[tokio::test]
1160+
async fn reattach_request_carries_task_subject_for_plugin_resolution() {
1161+
let _lock = test_env_lock().lock().unwrap_or_else(|p| p.into_inner());
1162+
let temp = TempDir::new().expect("temp dir");
1163+
let _guards = isolate_plugin_discovery(&temp);
1164+
init_git_repo(&temp);
1165+
write_standard_workflow_yaml(&temp);
1166+
let project_root = temp.path().to_string_lossy().to_string();
1167+
let _config_source_seam =
1168+
orchestrator_config::workflow_config::config_source_client::install_yaml_config_source_base(temp.path());
1169+
let hub = Arc::new(FileServiceHub::new(&project_root).expect("file service hub"));
1170+
let task = create_test_task(&hub, "reattach subject").await;
1171+
let existing = hub
1172+
.workflows()
1173+
.run(WorkflowRunInput::for_task(task.id.clone(), None))
1174+
.await
1175+
.expect("workflow should start");
1176+
1177+
let request = super::workflow_execute_request_for_existing(&existing);
1178+
1179+
assert_eq!(request.workflow_id.as_deref(), Some(existing.id.as_str()));
1180+
assert_eq!(
1181+
request.task_id.as_deref(),
1182+
Some(task.id.as_str()),
1183+
"reattach request must carry the task subject so the runner plugin resolves subject context"
1184+
);
1185+
assert_eq!(request.requirement_id, None);
1186+
}
1187+
11531188
#[tokio::test]
11541189
async fn resume_workflow_with_runner_rejects_terminal_and_runner_owned_workflows() {
11551190
let _lock = test_env_lock().lock().unwrap_or_else(|p| p.into_inner());

0 commit comments

Comments
 (0)