From 70a89f6f533fc7b5905f0bc5f43b2f35a1b2c656 Mon Sep 17 00:00:00 2001 From: Bryan Helmkamp Date: Tue, 24 Mar 2026 21:11:16 -0400 Subject: [PATCH] Replace RunConfig with RunSettings --- lib/crates/fabro-api/src/server.rs | 23 +- lib/crates/fabro-cli/src/commands/create.rs | 1 + lib/crates/fabro-cli/src/commands/resume.rs | 85 +- lib/crates/fabro-cli/src/commands/run.rs | 88 +- lib/crates/fabro-workflows/README.md | 15 +- .../src/core_adapter/lifecycle/disk.rs | 4 +- .../src/core_adapter/lifecycle/git.rs | 52 +- .../src/core_adapter/lifecycle/mod.rs | 18 +- lib/crates/fabro-workflows/src/engine.rs | 688 +++--- .../src/handler/manager_loop.rs | 21 +- .../fabro-workflows/src/pipeline/execute.rs | 6 +- .../fabro-workflows/src/pipeline/finalize.rs | 4 +- .../src/pipeline/initialize.rs | 6 +- .../fabro-workflows/src/pipeline/retro.rs | 4 +- .../fabro-workflows/src/pipeline/types.rs | 10 +- .../tests/daytona_integration.rs | 136 +- .../fabro-workflows/tests/integration.rs | 2037 ++++++----------- 17 files changed, 1238 insertions(+), 1960 deletions(-) diff --git a/lib/crates/fabro-api/src/server.rs b/lib/crates/fabro-api/src/server.rs index d71259fbe..b75470c5e 100644 --- a/lib/crates/fabro-api/src/server.rs +++ b/lib/crates/fabro-api/src/server.rs @@ -23,7 +23,7 @@ use crate::jwt_auth::{AuthMode, AuthenticatedService, AuthenticatedUser}; use fabro_interview::{Answer, Interviewer, QuestionType, WebInterviewer}; use fabro_workflows::checkpoint::Checkpoint; use fabro_workflows::context::Context; -use fabro_workflows::engine::{RunConfig, WorkflowRunEngine}; +use fabro_workflows::engine::{RunSettings, WorkflowRunEngine}; use fabro_workflows::event::{EventEmitter, WorkflowRunEvent}; use fabro_workflows::handler::HandlerRegistry; @@ -648,24 +648,21 @@ async fn execute_run(state: Arc, run_id: String) { } } - let config = RunConfig { + let run_record = fabro_workflows::run_record::RunRecord::load(&run_dir) + .expect("RunRecord must exist — written by start_run"); + let config = RunSettings { + config: run_record.config, run_dir, cancel_token: Some(cancel_token), dry_run: state.dry_run, run_id: run_id.clone(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, - labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, + labels: run_record.labels, git_author: state.git_author.clone(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; let result = tokio::select! { diff --git a/lib/crates/fabro-cli/src/commands/create.rs b/lib/crates/fabro-cli/src/commands/create.rs index 296c67e44..d89669af0 100644 --- a/lib/crates/fabro-cli/src/commands/create.rs +++ b/lib/crates/fabro-cli/src/commands/create.rs @@ -60,6 +60,7 @@ pub(crate) fn normalize_config( if flags.preserve_sandbox { config.sandbox.get_or_insert_default().preserve = Some(true); } + config.pull_request = config.pull_request.take().filter(|p| p.enabled); config } diff --git a/lib/crates/fabro-cli/src/commands/resume.rs b/lib/crates/fabro-cli/src/commands/resume.rs index 0be5a6fd4..2e5a247af 100644 --- a/lib/crates/fabro-cli/src/commands/resume.rs +++ b/lib/crates/fabro-cli/src/commands/resume.rs @@ -13,7 +13,7 @@ use fabro_model::{Catalog, Provider}; use fabro_util::terminal::Styles; use fabro_workflows::backend::{AgentApiBackend, AgentCliBackend, BackendRouter}; use fabro_workflows::checkpoint::Checkpoint; -use fabro_workflows::engine::RunConfig; +use fabro_workflows::engine::{GitCheckpointSettings, RunSettings}; use fabro_workflows::event::{EventEmitter, RunNoticeLevel}; use fabro_workflows::outcome::StageStatus; use fabro_workflows::run_record::RunRecord; @@ -102,7 +102,7 @@ struct ResumeContext { /// Kept as Arc so the sandbox event callbacks can emit through it. Listeners /// that need to be added later (e.g. ProgressUI) are registered separately. emitter: Arc, - config: RunConfig, + settings: RunSettings, setup_commands: Vec, /// Devcontainer lifecycle phases (on_create, post_create, post_start) resolved from config. devcontainer_phases: Vec<(String, Vec)>, @@ -231,7 +231,7 @@ async fn prepare_from_checkpoint( write_run_config_snapshot(&run_dir, workflow_toml_path.as_deref()).await?; // Write RunRecord for the resumed run - { + let settings_config = { let working_directory = std::env::current_dir().unwrap_or_else(|_| PathBuf::from(".")); let cli_flags = super::create::CliFlags { dry_run: args.dry_run, @@ -252,7 +252,7 @@ async fn prepare_from_checkpoint( let record = fabro_workflows::run_record::RunRecord { run_id: run_id.clone(), created_at: chrono::Utc::now(), - config: normalized, + config: normalized.clone(), graph: graph.clone(), workflow_slug: workflow_slug.clone(), working_directory: working_directory.clone(), @@ -261,7 +261,8 @@ async fn prepare_from_checkpoint( labels: std::collections::HashMap::new(), }; let _ = record.save(&run_dir); - } + normalized + }; let original_cwd = std::env::current_dir()?; let emitter = Arc::new(EventEmitter::new()); @@ -439,41 +440,23 @@ async fn prepare_from_checkpoint( }; let sandbox: Arc = Arc::new(fabro_agent::ReadBeforeWriteSandbox::new(sandbox)); - let config = RunConfig { + let settings = RunSettings { + config: settings_config, run_dir: run_dir.clone(), cancel_token: None, dry_run: args.dry_run, run_id: run_id.clone(), - git_checkpoint_enabled: false, host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, + git: None, labels: args .label .iter() .filter_map(|s| s.split_once('=')) .map(|(k, v)| (k.to_string(), v.to_string())) .collect(), - checkpoint_exclude_globs: run_cfg - .as_ref() - .map(|cfg| cfg.checkpoint.exclude_globs.clone()) - .unwrap_or_else(|| run_defaults.checkpoint.exclude_globs.clone()), github_app: github_app.clone(), git_author, base_branch: None, - pull_request: run_cfg - .as_ref() - .and_then(|cfg| cfg.pull_request.as_ref()) - .or(run_defaults.pull_request.as_ref()) - .filter(|p| p.enabled) - .cloned(), - asset_globs: run_cfg - .as_ref() - .and_then(|cfg| cfg.assets.as_ref()) - .or(run_defaults.assets.as_ref()) - .map(|a| a.include.clone()) - .unwrap_or_default(), workflow_slug, }; @@ -496,7 +479,7 @@ async fn prepare_from_checkpoint( run_cfg, sandbox, emitter, - config, + settings, setup_commands, devcontainer_phases, devcontainer_env, @@ -639,7 +622,7 @@ async fn prepare_from_branch( write_run_config_snapshot(&run_dir, None).await?; // Write RunRecord for the resumed run - { + let settings_config = { let (model_str, provider_str) = resolve_model_provider( args.model.as_deref(), args.provider.as_deref(), @@ -666,7 +649,7 @@ async fn prepare_from_branch( let record = fabro_workflows::run_record::RunRecord { run_id: run_id.clone(), created_at: chrono::Utc::now(), - config: normalized, + config: normalized.clone(), graph: graph.clone(), workflow_slug: workflow_slug.clone(), working_directory: resume_repo_path.clone(), @@ -675,7 +658,8 @@ async fn prepare_from_branch( labels: std::collections::HashMap::new(), }; let _ = record.save(&run_dir); - } + normalized + }; let emitter = Arc::new(EventEmitter::new()); @@ -888,42 +872,27 @@ async fn prepare_from_branch( .unwrap_or_default(); setup_commands.extend(sandbox.resume_setup_commands(&run_branch)); - let meta_branch = Some(fabro_workflows::git::MetadataStore::branch_name(&run_id)); - let config = RunConfig { + let settings = RunSettings { + config: settings_config, run_dir: run_dir.clone(), cancel_token: None, dry_run: args.dry_run, run_id: run_id.clone(), - git_checkpoint_enabled: true, host_repo_path: Some(resume_repo_path.clone()), - base_sha, - run_branch: Some(run_branch), - meta_branch, + git: Some(GitCheckpointSettings { + base_sha, + run_branch: Some(run_branch), + meta_branch: Some(fabro_workflows::git::MetadataStore::branch_name(&run_id)), + }), labels: args .label .iter() .filter_map(|s| s.split_once('=')) .map(|(k, v)| (k.to_string(), v.to_string())) .collect(), - checkpoint_exclude_globs: run_cfg - .as_ref() - .map(|cfg| cfg.checkpoint.exclude_globs.clone()) - .unwrap_or_else(|| run_defaults.checkpoint.exclude_globs.clone()), github_app: github_app.clone(), git_author, base_branch: detected_base_branch, - pull_request: run_cfg - .as_ref() - .and_then(|cfg| cfg.pull_request.as_ref()) - .or(run_defaults.pull_request.as_ref()) - .filter(|p| p.enabled) - .cloned(), - asset_globs: run_cfg - .as_ref() - .and_then(|cfg| cfg.assets.as_ref()) - .or(run_defaults.assets.as_ref()) - .map(|a| a.include.clone()) - .unwrap_or_default(), workflow_slug, }; @@ -940,7 +909,7 @@ async fn prepare_from_branch( run_cfg, sandbox, emitter, - config, + settings, setup_commands, devcontainer_phases, devcontainer_env, @@ -968,7 +937,7 @@ async fn run_resumed( mut run_cfg, sandbox, emitter, - mut config, + settings: mut config, setup_commands, devcontainer_phases, devcontainer_env, @@ -1386,7 +1355,7 @@ async fn run_resumed( // Auto-create PR on successful completion (mirrors run_command) let mut pushed_branch: Option = None; let mut pr_url: Option = None; - if let Some(ref pr_cfg) = config.pull_request { + if let Some(pr_cfg) = config.pull_request() { if config.dry_run { debug!("Skipping PR creation: dry-run mode"); } else if let Err(ref e) = engine_result { @@ -1408,12 +1377,12 @@ async fn run_resumed( Some(ref origin), ) = ( &config.base_branch, - &config.run_branch, + config.git.as_ref().and_then(|g| g.run_branch.as_ref()), &github_app, &origin_url, ) { - if config.git_checkpoint_enabled { - pushed_branch = Some(run_branch.clone()); + if config.git.is_some() { + pushed_branch = Some(run_branch.to_string()); } let auto_merge = if pr_cfg.auto_merge { diff --git a/lib/crates/fabro-cli/src/commands/run.rs b/lib/crates/fabro-cli/src/commands/run.rs index 3aa626cba..dea912c2d 100644 --- a/lib/crates/fabro-cli/src/commands/run.rs +++ b/lib/crates/fabro-cli/src/commands/run.rs @@ -20,7 +20,7 @@ use fabro_workflows::checkpoint::Checkpoint; use fabro_workflows::conclusion::Conclusion; use fabro_workflows::cost::{compute_stage_cost, format_cost}; use fabro_workflows::devcontainer_bridge; -use fabro_workflows::engine::{RunConfig, WorkflowRunEngine}; +use fabro_workflows::engine::{GitCheckpointSettings, RunSettings, WorkflowRunEngine}; use fabro_workflows::event::{EventEmitter, RunNoticeLevel, WorkflowRunEvent}; use fabro_workflows::git::GitSyncStatus; use fabro_workflows::handler::default_registry; @@ -1018,6 +1018,29 @@ async fn run_command_impl( record.save(&run_dir)?; } + let settings_config = if cached_run_restart { + existing_record + .as_ref() + .map(|r| r.config.clone()) + .unwrap_or_default() + } else { + super::create::normalize_config( + run_cfg.as_ref(), + &run_defaults, + &model, + provider.as_deref(), + sandbox_provider, + &graph, + super::create::CliFlags { + dry_run: dry_run_flag, + auto_approve: auto_approve_flag, + no_retro: no_retro_flag, + verbose: verbose_flag, + preserve_sandbox: preserve_sandbox_flag, + }, + ) + }; + // Now resolve ${env.VARNAME} references for runtime use. if let Some(ref mut cfg) = run_cfg { run_config::resolve_sandbox_env(cfg)?; @@ -1537,7 +1560,7 @@ async fn run_command_impl( "worktree_setup_failed", format!("Git worktree setup failed ({e}), running without worktree."), ); - // Reset so RunConfig does not enable git checkpointing + // Reset so RunSettings does not enable git checkpointing worktree_path = None; worktree_branch = None; worktree_base_sha = None; @@ -1710,53 +1733,39 @@ async fn run_command_impl( // 7. Execute // Set up metadata branch for git checkpointing (host or remote — engine fills remote) - let meta_branch = if worktree_path.is_some() { - Some(fabro_workflows::git::MetadataStore::branch_name(&run_id)) + let git = if worktree_path.is_some() { + Some(GitCheckpointSettings { + base_sha: worktree_base_sha, + run_branch: worktree_branch, + meta_branch: Some(fabro_workflows::git::MetadataStore::branch_name(&run_id)), + }) } else { None }; - let checkpoint_exclude_globs = run_cfg - .as_ref() - .map(|c| c.checkpoint.exclude_globs.clone()) - .unwrap_or_default(); - let mut config = RunConfig { + + let mut config = RunSettings { + config: settings_config, run_dir: run_dir.clone(), cancel_token: None, dry_run: dry_run_mode, run_id: run_id.clone(), - git_checkpoint_enabled: worktree_path.is_some(), - host_repo_path: existing_record - .as_ref() - .and_then(|r| r.host_repo_path.as_deref().map(PathBuf::from)) - .or_else(|| Some(original_cwd.clone())), - base_sha: worktree_base_sha, - run_branch: worktree_branch, - meta_branch, labels: label_vec .iter() .filter_map(|s| s.split_once('=')) .map(|(k, v)| (k.to_string(), v.to_string())) .collect(), - checkpoint_exclude_globs, + git_author: git_author.clone(), + workflow_slug: workflow_slug.clone(), github_app: github_app.clone(), - git_author, base_branch: existing_record .as_ref() .and_then(|r| r.base_branch.clone()) .or(detected_base_branch), - pull_request: run_cfg + host_repo_path: existing_record .as_ref() - .and_then(|c| c.pull_request.as_ref()) - .or(run_defaults.pull_request.as_ref()) - .filter(|p| p.enabled) - .cloned(), - asset_globs: run_cfg - .as_ref() - .and_then(|c| c.assets.as_ref()) - .or(run_defaults.assets.as_ref()) - .map(|a| a.include.clone()) - .unwrap_or_default(), - workflow_slug: workflow_slug.clone(), + .and_then(|r| r.host_repo_path.as_deref().map(PathBuf::from)) + .or_else(|| Some(original_cwd.clone())), + git, }; // Build lifecycle config for sandbox init, setup commands, and devcontainer phases @@ -1844,7 +1853,7 @@ async fn run_command_impl( // Auto-create PR on successful completion (skip in dry-run mode) let mut pushed_branch: Option = None; let mut pr_url: Option = None; - if let Some(ref pr_cfg) = config.pull_request { + if let Some(pr_cfg) = config.pull_request() { if dry_run_mode { debug!("Skipping PR creation: dry-run mode"); } else if let Err(ref e) = engine_result { @@ -1866,14 +1875,14 @@ async fn run_command_impl( Some(ref origin), ) = ( &config.base_branch, - &config.run_branch, + config.git.as_ref().and_then(|g| g.run_branch.as_ref()), &github_app, &origin_url, ) { // Run branch was pushed during checkpoint commits; // just record it for the PR creation. - if config.git_checkpoint_enabled { - pushed_branch = Some(run_branch.clone()); + if config.git.is_some() { + pushed_branch = Some(run_branch.to_string()); } let auto_merge = if pr_cfg.auto_merge { @@ -2689,10 +2698,11 @@ async fn run_preflight( /// /// This captures the last diff.patch (written after the final checkpoint) and retro.json. /// Best-effort: errors are logged as warnings. -pub(crate) async fn write_finalize_commit(config: &RunConfig, run_dir: &std::path::Path) { - let (Some(ref meta_branch), Some(ref repo_path)) = - (&config.meta_branch, &config.host_repo_path) - else { +pub(crate) async fn write_finalize_commit(config: &RunSettings, run_dir: &std::path::Path) { + let (Some(meta_branch), Some(repo_path)) = ( + config.git.as_ref().and_then(|g| g.meta_branch.as_ref()), + config.host_repo_path.as_ref(), + ) else { return; }; diff --git a/lib/crates/fabro-workflows/README.md b/lib/crates/fabro-workflows/README.md index 8675e43b3..6eea69425 100644 --- a/lib/crates/fabro-workflows/README.md +++ b/lib/crates/fabro-workflows/README.md @@ -62,7 +62,7 @@ assert_eq!(graph.goal(), "Run tests"); ### Running a Pipeline ```rust -use arc_workflows::engine::{PipelineEngine, RunConfig}; +use arc_workflows::engine::{PipelineEngine, RunSettings}; use arc_workflows::event::EventEmitter; use arc_workflows::handler::HandlerRegistry; use arc_workflows::handler::start::StartHandler; @@ -78,8 +78,19 @@ registry.register("exit", Box::new(ExitHandler)); registry.register("agent", Box::new(AgentHandler::new(None))); let engine = PipelineEngine::new(registry, EventEmitter::new()); -let config = RunConfig { +let config = RunSettings { + config: fabro_config::FabroConfig::default(), run_dir: "/tmp/pipeline-run".into(), + cancel_token: None, + dry_run: false, + run_id: "example-run".into(), + labels: std::collections::HashMap::new(), + git_author: fabro_workflows::git::GitAuthor::default(), + workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; // engine.run(&graph, &config).await diff --git a/lib/crates/fabro-workflows/src/core_adapter/lifecycle/disk.rs b/lib/crates/fabro-workflows/src/core_adapter/lifecycle/disk.rs index 013ea38b7..9b6b481ef 100644 --- a/lib/crates/fabro-workflows/src/core_adapter/lifecycle/disk.rs +++ b/lib/crates/fabro-workflows/src/core_adapter/lifecycle/disk.rs @@ -12,7 +12,7 @@ use super::super::graph::WorkflowGraph; use super::super::WorkflowNode; use super::circuit_breaker::CircuitBreakerLifecycle; use crate::checkpoint::Checkpoint; -use crate::engine::{self, RunConfig}; +use crate::engine::{self, RunSettings}; use crate::event::{EventEmitter, RunNoticeLevel, WorkflowRunEvent}; use crate::outcome::StageUsage; @@ -24,7 +24,7 @@ pub struct DiskLifecycle { pub run_dir: PathBuf, pub run_id: String, pub graph: Arc, - pub config: Arc, + pub config: Arc, pub emitter: Arc, pub circuit_breaker: Arc, pub checkpoint_enabled: bool, diff --git a/lib/crates/fabro-workflows/src/core_adapter/lifecycle/git.rs b/lib/crates/fabro-workflows/src/core_adapter/lifecycle/git.rs index cc3425e60..f7e3706a9 100644 --- a/lib/crates/fabro-workflows/src/core_adapter/lifecycle/git.rs +++ b/lib/crates/fabro-workflows/src/core_adapter/lifecycle/git.rs @@ -12,7 +12,7 @@ use fabro_core::state::RunState; use super::super::graph::WorkflowGraph; use super::super::WorkflowNode; use crate::artifact::ArtifactStore; -use crate::engine::{self, RunConfig}; +use crate::engine::{self, RunSettings}; use crate::event::{EventEmitter, RunNoticeLevel, WorkflowRunEvent}; use crate::outcome::{Outcome, StageStatus, StageUsage}; @@ -33,7 +33,7 @@ pub struct GitLifecycle { pub emitter: Arc, pub run_dir: PathBuf, pub run_id: String, - pub config: Arc, + pub config: Arc, pub start_node_id: Option, // Cross-lifecycle data (shared with EventLifecycle) pub checkpoint_git_result: Arc>>, @@ -52,9 +52,13 @@ impl RunLifecycle for GitLifecycle { *self.checkpoint_git_result.lock().unwrap() = None; // Init metadata branch (best-effort) - if let (Some(_), Some(ref repo_path)) = - (&self.config.meta_branch, &self.config.host_repo_path) - { + if let (Some(_), Some(repo_path)) = ( + self.config + .git + .as_ref() + .and_then(|g| g.meta_branch.as_ref()), + self.config.host_repo_path.as_ref(), + ) { let store = crate::git::MetadataStore::new(repo_path, &self.config.git_author); let run_json = std::fs::read(self.run_dir.join("run.json")).ok(); let start_json = std::fs::read(self.run_dir.join("start.json")).ok(); @@ -91,15 +95,19 @@ impl RunLifecycle for GitLifecycle { let node_id = node.id(); // Skip git checkpoint for the start node (always empty) or if git disabled - if self.start_node_id.as_deref() == Some(node_id) || !self.config.git_checkpoint_enabled { + if self.start_node_id.as_deref() == Some(node_id) || self.config.git.is_none() { *self.checkpoint_git_result.lock().unwrap() = None; return Ok(()); } // Shadow commit (best-effort, metadata branch) - let shadow_sha: Option = if let (Some(_), Some(ref repo_path)) = - (&self.config.meta_branch, &self.config.host_repo_path) - { + let shadow_sha: Option = if let (Some(_), Some(repo_path)) = ( + self.config + .git + .as_ref() + .and_then(|g| g.meta_branch.as_ref()), + self.config.host_repo_path.as_ref(), + ) { let store = crate::git::MetadataStore::new(repo_path, &self.config.git_author); // Build checkpoint JSON for shadow branch let checkpoint_path = self.run_dir.join("checkpoint.json"); @@ -148,7 +156,7 @@ impl RunLifecycle for GitLifecycle { &result.outcome.status.to_string(), completed_count, shadow_sha, - &self.config.checkpoint_exclude_globs, + self.config.checkpoint_exclude_globs(), &self.config.git_author, ) .await; @@ -177,10 +185,12 @@ impl RunLifecycle for GitLifecycle { // Push run branch (skip in dry-run mode) if !self.config.dry_run { - if let Some(ref branch) = self.config.run_branch { + if let Some(branch) = + self.config.git.as_ref().and_then(|g| g.run_branch.as_ref()) + { let push_ok = if self.sandbox.git_push_branch(branch).await { true - } else if let Some(ref repo_path) = self.config.host_repo_path { + } else if let Some(repo_path) = self.config.host_repo_path.as_ref() { let refspec = format!("refs/heads/{branch}"); engine::git_push_host( repo_path, @@ -195,9 +205,13 @@ impl RunLifecycle for GitLifecycle { git_result.push_results.push((branch.clone(), push_ok)); } // Push metadata branch (always from host) - if let (Some(ref meta_branch), Some(ref repo_path)) = - (&self.config.meta_branch, &self.config.host_repo_path) - { + if let (Some(meta_branch), Some(repo_path)) = ( + self.config + .git + .as_ref() + .and_then(|g| g.meta_branch.as_ref()), + self.config.host_repo_path.as_ref(), + ) { let refspec = format!("refs/heads/{meta_branch}"); let meta_push_ok = engine::git_push_host( repo_path, @@ -219,7 +233,7 @@ impl RunLifecycle for GitLifecycle { .lock() .unwrap() .clone() - .or_else(|| self.config.base_sha.clone()) + .or_else(|| self.config.git.as_ref().and_then(|g| g.base_sha.clone())) .unwrap_or_else(|| sha.clone()); let diff_dest = engine::node_dir(&self.run_dir, node_id, visit).join("diff.patch"); @@ -259,11 +273,11 @@ impl RunLifecycle for GitLifecycle { async fn on_run_end(&self, outcome: &Outcome, _state: &WfRunState) { // Write final.patch on success if (outcome.status == StageStatus::Success || outcome.status == StageStatus::PartialSuccess) - && self.config.git_checkpoint_enabled + && self.config.git.is_some() { - if let Some(ref base_sha) = self.config.base_sha { + if let Some(base_sha) = self.config.git.as_ref().and_then(|g| g.base_sha.clone()) { let diff_dest = self.run_dir.join("final.patch"); - match engine::git_diff(&*self.sandbox, base_sha).await { + match engine::git_diff(&*self.sandbox, &base_sha).await { Ok(patch) if !patch.is_empty() => { let _ = std::fs::write(&diff_dest, patch); } diff --git a/lib/crates/fabro-workflows/src/core_adapter/lifecycle/mod.rs b/lib/crates/fabro-workflows/src/core_adapter/lifecycle/mod.rs index bd28360eb..5ff144142 100644 --- a/lib/crates/fabro-workflows/src/core_adapter/lifecycle/mod.rs +++ b/lib/crates/fabro-workflows/src/core_adapter/lifecycle/mod.rs @@ -27,7 +27,7 @@ use super::graph::WorkflowGraph; use super::WorkflowNode; use crate::artifact::ArtifactStore; use crate::context; -use crate::engine::RunConfig; +use crate::engine::RunSettings; use crate::event::EventEmitter; use crate::outcome::{Outcome, StageUsage}; use fabro_hooks::HookRunner; @@ -79,7 +79,7 @@ impl WorkflowLifecycle { sandbox: Arc, graph: Arc, run_dir: PathBuf, - config: Arc, + config: Arc, is_resume: bool, ) -> Self { let restarted_from: Arc>> = Arc::new(Mutex::new(None)); @@ -91,8 +91,12 @@ impl WorkflowLifecycle { let circuit_breaker = Arc::new(CircuitBreakerLifecycle::new(loop_restart_signature_limit)); - let local_git_checkpoint = - config.git_checkpoint_enabled && sandbox.host_git_dir().is_some(); + let has_run_branch = config + .git + .as_ref() + .and_then(|g| g.run_branch.as_ref()) + .is_some(); + let local_git_checkpoint = has_run_branch && sandbox.host_git_dir().is_some(); let working_directory = if local_git_checkpoint { Some(sandbox.working_directory().to_string()) } else { @@ -105,8 +109,8 @@ impl WorkflowLifecycle { run_id: config.run_id.clone(), run_start: Mutex::new(Instant::now()), restarted_from: Arc::clone(&restarted_from), - base_sha: config.base_sha.clone(), - run_branch: config.run_branch.clone(), + base_sha: config.git.as_ref().and_then(|g| g.base_sha.clone()), + run_branch: config.git.as_ref().and_then(|g| g.run_branch.clone()), worktree_dir: working_directory.clone(), goal: (!graph.goal().is_empty()).then(|| graph.goal().to_string()), artifact_store: Arc::clone(&artifact_store), @@ -154,7 +158,7 @@ impl WorkflowLifecycle { Some(run_dir.clone()), Arc::clone(&emitter), run_dir, - config.asset_globs.clone(), + config.asset_globs().to_vec(), ); Self { diff --git a/lib/crates/fabro-workflows/src/engine.rs b/lib/crates/fabro-workflows/src/engine.rs index 01c16f756..4ddfd855d 100644 --- a/lib/crates/fabro-workflows/src/engine.rs +++ b/lib/crates/fabro-workflows/src/engine.rs @@ -23,7 +23,7 @@ use crate::error::{FabroError, FailureCategory, Result}; use crate::event::{EventEmitter, WorkflowRunEvent}; use crate::handler::{EngineServices, HandlerRegistry}; use crate::outcome::{Outcome, OutcomeExt, StageStatus}; -use fabro_config::run::PullRequestConfig; +use fabro_config::{config::FabroConfig, run::PullRequestConfig}; use fabro_graphviz::graph::{Edge, Graph, Node}; use fabro_hooks::{HookContext, HookDecision, HookEvent, HookRunner}; use fabro_interview::Interviewer; @@ -229,13 +229,14 @@ pub fn resolve_thread_id( /// Write start.json at the start of a workflow run. Returns the StartRecord. pub(crate) fn write_start_record( run_dir: &Path, - config: &RunConfig, + settings: &RunSettings, ) -> crate::start_record::StartRecord { + let git_state = settings.git.as_ref(); let record = crate::start_record::StartRecord { - run_id: config.run_id.clone(), + run_id: settings.run_id.clone(), start_time: Utc::now(), - run_branch: config.run_branch.clone(), - base_sha: config.base_sha.clone(), + run_branch: git_state.and_then(|g| g.run_branch.clone()), + base_sha: git_state.and_then(|g| g.base_sha.clone()), }; let _ = std::fs::create_dir_all(run_dir); let _ = record.save(run_dir); @@ -757,39 +758,54 @@ pub async fn git_replace_worktree(sandbox: &dyn Sandbox, path: &str, branch: &st /// Configuration for a workflow run. #[derive(Clone)] -pub struct RunConfig { +pub struct GitCheckpointSettings { + pub base_sha: Option, + pub run_branch: Option, + pub meta_branch: Option, +} + +/// Configuration for a workflow run. +#[derive(Clone)] +pub struct RunSettings { + pub config: FabroConfig, pub run_dir: PathBuf, pub cancel_token: Option>, pub dry_run: bool, /// Unique identifier for this workflow run. pub run_id: String, - /// Whether git checkpointing is enabled. - pub git_checkpoint_enabled: bool, - /// Host repo path for MetadataStore (shadow commits) and host-side pushes. - pub host_repo_path: Option, - /// SHA of the commit the worktree branched from. - pub base_sha: Option, - /// Git branch name for the run (e.g. `fabro/run/{run_id}`). - pub run_branch: Option, - /// Metadata branch name for git-native checkpoint storage (e.g. `fabro/meta/{run_id}`). - pub meta_branch: Option, /// User-defined key-value labels for this run. pub labels: HashMap, - /// Glob patterns to exclude from git checkpoint staging. - #[allow(clippy::struct_field_names)] - pub checkpoint_exclude_globs: Vec, - /// GitHub App credentials for pushing metadata branches to origin. - pub github_app: Option, /// Git author identity for checkpoint commits. pub git_author: crate::git::GitAuthor, - /// Name of the branch the run was started from (for PR base). - pub base_branch: Option, - /// Pull request configuration; `None` = disabled. - pub pull_request: Option, - /// Glob patterns for asset collection. Empty = no asset collection. - pub asset_globs: Vec, /// Workflow directory slug (e.g. "smoke" from `fabro/workflows/smoke/`). pub workflow_slug: Option, + /// GitHub App credentials for pushing metadata branches to origin. + pub github_app: Option, + /// Host repo path for MetadataStore (shadow commits) and host-side pushes. + pub host_repo_path: Option, + /// Name of the branch the run was started from (for PR base). + pub base_branch: Option, + /// Git checkpoint settings; `None` means checkpointing disabled. + pub git: Option, +} + +impl RunSettings { + pub fn checkpoint_exclude_globs(&self) -> &[String] { + &self.config.checkpoint.exclude_globs + } + + /// PR config (already normalized — disabled entries stripped at construction). + pub fn pull_request(&self) -> Option<&PullRequestConfig> { + self.config.pull_request.as_ref() + } + + pub fn asset_globs(&self) -> &[String] { + self.config + .assets + .as_ref() + .map(|a| a.include.as_slice()) + .unwrap_or(&[]) + } } /// Configuration for sandbox lifecycle management within the engine. @@ -900,8 +916,8 @@ impl WorkflowRunEngine { /// /// Returns an error if no start node is found, a node is missing, or a goal gate fails /// without a retry target. - pub async fn run(&self, graph: &Graph, config: &RunConfig) -> Result { - let (outcome, _context) = self.run_via_core(graph, config, None, None).await?; + pub async fn run(&self, graph: &Graph, settings: &RunSettings) -> Result { + let (outcome, _context) = self.run_via_core(graph, settings, None, None).await?; Ok(outcome) } @@ -923,12 +939,12 @@ impl WorkflowRunEngine { pub async fn run_with_lifecycle( &self, graph: &Graph, - config: &mut RunConfig, + settings: &mut RunSettings, lifecycle: LifecycleConfig, checkpoint: Option<&Checkpoint>, ) -> Result { - self.prepare_sandbox(graph, config, lifecycle).await?; - self.execute_graph(graph, config, checkpoint).await + self.prepare_sandbox(graph, settings, lifecycle).await?; + self.execute_graph(graph, settings, checkpoint).await } /// INITIALIZE: sandbox setup, git, setup commands, devcontainer. @@ -936,7 +952,7 @@ impl WorkflowRunEngine { pub async fn prepare_sandbox( &self, graph: &Graph, - config: &mut RunConfig, + settings: &mut RunSettings, lifecycle: LifecycleConfig, ) -> Result<()> { // 1. Initialize sandbox @@ -950,7 +966,7 @@ impl WorkflowRunEngine { { let hook_ctx = HookContext::new( HookEvent::SandboxReady, - config.run_id.clone(), + settings.run_id.clone(), graph.name.clone(), ); let decision = self.run_hooks(&hook_ctx, None).await; @@ -967,24 +983,34 @@ impl WorkflowRunEngine { working_directory: self.services.sandbox.working_directory().to_string(), }); - // 4. Sandbox git setup — let the sandbox set up its own git state if needed - // (skip when resuming from an existing branch — caller sets run_branch/base_sha) - if config.run_branch.is_none() { + // 4. Sandbox git setup — let the sandbox set up its own git state if needed. + // Skip when caller already has an assigned run branch. + let has_run_branch = settings + .git + .as_ref() + .and_then(|g| g.run_branch.as_ref()) + .is_some(); + if !has_run_branch { match self .services .sandbox - .setup_git_for_run(&config.run_id) + .setup_git_for_run(&settings.run_id) .await { Ok(Some(info)) => { - config.git_checkpoint_enabled = true; - config.base_sha = Some(info.base_sha); - config.run_branch = Some(info.run_branch); - if config.base_branch.is_none() { - config.base_branch = info.base_branch; + let base_sha = settings + .git + .as_ref() + .and_then(|g| g.base_sha.clone()) + .or(Some(info.base_sha)); + settings.git = Some(GitCheckpointSettings { + base_sha, + run_branch: Some(info.run_branch.clone()), + meta_branch: Some(crate::git::MetadataStore::branch_name(&settings.run_id)), + }); + if settings.base_branch.is_none() { + settings.base_branch = info.base_branch; } - config.meta_branch = - Some(crate::git::MetadataStore::branch_name(&config.run_id)); } Ok(None) => { // Sandbox does not manage git internally (e.g. local sandbox) @@ -1065,13 +1091,13 @@ impl WorkflowRunEngine { pub async fn execute_graph( &self, graph: &Graph, - config: &RunConfig, + settings: &RunSettings, checkpoint: Option<&Checkpoint>, ) -> Result { if let Some(cp) = checkpoint { - self.run_from_checkpoint(graph, config, cp).await + self.run_from_checkpoint(graph, settings, cp).await } else { - self.run(graph, config).await + self.run(graph, settings).await } } @@ -1104,10 +1130,10 @@ impl WorkflowRunEngine { pub async fn run_with_context( &self, graph: &Graph, - config: &RunConfig, + settings: &RunSettings, seed_context: Context, ) -> Result<(Outcome, Context)> { - self.run_via_core(graph, config, None, Some(seed_context)) + self.run_via_core(graph, settings, None, Some(seed_context)) .await } @@ -1120,11 +1146,11 @@ impl WorkflowRunEngine { pub async fn run_from_checkpoint( &self, graph: &Graph, - config: &RunConfig, + settings: &RunSettings, checkpoint: &Checkpoint, ) -> Result { let (outcome, _context) = self - .run_via_core(graph, config, Some(checkpoint), None) + .run_via_core(graph, settings, Some(checkpoint), None) .await?; Ok(outcome) } @@ -1133,7 +1159,7 @@ impl WorkflowRunEngine { async fn run_via_core( &self, graph: &Graph, - config: &RunConfig, + settings: &RunSettings, resume_checkpoint: Option<&Checkpoint>, seed_context: Option, ) -> Result<(Outcome, Context)> { @@ -1141,20 +1167,17 @@ impl WorkflowRunEngine { let wf_graph = crate::core_adapter::WorkflowGraph(Arc::clone(&graph_arc)); // Populate git_state for handlers (parallel, fan_in) when checkpointing is active - let git_state = if config.git_checkpoint_enabled { - config.base_sha.as_ref().map(|base_sha| { - Arc::new(GitState { - run_id: config.run_id.clone(), - base_sha: base_sha.clone(), - run_branch: config.run_branch.clone(), - meta_branch: config.meta_branch.clone(), - checkpoint_exclude_globs: config.checkpoint_exclude_globs.clone(), - git_author: config.git_author.clone(), - }) - }) - } else { - None - }; + let git_state = settings.git.as_ref().and_then(|git| { + let base_sha = git.base_sha.clone()?; + Some(Arc::new(GitState { + run_id: settings.run_id.clone(), + base_sha, + run_branch: git.run_branch.clone(), + meta_branch: git.meta_branch.clone(), + checkpoint_exclude_globs: settings.checkpoint_exclude_globs().to_vec(), + git_author: settings.git_author.clone(), + })) + }); // Build a shared EngineServices for the handler let shared_services = std::sync::Arc::new(EngineServices { @@ -1170,19 +1193,19 @@ impl WorkflowRunEngine { // Build handler let handler = std::sync::Arc::new(crate::core_adapter::WorkflowNodeHandler { services: shared_services, - run_dir: config.run_dir.clone(), + run_dir: settings.run_dir.clone(), graph: Arc::clone(&graph_arc), }); // Build lifecycle - let config_arc = std::sync::Arc::new(config.clone()); + let settings_arc = std::sync::Arc::new(settings.clone()); let lifecycle = crate::core_adapter::WorkflowLifecycle::new( self.services.emitter.clone(), self.services.hook_runner.clone(), self.services.sandbox.clone(), graph_arc, - config.run_dir.clone(), - config_arc, + settings.run_dir.clone(), + settings_arc, resume_checkpoint.is_some(), ); @@ -1251,7 +1274,7 @@ impl WorkflowRunEngine { let graph_max = graph.max_node_visits(); let max_node_visits = if graph_max > 0 { Some(graph_max as usize) - } else if config.dry_run { + } else if settings.dry_run { Some(10) } else { None @@ -1306,7 +1329,7 @@ impl WorkflowRunEngine { ) .lifecycle(Box::new(lifecycle)); - if let Some(ref cancel) = config.cancel_token { + if let Some(ref cancel) = settings.cancel_token { builder = builder.cancel_token(cancel.clone()); } if let Some(token) = stall_token.clone() { @@ -2129,23 +2152,23 @@ mod tests { let g = simple_graph(); let engine = WorkflowRunEngine::new(make_registry(), Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, + config: FabroConfig::default(), + git: Some(GitCheckpointSettings { + base_sha: None, + run_branch: Some("fabro/run/test-run".into()), + meta_branch: None, + }), host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, + labels: HashMap::new(), - checkpoint_exclude_globs: Vec::new(), github_app: None, git_author: crate::git::GitAuthor::default(), base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, }; let outcome = engine.run(&g, &config).await.unwrap(); @@ -2158,23 +2181,23 @@ mod tests { let g = simple_graph(); let engine = WorkflowRunEngine::new(make_registry(), Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, + config: FabroConfig::default(), + git: Some(GitCheckpointSettings { + base_sha: None, + run_branch: Some("fabro/run/test-run".into()), + meta_branch: None, + }), host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, + labels: HashMap::new(), - checkpoint_exclude_globs: Vec::new(), github_app: None, git_author: crate::git::GitAuthor::default(), base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, }; engine.run(&g, &config).await.unwrap(); @@ -2195,23 +2218,23 @@ mod tests { }); let engine = WorkflowRunEngine::new(make_registry(), Arc::new(emitter), local_env()); - let config = RunConfig { + let config = RunSettings { run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, + config: FabroConfig::default(), + git: Some(GitCheckpointSettings { + base_sha: None, + run_branch: Some("fabro/run/test-run".into()), + meta_branch: None, + }), host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, + labels: HashMap::new(), - checkpoint_exclude_globs: Vec::new(), github_app: None, git_author: crate::git::GitAuthor::default(), base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, }; engine.run(&g, &config).await.unwrap(); @@ -2228,23 +2251,23 @@ mod tests { let g = Graph::new("empty"); let engine = WorkflowRunEngine::new(make_registry(), Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, + config: FabroConfig::default(), + git: Some(GitCheckpointSettings { + base_sha: None, + run_branch: Some("fabro/run/test-run".into()), + meta_branch: None, + }), host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, + labels: HashMap::new(), - checkpoint_exclude_globs: Vec::new(), github_app: None, git_author: crate::git::GitAuthor::default(), base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, }; let result = engine.run(&g, &config).await; @@ -2257,23 +2280,19 @@ mod tests { let g = simple_graph(); let engine = WorkflowRunEngine::new(make_registry(), Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, + config: FabroConfig::default(), + git: None, host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, + labels: HashMap::new(), - checkpoint_exclude_globs: Vec::new(), github_app: None, git_author: crate::git::GitAuthor::default(), base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, }; engine.run(&g, &config).await.unwrap(); @@ -2299,23 +2318,19 @@ mod tests { let engine = WorkflowRunEngine::new(make_registry(), Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, + config: FabroConfig::default(), + git: None, host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, + labels: HashMap::new(), - checkpoint_exclude_globs: Vec::new(), github_app: None, git_author: crate::git::GitAuthor::default(), base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, }; let outcome = engine.run(&g, &config).await.unwrap(); @@ -2365,23 +2380,19 @@ mod tests { let engine = WorkflowRunEngine::new(make_registry(), Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, + config: FabroConfig::default(), + git: None, host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, + labels: HashMap::new(), - checkpoint_exclude_globs: Vec::new(), github_app: None, git_author: crate::git::GitAuthor::default(), base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, }; engine.run(&g, &config).await.unwrap(); @@ -2458,23 +2469,23 @@ mod tests { let g = simple_graph(); let engine = WorkflowRunEngine::new(make_registry(), Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, + config: FabroConfig::default(), + git: Some(GitCheckpointSettings { + base_sha: None, + run_branch: Some("fabro/run/test-run".into()), + meta_branch: None, + }), host_repo_path: None, - base_sha: None, - run_branch: Some("fabro/run/test-run".into()), - meta_branch: None, + labels: HashMap::new(), - checkpoint_exclude_globs: Vec::new(), github_app: None, git_author: crate::git::GitAuthor::default(), base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, }; engine.run(&g, &config).await.unwrap(); @@ -2490,23 +2501,23 @@ mod tests { let g = simple_graph(); let engine = WorkflowRunEngine::new(make_registry(), Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "sha-run".into(), - git_checkpoint_enabled: false, + config: FabroConfig::default(), + git: Some(GitCheckpointSettings { + base_sha: Some("abc123".into()), + run_branch: None, + meta_branch: None, + }), host_repo_path: None, - base_sha: Some("abc123".into()), - run_branch: None, - meta_branch: None, + labels: HashMap::new(), - checkpoint_exclude_globs: Vec::new(), github_app: None, git_author: crate::git::GitAuthor::default(), base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, }; engine.run(&g, &config).await.unwrap(); @@ -2521,23 +2532,19 @@ mod tests { let g = simple_graph(); let engine = WorkflowRunEngine::new(make_registry(), Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "no-optional-run".into(), - git_checkpoint_enabled: false, + config: FabroConfig::default(), + git: None, host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, + labels: HashMap::new(), - checkpoint_exclude_globs: Vec::new(), github_app: None, git_author: crate::git::GitAuthor::default(), base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, }; engine.run(&g, &config).await.unwrap(); @@ -2553,23 +2560,19 @@ mod tests { let g = simple_graph(); let engine = WorkflowRunEngine::new(make_registry(), Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, + config: FabroConfig::default(), + git: None, host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, + labels: HashMap::new(), - checkpoint_exclude_globs: Vec::new(), github_app: None, git_author: crate::git::GitAuthor::default(), base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, }; engine.run(&g, &config).await.unwrap(); @@ -2588,23 +2591,19 @@ mod tests { let g = simple_graph(); let engine = WorkflowRunEngine::new(make_registry(), Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, + config: FabroConfig::default(), + git: None, host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, + labels: HashMap::new(), - checkpoint_exclude_globs: Vec::new(), github_app: None, git_author: crate::git::GitAuthor::default(), base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, }; engine.run(&g, &config).await.unwrap(); @@ -2770,23 +2769,19 @@ mod tests { let g = simple_graph(); let engine = WorkflowRunEngine::new(make_registry(), Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, + config: FabroConfig::default(), + git: None, host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, + labels: HashMap::new(), - checkpoint_exclude_globs: Vec::new(), github_app: None, git_author: crate::git::GitAuthor::default(), base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, }; engine.run(&g, &config).await.unwrap(); @@ -2815,23 +2810,19 @@ mod tests { let engine = WorkflowRunEngine::new(make_registry(), Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, + config: FabroConfig::default(), + git: None, host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, + labels: HashMap::new(), - checkpoint_exclude_globs: Vec::new(), github_app: None, git_author: crate::git::GitAuthor::default(), base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, }; engine.run(&g, &config).await.unwrap(); @@ -2878,23 +2869,19 @@ mod tests { let mut registry = make_registry(); registry.register("always_fail", Box::new(AlwaysFailHandler)); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, + config: FabroConfig::default(), + git: None, host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, + labels: HashMap::new(), - checkpoint_exclude_globs: Vec::new(), github_app: None, git_author: crate::git::GitAuthor::default(), base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, }; let outcome = engine.run(&g, &config).await.unwrap(); @@ -2949,23 +2936,19 @@ mod tests { let mut registry = make_registry(); registry.register("always_fail", Box::new(AlwaysFailHandler)); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, + config: FabroConfig::default(), + git: None, host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, + labels: HashMap::new(), - checkpoint_exclude_globs: Vec::new(), github_app: None, git_author: crate::git::GitAuthor::default(), base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, }; let result = engine.run(&g, &config).await; @@ -3020,23 +3003,19 @@ mod tests { let mut registry = make_registry(); registry.register("slow", Box::new(SlowHandler { sleep_ms: 500 })); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, + config: FabroConfig::default(), + git: None, host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, + labels: HashMap::new(), - checkpoint_exclude_globs: Vec::new(), github_app: None, git_author: crate::git::GitAuthor::default(), base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, }; let result = engine.run(&g, &config).await; @@ -3080,23 +3059,19 @@ mod tests { let mut registry = make_registry(); registry.register("slow", Box::new(SlowHandler { sleep_ms: 10 })); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, + config: FabroConfig::default(), + git: None, host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, + labels: HashMap::new(), - checkpoint_exclude_globs: Vec::new(), github_app: None, git_author: crate::git::GitAuthor::default(), base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, }; let outcome = engine.run(&g, &config).await.unwrap(); @@ -3141,23 +3116,19 @@ mod tests { let mut registry = make_registry(); registry.register("slow", Box::new(SlowHandler { sleep_ms: 500 })); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, + config: FabroConfig::default(), + git: None, host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, + labels: HashMap::new(), - checkpoint_exclude_globs: Vec::new(), github_app: None, git_author: crate::git::GitAuthor::default(), base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, }; let outcome = engine.run(&g, &config).await.unwrap(); @@ -3181,23 +3152,19 @@ mod tests { let g = simple_graph(); let engine = WorkflowRunEngine::new(make_registry(), Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, + config: FabroConfig::default(), + git: None, host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, + labels: HashMap::new(), - checkpoint_exclude_globs: Vec::new(), github_app: None, git_author: crate::git::GitAuthor::default(), base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, }; let outcome = engine.run(&g, &config).await.unwrap(); @@ -3213,23 +3180,19 @@ mod tests { let engine = WorkflowRunEngine::new(make_registry(), Arc::new(EventEmitter::new()), local_env()); let cancel_token = Arc::new(AtomicBool::new(true)); - let config = RunConfig { + let config = RunSettings { run_dir: dir.path().to_path_buf(), cancel_token: Some(cancel_token), dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, + config: FabroConfig::default(), + git: None, host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, + labels: HashMap::new(), - checkpoint_exclude_globs: Vec::new(), github_app: None, git_author: crate::git::GitAuthor::default(), base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, }; let result = engine.run(&g, &config).await; @@ -3244,23 +3207,19 @@ mod tests { let engine = WorkflowRunEngine::new(make_registry(), Arc::new(EventEmitter::new()), local_env()); let cancel_token = Arc::new(AtomicBool::new(false)); - let config = RunConfig { + let config = RunSettings { run_dir: dir.path().to_path_buf(), cancel_token: Some(cancel_token), dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, + config: FabroConfig::default(), + git: None, host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, + labels: HashMap::new(), - checkpoint_exclude_globs: Vec::new(), github_app: None, git_author: crate::git::GitAuthor::default(), base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, }; let outcome = engine.run(&g, &config).await.unwrap(); @@ -3288,23 +3247,19 @@ mod tests { let mut registry = make_registry(); registry.register("slow", Box::new(SlowHandler { sleep_ms: 200 })); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { run_dir: dir.path().to_path_buf(), cancel_token: Some(cancel_token), dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, + config: FabroConfig::default(), + git: None, host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, + labels: HashMap::new(), - checkpoint_exclude_globs: Vec::new(), github_app: None, git_author: crate::git::GitAuthor::default(), base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, }; @@ -3369,23 +3324,19 @@ mod tests { .insert("max_node_visits".to_string(), AttrValue::Integer(3)); let engine = WorkflowRunEngine::new(make_registry(), Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, + config: FabroConfig::default(), + git: None, host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, + labels: HashMap::new(), - checkpoint_exclude_globs: Vec::new(), github_app: None, git_author: crate::git::GitAuthor::default(), base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, }; let result = engine.run(&g, &config).await; @@ -3403,23 +3354,19 @@ mod tests { let g = cyclic_graph(); let engine = WorkflowRunEngine::new(make_registry(), Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: true, run_id: "test-run".into(), - git_checkpoint_enabled: false, + config: FabroConfig::default(), + git: None, host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, + labels: HashMap::new(), - checkpoint_exclude_globs: Vec::new(), github_app: None, git_author: crate::git::GitAuthor::default(), base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, }; let result = engine.run(&g, &config).await; @@ -3439,23 +3386,19 @@ mod tests { .insert("max_node_visits".to_string(), AttrValue::Integer(2)); let engine = WorkflowRunEngine::new(make_registry(), Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: true, run_id: "test-run".into(), - git_checkpoint_enabled: false, + config: FabroConfig::default(), + git: None, host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, + labels: HashMap::new(), - checkpoint_exclude_globs: Vec::new(), github_app: None, git_author: crate::git::GitAuthor::default(), base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, }; let result = engine.run(&g, &config).await; @@ -3480,23 +3423,19 @@ mod tests { .insert("max_visits".to_string(), AttrValue::Integer(2)); let engine = WorkflowRunEngine::new(make_registry(), Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, + config: FabroConfig::default(), + git: None, host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, + labels: HashMap::new(), - checkpoint_exclude_globs: Vec::new(), github_app: None, git_author: crate::git::GitAuthor::default(), base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, }; let result = engine.run(&g, &config).await; @@ -3519,23 +3458,19 @@ mod tests { .insert("max_visits".to_string(), AttrValue::Integer(3)); let engine = WorkflowRunEngine::new(make_registry(), Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: true, run_id: "test-run".into(), - git_checkpoint_enabled: false, + config: FabroConfig::default(), + git: None, host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, + labels: HashMap::new(), - checkpoint_exclude_globs: Vec::new(), github_app: None, git_author: crate::git::GitAuthor::default(), base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, }; let result = engine.run(&g, &config).await; @@ -3555,23 +3490,19 @@ mod tests { .insert("max_node_visits".to_string(), AttrValue::Integer(3)); let engine = WorkflowRunEngine::new(make_registry(), Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, + config: FabroConfig::default(), + git: None, host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, + labels: HashMap::new(), - checkpoint_exclude_globs: Vec::new(), github_app: None, git_author: crate::git::GitAuthor::default(), base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, }; let result = engine.run(&g, &config).await; @@ -3652,23 +3583,19 @@ mod tests { let mut registry = make_registry(); registry.register("panicker", Box::new(PanickingHandler)); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, + config: FabroConfig::default(), + git: None, host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, + labels: HashMap::new(), - checkpoint_exclude_globs: Vec::new(), github_app: None, git_author: crate::git::GitAuthor::default(), base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, }; @@ -3866,23 +3793,19 @@ mod tests { let mut registry = make_registry(); registry.register("always_fail", Box::new(AlwaysFailHandler)); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, + config: FabroConfig::default(), + git: None, host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, + labels: HashMap::new(), - checkpoint_exclude_globs: Vec::new(), github_app: None, git_author: crate::git::GitAuthor::default(), base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, }; let result = engine.run(&g, &config).await; @@ -3905,23 +3828,19 @@ mod tests { let mut registry = make_registry(); registry.register("always_fail", Box::new(TransientFailHandler)); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, + config: FabroConfig::default(), + git: None, host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, + labels: HashMap::new(), - checkpoint_exclude_globs: Vec::new(), github_app: None, git_author: crate::git::GitAuthor::default(), base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, }; let result = engine.run(&g, &config).await; @@ -3951,23 +3870,19 @@ mod tests { }), ); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, + config: FabroConfig::default(), + git: None, host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, + labels: HashMap::new(), - checkpoint_exclude_globs: Vec::new(), github_app: None, git_author: crate::git::GitAuthor::default(), base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, }; let result = engine.run(&g, &config).await; @@ -4037,23 +3952,19 @@ mod tests { let mut registry = make_registry(); registry.register("always_fail", Box::new(AlwaysFailHandler)); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, + config: FabroConfig::default(), + git: None, host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, + labels: HashMap::new(), - checkpoint_exclude_globs: Vec::new(), github_app: None, git_author: crate::git::GitAuthor::default(), base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, }; let result = engine.run(&g, &config).await; @@ -4134,23 +4045,19 @@ mod tests { let mut registry = make_registry(); registry.register("slow", Box::new(SlowHandler { sleep_ms: 60_000 })); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, + config: FabroConfig::default(), + git: None, host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, + labels: HashMap::new(), - checkpoint_exclude_globs: Vec::new(), github_app: None, git_author: crate::git::GitAuthor::default(), base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, }; let result = engine.run(&g, &config).await; @@ -4208,23 +4115,19 @@ mod tests { }), ); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, + config: FabroConfig::default(), + git: None, host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, + labels: HashMap::new(), - checkpoint_exclude_globs: Vec::new(), github_app: None, git_author: crate::git::GitAuthor::default(), base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, }; let outcome = engine.run(&g, &config).await.unwrap(); @@ -4269,23 +4172,19 @@ mod tests { let mut registry = make_registry(); registry.register("slow", Box::new(SlowHandler { sleep_ms: 50 })); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, + config: FabroConfig::default(), + git: None, host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, + labels: HashMap::new(), - checkpoint_exclude_globs: Vec::new(), github_app: None, git_author: crate::git::GitAuthor::default(), base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, }; let outcome = engine.run(&g, &config).await.unwrap(); @@ -4331,23 +4230,19 @@ mod tests { let mut registry = make_registry(); registry.register("always_fail", Box::new(AlwaysFailHandler)); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, + config: FabroConfig::default(), + git: None, host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, + labels: HashMap::new(), - checkpoint_exclude_globs: Vec::new(), github_app: None, git_author: crate::git::GitAuthor::default(), base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, }; let _outcome = engine.run(&g, &config).await.unwrap(); @@ -4489,23 +4384,22 @@ mod tests { let sandbox: Arc = Arc::new(fabro_agent::LocalSandbox::new(repo.to_path_buf())); let engine = WorkflowRunEngine::new(make_registry(), Arc::new(emitter), sandbox); - let config = RunConfig { + let config = RunSettings { run_dir: run_tmp.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "git-cp-test".into(), - git_checkpoint_enabled: true, + config: FabroConfig::default(), + git: Some(GitCheckpointSettings { + base_sha: Some(base_sha), + run_branch: None, + meta_branch: Some(crate::git::MetadataStore::branch_name("git-cp-test")), + }), host_repo_path: Some(repo.to_path_buf()), - base_sha: Some(base_sha), - run_branch: None, - meta_branch: None, labels: HashMap::new(), - checkpoint_exclude_globs: Vec::new(), github_app: None, git_author: crate::git::GitAuthor::default(), base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, }; engine.run(&g, &config).await.unwrap(); @@ -4533,24 +4427,20 @@ mod tests { ); } - fn test_run_config(run_dir: &std::path::Path, run_id: &str) -> RunConfig { - RunConfig { + fn test_run_settings(run_dir: &std::path::Path, run_id: &str) -> RunSettings { + RunSettings { run_dir: run_dir.to_path_buf(), cancel_token: None, dry_run: false, run_id: run_id.into(), - git_checkpoint_enabled: false, + config: FabroConfig::default(), + git: None, host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, + labels: HashMap::new(), - checkpoint_exclude_globs: Vec::new(), github_app: None, git_author: crate::git::GitAuthor::default(), base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, } } @@ -4576,7 +4466,7 @@ mod tests { }); let engine = WorkflowRunEngine::new(make_registry(), Arc::new(emitter), local_env()); - let mut config = test_run_config(dir.path(), "lifecycle-test"); + let mut config = test_run_settings(dir.path(), "lifecycle-test"); let outcome = engine .run_with_lifecycle(&g, &mut config, test_lifecycle(Vec::new()), None) .await @@ -4607,7 +4497,7 @@ mod tests { }); let engine = WorkflowRunEngine::new(make_registry(), Arc::new(emitter), local_env()); - let mut config = test_run_config(dir.path(), "setup-test"); + let mut config = test_run_settings(dir.path(), "setup-test"); let outcome = engine .run_with_lifecycle( &g, @@ -4637,7 +4527,7 @@ mod tests { let engine = WorkflowRunEngine::new(make_registry(), Arc::new(EventEmitter::new()), local_env()); - let mut config = test_run_config(dir.path(), "setup-fail-test"); + let mut config = test_run_settings(dir.path(), "setup-fail-test"); let result = engine .run_with_lifecycle( &g, @@ -4743,7 +4633,7 @@ mod tests { ); let engine = WorkflowRunEngine::new(registry, Arc::new(emitter), local_env()); - let config = test_run_config(dir.path(), "retry-events-test"); + let config = test_run_settings(dir.path(), "retry-events-test"); let outcome = engine.run(&g, &config).await.unwrap(); assert_eq!(outcome.status, StageStatus::Success); @@ -4786,7 +4676,7 @@ mod tests { }); let engine = WorkflowRunEngine::new(make_registry(), Arc::new(emitter), local_env()); - let mut config = test_run_config(dir.path(), "order-test"); + let mut config = test_run_settings(dir.path(), "order-test"); engine .run_with_lifecycle( &g, diff --git a/lib/crates/fabro-workflows/src/handler/manager_loop.rs b/lib/crates/fabro-workflows/src/handler/manager_loop.rs index 519c087f6..1cb563e7d 100644 --- a/lib/crates/fabro-workflows/src/handler/manager_loop.rs +++ b/lib/crates/fabro-workflows/src/handler/manager_loop.rs @@ -9,7 +9,7 @@ use async_trait::async_trait; use crate::condition::evaluate_condition; use crate::context::keys; use crate::context::{Context, WorkflowContext}; -use crate::engine::{RunConfig, WorkflowRunEngine}; +use crate::engine::{RunSettings, WorkflowRunEngine}; use crate::error::FabroError; use crate::outcome::{Outcome, OutcomeExt, StageStatus}; use crate::workflow::{prepare_from_file, prepare_from_source}; @@ -127,7 +127,7 @@ impl Handler for SubWorkflowHandler { } }; - // Build child RunConfig + // Build child RunSettings let visit = crate::engine::visit_from_context(context) as u64; let child_logs = run_dir.join(format!("nodes/{}_{visit}/child", node.id)); let _ = std::fs::create_dir_all(&child_logs); @@ -137,27 +137,22 @@ impl Handler for SubWorkflowHandler { let child_cancel = Arc::clone(&cancel_token); let git_state = services.git_state(); - let child_config = RunConfig { + let child_config = RunSettings { + config: fabro_config::FabroConfig::default(), run_dir: child_logs, cancel_token: Some(cancel_token), dry_run: services.dry_run, run_id: format!("{parent_run_id}_child_{}", node.id), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: git_state .as_ref() .map(|gs| gs.git_author.clone()) .unwrap_or_default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; // Clone parent context for child; inject parent preamble diff --git a/lib/crates/fabro-workflows/src/pipeline/execute.rs b/lib/crates/fabro-workflows/src/pipeline/execute.rs index b18e83ea6..e65b00a85 100644 --- a/lib/crates/fabro-workflows/src/pipeline/execute.rs +++ b/lib/crates/fabro-workflows/src/pipeline/execute.rs @@ -10,7 +10,7 @@ pub async fn execute(init: Initialized) -> Executed { graph, source: _, engine, - config, + settings, checkpoint, emitter, sandbox, @@ -19,7 +19,7 @@ pub async fn execute(init: Initialized) -> Executed { let start = Instant::now(); let outcome = engine - .execute_graph(&graph, &config, checkpoint.as_ref()) + .execute_graph(&graph, &settings, checkpoint.as_ref()) .await; let duration_ms = crate::millis_u64(start.elapsed()); @@ -27,7 +27,7 @@ pub async fn execute(init: Initialized) -> Executed { Executed { graph, outcome, - config, + settings, engine, emitter, sandbox, diff --git a/lib/crates/fabro-workflows/src/pipeline/finalize.rs b/lib/crates/fabro-workflows/src/pipeline/finalize.rs index 1ab7bae4f..7d5652f2e 100644 --- a/lib/crates/fabro-workflows/src/pipeline/finalize.rs +++ b/lib/crates/fabro-workflows/src/pipeline/finalize.rs @@ -14,7 +14,7 @@ pub async fn finalize( let Retroed { graph: _, outcome, - config, + settings, engine: _, emitter: _, sandbox: _, @@ -45,7 +45,7 @@ pub async fn finalize( }; Ok(Finalized { - run_id: config.run_id, + run_id: settings.run_id, outcome, conclusion, pr_url: None, diff --git a/lib/crates/fabro-workflows/src/pipeline/initialize.rs b/lib/crates/fabro-workflows/src/pipeline/initialize.rs index e07087103..061a46406 100644 --- a/lib/crates/fabro-workflows/src/pipeline/initialize.rs +++ b/lib/crates/fabro-workflows/src/pipeline/initialize.rs @@ -47,16 +47,16 @@ pub async fn initialize( // Prepare sandbox (initialize, git setup, setup commands, devcontainer) engine - .prepare_sandbox(&graph, &mut options.run_config, options.lifecycle) + .prepare_sandbox(&graph, &mut options.run_settings, options.lifecycle) .await?; - // At this point run_config may have been mutated by prepare_sandbox (base_sha, run_branch, etc.) + // At this point run_settings may have been mutated by prepare_sandbox (base_sha, run_branch, etc.) Ok(Initialized { graph, source, engine, - config: options.run_config, + settings: options.run_settings, checkpoint: None, emitter: options.emitter, sandbox: options.sandbox, diff --git a/lib/crates/fabro-workflows/src/pipeline/retro.rs b/lib/crates/fabro-workflows/src/pipeline/retro.rs index 9c3b324c3..ad85cd202 100644 --- a/lib/crates/fabro-workflows/src/pipeline/retro.rs +++ b/lib/crates/fabro-workflows/src/pipeline/retro.rs @@ -8,7 +8,7 @@ pub async fn retro(executed: Executed, _options: &RetroOptions) -> Retroed { let Executed { graph, outcome, - config, + settings, engine, emitter, sandbox, @@ -20,7 +20,7 @@ pub async fn retro(executed: Executed, _options: &RetroOptions) -> Retroed { Retroed { graph, outcome, - config, + settings, engine, emitter, sandbox, diff --git a/lib/crates/fabro-workflows/src/pipeline/types.rs b/lib/crates/fabro-workflows/src/pipeline/types.rs index 420823798..2165eb61e 100644 --- a/lib/crates/fabro-workflows/src/pipeline/types.rs +++ b/lib/crates/fabro-workflows/src/pipeline/types.rs @@ -8,7 +8,7 @@ use fabro_validate::Diagnostic; use crate::checkpoint::Checkpoint; use crate::conclusion::Conclusion; -use crate::engine::{LifecycleConfig, RunConfig, WorkflowRunEngine}; +use crate::engine::{LifecycleConfig, RunSettings, WorkflowRunEngine}; use crate::error::FabroError; use crate::event::EventEmitter; use crate::handler::HandlerRegistry; @@ -103,7 +103,7 @@ pub struct InitOptions { pub sandbox: Arc, pub registry: HandlerRegistry, pub lifecycle: LifecycleConfig, - pub run_config: RunConfig, + pub run_settings: RunSettings, pub hooks: fabro_hooks::HookConfig, pub sandbox_env: HashMap, } @@ -114,7 +114,7 @@ pub struct Initialized { pub graph: Graph, pub source: String, pub engine: WorkflowRunEngine, - pub config: RunConfig, + pub settings: RunSettings, pub(crate) checkpoint: Option, pub emitter: Arc, pub sandbox: Arc, @@ -125,7 +125,7 @@ pub struct Initialized { pub struct Executed { pub graph: Graph, pub outcome: Result, - pub config: RunConfig, + pub settings: RunSettings, pub engine: WorkflowRunEngine, pub emitter: Arc, pub sandbox: Arc, @@ -137,7 +137,7 @@ pub struct Executed { pub struct Retroed { pub graph: Graph, pub outcome: Result, - pub config: RunConfig, + pub settings: RunSettings, pub engine: WorkflowRunEngine, pub emitter: Arc, pub sandbox: Arc, diff --git a/lib/crates/fabro-workflows/tests/daytona_integration.rs b/lib/crates/fabro-workflows/tests/daytona_integration.rs index fd8e8ed5c..b13ea6c1b 100644 --- a/lib/crates/fabro-workflows/tests/daytona_integration.rs +++ b/lib/crates/fabro-workflows/tests/daytona_integration.rs @@ -8,13 +8,14 @@ use std::path::Path; use std::sync::Arc; use fabro_agent::Sandbox; +use fabro_config::FabroConfig; use fabro_graphviz::graph::{AttrValue, Edge, Graph, Node}; use fabro_llm::provider::Provider; use fabro_sandbox::daytona::{DaytonaConfig, DaytonaSandbox, DaytonaSnapshotConfig}; use fabro_workflows::artifact::sync_artifacts_to_env; use fabro_workflows::checkpoint::Checkpoint; use fabro_workflows::context::Context; -use fabro_workflows::engine::{RunConfig, WorkflowRunEngine}; +use fabro_workflows::engine::{GitCheckpointSettings, RunSettings, WorkflowRunEngine}; use fabro_workflows::error::FabroError; use fabro_workflows::event::EventEmitter; use fabro_workflows::handler::exit::ExitHandler; @@ -386,26 +387,20 @@ async fn daytona_pipeline_artifact_offload_and_sync() { registry.register("exit", Box::new(ExitHandler)); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), env.clone()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; - let outcome = engine .run(&graph, &config) .await @@ -536,7 +531,7 @@ async fn daytona_git_checkpoint_remote_emits_events() { } // Set up git in the sandbox - let (run_id, base_sha, branch_name) = setup_daytona_git(&*env).await; + let (_run_id, base_sha, branch_name) = setup_daytona_git(&*env).await; // Pipeline: start -> work -> exit let mut graph = Graph::new("DaytonaGitCheckpoint"); @@ -583,26 +578,24 @@ async fn daytona_git_checkpoint_remote_emits_events() { registry.register("exit", Box::new(ExitHandler)); let engine = WorkflowRunEngine::new(registry, Arc::new(emitter), env.clone()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, - run_id, - git_checkpoint_enabled: true, - host_repo_path: Some(dir.path().to_path_buf()), - base_sha: Some(base_sha), - run_branch: Some(branch_name), - meta_branch: None, + run_id: "git-cp-test".into(), labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: Some(dir.path().to_path_buf()), + git: Some(GitCheckpointSettings { + base_sha: Some(base_sha), + run_branch: Some(branch_name), + meta_branch: None, + }), }; - let outcome = engine .run(&graph, &config) .await @@ -771,26 +764,24 @@ async fn daytona_parallel_git_branching_e2e() { let engine = WorkflowRunEngine::new(registry, Arc::new(emitter), Arc::clone(&env)); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: run_tmp.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: run_id.clone(), - git_checkpoint_enabled: true, - host_repo_path: Some(run_tmp.path().to_path_buf()), - base_sha: Some(base_sha), - run_branch: Some(branch_name), - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: Some(run_tmp.path().to_path_buf()), + git: Some(GitCheckpointSettings { + base_sha: Some(base_sha), + run_branch: Some(branch_name), + meta_branch: None, + }), }; - let outcome = engine .run(&graph, &config) .await @@ -1149,26 +1140,24 @@ async fn daytona_git_checkpoint_with_shadow_branch() { let meta_branch = MetadataStore::branch_name(&run_id); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), env.clone()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: run_id.clone(), - git_checkpoint_enabled: true, - host_repo_path: Some(host_repo.path().to_path_buf()), - base_sha: Some(base_sha), - run_branch: Some(branch_name), - meta_branch: Some(meta_branch), labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: Some(host_repo.path().to_path_buf()), + git: Some(GitCheckpointSettings { + base_sha: Some(base_sha), + run_branch: Some(branch_name), + meta_branch: Some(meta_branch), + }), }; - let outcome = engine .run(&graph, &config) .await @@ -1291,26 +1280,25 @@ async fn daytona_asset_collection() { graph.edges.push(Edge::new("start", "create_assets")); graph.edges.push(Edge::new("create_assets", "exit")); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig { + assets: Some(fabro_config::run::AssetsConfig { + include: vec!["test-results/**".to_string()], + }), + ..FabroConfig::default() + }, run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "asset-test-daytona".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: vec!["test-results/**".to_string()], workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; - let outcome = engine .run(&graph, &config) .await @@ -1548,26 +1536,24 @@ async fn daytona_git_push_run_branch_to_origin() { registry.register("exit", Box::new(ExitHandler)); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), env.clone()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: run_id.clone(), - git_checkpoint_enabled: true, - host_repo_path: Some(dir.path().to_path_buf()), - base_sha: Some(base_sha), - run_branch: Some(branch_name.clone()), - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: Some(dir.path().to_path_buf()), + git: Some(GitCheckpointSettings { + base_sha: Some(base_sha), + run_branch: Some(branch_name.clone()), + meta_branch: None, + }), }; - let outcome = engine .run(&graph, &config) .await diff --git a/lib/crates/fabro-workflows/tests/integration.rs b/lib/crates/fabro-workflows/tests/integration.rs index b3fcc4198..58880046f 100644 --- a/lib/crates/fabro-workflows/tests/integration.rs +++ b/lib/crates/fabro-workflows/tests/integration.rs @@ -16,7 +16,7 @@ use fabro_workflows::backend::cli::{parse_cli_response, AgentCliBackend, Backend use fabro_workflows::backend::AgentApiBackend; use fabro_workflows::checkpoint::Checkpoint; use fabro_workflows::context::Context; -use fabro_workflows::engine::{RunConfig, WorkflowRunEngine}; +use fabro_workflows::engine::{GitCheckpointSettings, RunSettings, WorkflowRunEngine}; use fabro_workflows::error::FabroError; use fabro_workflows::event::{EventEmitter, WorkflowRunEvent}; use fabro_workflows::handler::agent::{AgentHandler, CodergenBackend, CodergenResult}; @@ -192,26 +192,20 @@ async fn end_to_end_linear_pipeline() { Arc::new(EventEmitter::new()), local_env(), ); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; - let outcome = engine .run(&graph, &config) .await @@ -337,26 +331,20 @@ async fn end_to_end_branching_pipeline() { registry.register("conditional", Box::new(ConditionalHandler)); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; - let outcome = engine .run(&graph, &config) .await @@ -463,26 +451,20 @@ async fn end_to_end_human_gate_pipeline() { registry.register("human", Box::new(HumanHandler::new(interviewer))); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; - let outcome = engine .run(&graph, &config) .await @@ -565,26 +547,20 @@ async fn human_gate_aborted_input_fails_closed_without_fail_route() { registry.register("human", Box::new(HumanHandler::new(interviewer))); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; - let outcome = engine .run(&graph, &config) .await @@ -682,26 +658,20 @@ async fn human_gate_aborted_input_routes_via_outcome_fail_condition() { registry.register("human", Box::new(HumanHandler::new(interviewer))); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; - let outcome = engine .run(&graph, &config) .await @@ -801,26 +771,20 @@ async fn goal_gate_routes_to_retry_target_on_failure() { registry.register("always_fail", Box::new(AlwaysFailHandler)); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; - let result = engine.run(&graph, &config).await; assert!( result.is_ok(), @@ -928,26 +892,20 @@ async fn goal_gate_routes_to_retry_target_when_present() { ); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; - let outcome = engine .run(&graph, &config) .await @@ -1246,26 +1204,20 @@ async fn retry_on_failure_then_succeed() { ); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; - let outcome = engine .run(&graph, &config) .await @@ -1327,26 +1279,20 @@ async fn pipeline_with_many_nodes() { Arc::new(EventEmitter::new()), local_env(), ); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; - let outcome = engine .run(&graph, &config) .await @@ -1655,26 +1601,20 @@ async fn smoke_test_with_mock_codergen_backend() { registry.register("conditional", Box::new(ConditionalHandler)); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; - let outcome = engine .run(&graph, &config) .await @@ -1762,26 +1702,20 @@ async fn end_to_end_parallel_fan_out_fan_in() { ); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; - let outcome = engine .run(&graph, &config) .await @@ -1881,26 +1815,20 @@ async fn resume_from_checkpoint_completes_pipeline() { registry.register("exit", Box::new(ExitHandler)); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; - let outcome = engine .run_from_checkpoint(&graph, &config, &checkpoint) .await @@ -1986,26 +1914,20 @@ async fn resume_from_checkpoint_preserves_goal_gate_outcomes() { registry.register("exit", Box::new(ExitHandler)); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; - // This should succeed because goal gate for gated_work is satisfied // via restored outcomes let outcome = engine @@ -2035,24 +1957,19 @@ async fn graph_goal_in_context() { Arc::new(EventEmitter::new()), local_env(), ); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; engine.run(&graph, &config).await.expect("run"); @@ -2076,24 +1993,19 @@ async fn event_streaming_lifecycle() { let emitter = EventEmitter::new(); let events = collect_events(&emitter); let engine = WorkflowRunEngine::new(make_linear_registry(), Arc::new(emitter), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; engine.run(&graph, &config).await.expect("run"); @@ -2161,24 +2073,19 @@ async fn context_flow_between_stages() { Arc::new(EventEmitter::new()), local_env(), ); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; engine.run(&graph, &config).await.expect("run"); @@ -2219,24 +2126,19 @@ async fn tool_handler_e2e() { Arc::new(EventEmitter::new()), local_env(), ); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; let outcome = engine.run(&graph, &config).await.expect("run"); assert_eq!(outcome.status, StageStatus::Success); @@ -2294,24 +2196,19 @@ async fn auto_approve_interviewer_e2e() { Arc::new(EventEmitter::new()), local_env(), ); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; let outcome = engine.run(&graph, &config).await.expect("run"); assert_eq!(outcome.status, StageStatus::Success); @@ -2336,24 +2233,19 @@ async fn codergen_without_backend_simulated() { Arc::new(EventEmitter::new()), local_env(), ); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; engine.run(&graph, &config).await.expect("run"); @@ -2446,24 +2338,19 @@ async fn branching_loop_back_on_failure() { }), ); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; let outcome = engine.run(&graph, &config).await.expect("run"); assert_eq!(outcome.status, StageStatus::Success); @@ -2534,24 +2421,19 @@ async fn human_gate_loops_back() { registry.register("exit", Box::new(ExitHandler)); registry.register("human", Box::new(HumanHandler::new(interviewer))); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; let outcome = engine.run(&graph, &config).await.expect("run"); assert_eq!(outcome.status, StageStatus::Success); @@ -2597,24 +2479,19 @@ async fn scenario_ship_a_feature() { Arc::new(emitter), local_env(), ); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; let outcome = engine.run(&graph, &config).await.expect("run"); assert_eq!(outcome.status, StageStatus::Success); @@ -2688,24 +2565,19 @@ async fn scenario_parallel_expert_review() { registry.register("human", Box::new(HumanHandler::new(interviewer))); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; let outcome = engine.run(&graph, &config).await.expect("run"); assert_eq!(outcome.status, StageStatus::Success); @@ -2777,24 +2649,19 @@ async fn scenario_node_retries_on_retry_status() { }), ); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; let outcome = engine.run(&graph, &config).await.expect("run"); assert_eq!(outcome.status, StageStatus::Success); @@ -2844,24 +2711,19 @@ async fn scenario_loop_restart_resets_context() { }), ); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; let outcome = engine.run(&graph, &config).await.expect("run"); assert_eq!(outcome.status, StageStatus::Success); @@ -2917,24 +2779,19 @@ async fn scenario_bug_triage_router() { registry.register("exit", Box::new(ExitHandler)); registry.register("conditional", Box::new(ConditionalHandler)); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; let outcome = engine.run(&graph, &config).await.expect("run"); assert_eq!(outcome.status, StageStatus::Success); @@ -2981,24 +2838,19 @@ async fn scenario_crash_recovery() { registry.register("start", Box::new(StartHandler)); registry.register("exit", Box::new(ExitHandler)); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; let outcome = engine .run_from_checkpoint(&graph, &config, &checkpoint) @@ -3095,24 +2947,19 @@ async fn manager_loop_stop_condition_satisfied_e2e() { registry.register("done_setter", Box::new(DoneSetterHandler)); registry.register("stack.manager_loop", Box::new(SubWorkflowHandler)); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; let outcome = engine.run(&graph, &config).await.expect("run"); @@ -3177,24 +3024,19 @@ async fn manager_loop_max_cycles_exceeded_e2e() { registry.register("exit", Box::new(ExitHandler)); registry.register("stack.manager_loop", Box::new(SubWorkflowHandler)); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; let outcome = engine.run(&graph, &config).await.expect("run"); @@ -3318,24 +3160,19 @@ async fn conditional_branching_success_fail_paths() { registry.register("exit", Box::new(ExitHandler)); registry.register("always_fail", Box::new(AlwaysFailHandler)); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; let outcome = engine.run(&graph, &config).await.expect("run"); assert_eq!(outcome.status, StageStatus::Success); @@ -3376,24 +3213,19 @@ async fn edge_selection_condition_match_wins_over_weight() { registry.register("start", Box::new(StartHandler)); registry.register("exit", Box::new(ExitHandler)); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; engine.run(&graph, &config).await.expect("run"); @@ -3428,24 +3260,19 @@ async fn edge_selection_weight_breaks_ties() { registry.register("start", Box::new(StartHandler)); registry.register("exit", Box::new(ExitHandler)); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; engine.run(&graph, &config).await.expect("run"); @@ -3472,24 +3299,19 @@ async fn edge_selection_lexical_tiebreak() { registry.register("start", Box::new(StartHandler)); registry.register("exit", Box::new(ExitHandler)); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; engine.run(&graph, &config).await.expect("run"); @@ -3535,24 +3357,19 @@ async fn context_updates_visible_across_nodes() { registry.register("conditional", Box::new(ConditionalHandler)); registry.register("context_setter", Box::new(ContextSetterHandler)); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; engine.run(&graph, &config).await.expect("run"); @@ -3584,24 +3401,19 @@ async fn stylesheet_applies_model_override() { Arc::new(EventEmitter::new()), local_env(), ); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; let outcome = engine.run(&graph, &config).await.expect("run"); assert_eq!(outcome.status, StageStatus::Success); @@ -3645,24 +3457,19 @@ async fn custom_handler_registration_and_execution() { registry.register("exit", Box::new(ExitHandler)); registry.register("my_custom", Box::new(CustomHandler)); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; engine.run(&graph, &config).await.expect("run"); @@ -3721,24 +3528,19 @@ async fn integration_smoke_plan_implement_review_done() { Arc::new(emitter), local_env(), ); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; let outcome = engine.run(&graph, &config).await.expect("run"); assert_eq!(outcome.status, StageStatus::Success); @@ -3830,26 +3632,20 @@ async fn manager_loop_runs_child_engine_e2e() { registry.register("stack.manager_loop", Box::new(SubWorkflowHandler)); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; - let outcome = engine .run(&graph, &config) .await @@ -3970,26 +3766,20 @@ async fn manager_loop_context_flows_e2e() { registry.register("stack.manager_loop", Box::new(SubWorkflowHandler)); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; - let outcome = engine.run(&graph, &config).await.expect("run"); assert_eq!(outcome.status, StageStatus::Success); @@ -4049,26 +3839,20 @@ async fn manager_loop_child_dotfile_e2e() { registry.register("stack.manager_loop", Box::new(SubWorkflowHandler)); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; - let outcome = engine.run(&graph, &config).await.expect("run"); assert_eq!(outcome.status, StageStatus::Success); } @@ -4168,26 +3952,20 @@ async fn graph_merge_e2e_through_engine() { Arc::new(EventEmitter::new()), local_env(), ); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; - let outcome = engine .run(&main_graph, &config) .await @@ -4324,24 +4102,19 @@ async fn fidelity_default_is_compact() { ); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; engine.run(&graph, &config).await.expect("run"); @@ -4386,24 +4159,19 @@ async fn fidelity_graph_default_applied() { ); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; engine.run(&graph, &config).await.expect("run"); @@ -4444,24 +4212,19 @@ async fn fidelity_node_overrides_graph_default() { ); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; engine.run(&graph, &config).await.expect("run"); @@ -4508,24 +4271,19 @@ async fn fidelity_edge_overrides_node_and_graph() { ); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; engine.run(&graph, &config).await.expect("run"); @@ -4562,24 +4320,19 @@ async fn fidelity_full_produces_empty_preamble() { ); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; engine.run(&graph, &config).await.expect("run"); @@ -4626,24 +4379,19 @@ async fn fidelity_truncate_preamble_minimal() { ); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; engine.run(&graph, &config).await.expect("run"); @@ -4703,24 +4451,19 @@ async fn fidelity_summary_low_mode() { ); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; engine.run(&graph, &config).await.expect("run"); @@ -4775,24 +4518,19 @@ async fn fidelity_summary_medium_mode() { ); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; engine.run(&graph, &config).await.expect("run"); @@ -4847,24 +4585,19 @@ async fn fidelity_summary_high_mode() { ); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; engine.run(&graph, &config).await.expect("run"); @@ -4912,24 +4645,19 @@ async fn fidelity_full_sets_thread_id_in_context() { ); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; engine.run(&graph, &config).await.expect("run"); @@ -4988,24 +4716,19 @@ async fn fidelity_full_nodes_share_thread_id() { ); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; engine.run(&graph, &config).await.expect("run"); @@ -5074,24 +4797,19 @@ async fn fidelity_resume_degrades_full_to_summary_high() { ); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; engine .run_from_checkpoint(&graph, &config, &checkpoint) @@ -5176,24 +4894,19 @@ async fn fidelity_resume_degrade_only_affects_first_hop() { ); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; engine .run_from_checkpoint(&graph, &config, &checkpoint) @@ -5265,24 +4978,19 @@ async fn fidelity_resume_no_degrade_when_not_full() { ); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; engine .run_from_checkpoint(&graph, &config, &checkpoint) @@ -5312,24 +5020,19 @@ async fn fidelity_stored_in_checkpoint_context() { registry.register("exit", Box::new(ExitHandler)); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; engine.run(&graph, &config).await.expect("run"); @@ -5403,24 +5106,19 @@ async fn fidelity_precedence_multi_node_pipeline() { ); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; engine.run(&graph, &config).await.expect("run"); @@ -5476,24 +5174,19 @@ async fn fidelity_compact_preamble_includes_completed_stages_and_context() { ); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; engine.run(&graph, &config).await.expect("run"); @@ -5557,24 +5250,19 @@ async fn fidelity_summary_low_excludes_context_values_in_pipeline() { ); let engine_low = WorkflowRunEngine::new(registry_low, Arc::new(EventEmitter::new()), local_env()); - let config_low = RunConfig { + let config_low = RunSettings { + config: FabroConfig::default(), run_dir: dir_low.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; engine_low .run(&graph_low, &config_low) @@ -5630,24 +5318,19 @@ async fn fidelity_summary_low_excludes_context_values_in_pipeline() { ); let engine_med = WorkflowRunEngine::new(registry_med, Arc::new(EventEmitter::new()), local_env()); - let config_med = RunConfig { + let config_med = RunSettings { + config: FabroConfig::default(), run_dir: dir_med.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; engine_med .run(&graph_med, &config_med) @@ -5706,24 +5389,19 @@ async fn fidelity_thread_id_fallback_to_previous_node_in_pipeline() { ); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; engine.run(&graph, &config).await.expect("run"); @@ -5765,24 +5443,19 @@ async fn fidelity_thread_id_from_node_class_in_pipeline() { ); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; engine.run(&graph, &config).await.expect("run"); @@ -5827,24 +5500,19 @@ async fn fidelity_edge_thread_id_override_in_pipeline() { ); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; engine.run(&graph, &config).await.expect("run"); @@ -5890,24 +5558,19 @@ async fn fidelity_full_without_explicit_thread_id_uses_previous_node() { ); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; engine.run(&graph, &config).await.expect("run"); @@ -5963,24 +5626,19 @@ async fn fidelity_from_parsed_dot_pipeline() { ); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; engine.run(&graph, &config).await.expect("run"); @@ -6016,24 +5674,19 @@ async fn fidelity_checkpoint_roundtrip_preserves_fidelity() { registry.register("exit", Box::new(ExitHandler)); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; engine.run(&graph, &config).await.expect("run"); @@ -6091,24 +5744,19 @@ async fn fidelity_node_thread_id_overrides_edge_thread_id_in_pipeline() { ); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; engine.run(&graph, &config).await.expect("run"); @@ -6183,24 +5831,19 @@ async fn fidelity_resume_preserves_context_values_across_checkpoint() { ); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; engine .run_from_checkpoint(&graph, &config, &checkpoint) @@ -6231,6 +5874,7 @@ mod real_llm { use async_trait::async_trait; + use fabro_config::FabroConfig; use fabro_graphviz::graph::Node; use fabro_workflows::context::Context; use fabro_workflows::error::FabroError; @@ -6325,7 +5969,7 @@ mod real_llm { use fabro_graphviz::graph::{AttrValue, Edge, Graph}; use fabro_interview::AutoApproveInterviewer; use fabro_workflows::checkpoint::Checkpoint; - use fabro_workflows::engine::{RunConfig, WorkflowRunEngine}; + use fabro_workflows::engine::{RunSettings, WorkflowRunEngine}; use fabro_workflows::event::EventEmitter; use fabro_workflows::handler::exit::ExitHandler; use fabro_workflows::handler::human::HumanHandler; @@ -6401,26 +6045,20 @@ mod real_llm { ); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; - let outcome = tokio::time::timeout( std::time::Duration::from_secs(120), engine.run(&graph, &config), @@ -6521,26 +6159,20 @@ mod real_llm { ); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; - let outcome = tokio::time::timeout( std::time::Duration::from_secs(120), engine.run(&graph, &config), @@ -6666,26 +6298,20 @@ mod real_llm { registry.register("human", Box::new(HumanHandler::new(interviewer))); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; - let outcome = tokio::time::timeout( std::time::Duration::from_secs(120), engine.run(&graph, &config), @@ -6779,26 +6405,20 @@ mod real_llm { ); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; - let outcome = tokio::time::timeout( std::time::Duration::from_secs(30), engine.run(&graph, &config), @@ -6881,26 +6501,20 @@ async fn human_gate_freeform_only_routes_text() { registry.register("human", Box::new(HumanHandler::new(interviewer))); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; - let outcome = engine .run(&graph, &config) .await @@ -7017,26 +6631,20 @@ async fn human_gate_freeform_with_fixed_choice_match() { registry.register("human", Box::new(HumanHandler::new(interviewer))); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; - let outcome = engine .run(&graph, &config) .await @@ -7138,26 +6746,20 @@ async fn human_gate_freeform_fallback_on_unmatched_text() { registry.register("human", Box::new(HumanHandler::new(interviewer))); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; - let outcome = engine .run(&graph, &config) .await @@ -7272,26 +6874,20 @@ async fn human_gate_freeform_sets_allow_freeform_on_question() { registry.register("human", Box::new(HumanHandler::new(interviewer))); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; - let outcome = engine .run(&graph, &config) .await @@ -7386,26 +6982,20 @@ async fn human_gate_without_freeform_sets_allow_freeform_false() { registry.register("human", Box::new(HumanHandler::new(interviewer))); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; - let outcome = engine .run(&graph, &config) .await @@ -7651,25 +7241,20 @@ fn engine_with_hooks_and_events( (engine, events) } -fn make_run_config(dir: &std::path::Path) -> RunConfig { - RunConfig { +fn make_run_config(dir: &std::path::Path) -> RunSettings { + RunSettings { + config: FabroConfig::default(), run_dir: dir.to_path_buf(), cancel_token: None, dry_run: false, run_id: "hook-test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, } } @@ -8761,26 +8346,20 @@ async fn arc_e2e_with_real_llm() { let run_dir = tempfile::tempdir().unwrap(); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: run_dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; - let outcome = engine .run(&graph, &config) .await @@ -8895,26 +8474,20 @@ async fn run_fidelity_prompt_pipeline(fidelity: &str) -> String { ); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; - engine .run(&graph, &config) .await @@ -9100,26 +8673,20 @@ async fn large_context_values_are_offloaded_to_artifact_store() { let emitter = EventEmitter::new(); let events = collect_events(&emitter); let engine = WorkflowRunEngine::new(registry, Arc::new(emitter), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; - let outcome = engine .run(&graph, &config) .await @@ -9326,26 +8893,20 @@ async fn artifact_pointers_rewritten_for_remote_sandbox() { let remote_env = Arc::new(RemoteMockEnv::new("/sandbox")); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), remote_env.clone()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; - let outcome = engine .run(&graph, &config) .await @@ -9462,26 +9023,20 @@ async fn node_dir_uses_visit_count_on_revisit() { ); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; - let outcome = engine .run(&graph, &config) .await @@ -10440,26 +9995,20 @@ async fn full_pipeline_with_cli_backend_node() { let dir = tempfile::tempdir().unwrap(); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), env); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; - let outcome = engine .run(&graph, &config) .await @@ -10577,26 +10126,20 @@ async fn stylesheet_backend_property_routes_to_cli() { let dir = tempfile::tempdir().unwrap(); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), env); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; - let outcome = engine .run(&graph, &config) .await @@ -10862,26 +10405,24 @@ async fn git_checkpoint_host_emits_events_and_diff_patch() { registry.register("exit", Box::new(ExitHandler)); let engine = WorkflowRunEngine::new(registry, Arc::new(emitter), env); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: run_dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-docker".into(), - git_checkpoint_enabled: true, - host_repo_path: Some(worktree_path.clone()), - base_sha: Some(base_sha.clone()), - run_branch: Some("fabro/run/test-docker".to_string()), - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: Some(worktree_path.clone()), + git: Some(GitCheckpointSettings { + base_sha: Some(base_sha.clone()), + run_branch: Some("fabro/run/test-docker".to_string()), + meta_branch: None, + }), }; - // 5. Run pipeline let outcome = engine .run(&graph, &config) @@ -11067,26 +10608,24 @@ async fn git_checkpoint_host_writes_shadow_branch() { let engine = WorkflowRunEngine::new(registry, Arc::new(emitter), env); let meta_branch = MetadataStore::branch_name(run_id); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: run_dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: run_id.into(), - git_checkpoint_enabled: true, - host_repo_path: Some(worktree_path.clone()), - base_sha: Some(base_sha), - run_branch: Some(format!("fabro/run/{run_id}")), - meta_branch: Some(meta_branch), labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: Some(worktree_path.clone()), + git: Some(GitCheckpointSettings { + base_sha: Some(base_sha), + run_branch: Some(format!("fabro/run/{run_id}")), + meta_branch: Some(meta_branch), + }), }; - // 5. Run pipeline let outcome = engine .run(&graph, &config) @@ -11267,26 +10806,24 @@ async fn parallel_git_branching_host_e2e() { let engine = WorkflowRunEngine::new(registry, Arc::new(emitter), env); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: run_dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: run_id.into(), - git_checkpoint_enabled: true, - host_repo_path: Some(worktree_path.clone()), - base_sha: Some(base_sha.clone()), - run_branch: Some(run_branch.clone()), - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: Some(worktree_path.clone()), + git: Some(GitCheckpointSettings { + base_sha: Some(base_sha.clone()), + run_branch: Some(run_branch.clone()), + meta_branch: None, + }), }; - // 5. Run pipeline let outcome = engine .run(&graph, &config) @@ -11532,26 +11069,24 @@ async fn git_checkpoint_host_skips_empty_diff_patch() { registry.register("exit", Box::new(ExitHandler)); let engine = WorkflowRunEngine::new(registry, Arc::new(emitter), env); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: run_dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "empty-diff".into(), - git_checkpoint_enabled: true, - host_repo_path: Some(worktree_path.clone()), - base_sha: Some(base_sha.clone()), - run_branch: Some("fabro/run/empty-diff".to_string()), - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: Some(worktree_path.clone()), + git: Some(GitCheckpointSettings { + base_sha: Some(base_sha.clone()), + run_branch: Some("fabro/run/empty-diff".to_string()), + meta_branch: None, + }), }; - let outcome = engine .run(&graph, &config) .await @@ -11916,26 +11451,20 @@ async fn e2e_circuit_breaker_deterministic_self_loop() { ); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "e2e-circuit-breaker".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; - let result = engine.run(&graph, &config).await; assert!(result.is_err(), "pipeline should abort, not loop forever"); let err = result.unwrap_err().to_string(); @@ -11969,26 +11498,20 @@ async fn e2e_circuit_breaker_custom_limit() { ); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "e2e-custom-limit".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; - let result = engine.run(&graph, &config).await; assert!(result.is_err()); let err = result.unwrap_err().to_string(); @@ -12015,26 +11538,20 @@ async fn e2e_circuit_breaker_ignores_transient_failures() { registry.register("test_handler", Box::new(TransientInfraFailHandler)); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "e2e-transient-no-breaker".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; - let result = engine.run(&graph, &config).await; assert!(result.is_err()); let err = result.unwrap_err().to_string(); @@ -12068,26 +11585,20 @@ async fn e2e_circuit_breaker_different_reasons_separate_counters() { ); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "e2e-varying-reasons".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; - let result = engine.run(&graph, &config).await; assert!(result.is_err()); let err = result.unwrap_err().to_string(); @@ -12114,26 +11625,20 @@ async fn e2e_circuit_breaker_loop_restart() { ); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "e2e-restart-breaker".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; - let result = engine.run(&graph, &config).await; assert!( result.is_err(), @@ -12182,26 +11687,20 @@ async fn e2e_failure_signature_persisted_in_context() { ); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "e2e-sig-context".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; - let outcome = engine.run(&graph, &config).await.unwrap(); // Pipeline reaches exit (terminal) with goal gates satisfied. // Per spec, reaching exit with satisfied goal gates returns SUCCESS. @@ -12252,26 +11751,20 @@ async fn e2e_failure_signature_hint_overrides_reason_in_context() { registry.register("hint_handler", Box::new(SignatureHintHandler)); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "e2e-sig-hint".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; - let _outcome = engine.run(&graph, &config).await.unwrap(); let cp = Checkpoint::load(&dir.path().join("checkpoint.json")).unwrap(); @@ -12314,26 +11807,20 @@ async fn e2e_signature_maps_persist_in_checkpoint() { ); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "e2e-sig-persist".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; - let outcome = engine.run(&graph, &config).await.unwrap(); assert_eq!(outcome.status, StageStatus::Success); @@ -12447,26 +11934,20 @@ async fn e2e_circuit_breaker_emits_events_before_abort() { ); let engine = WorkflowRunEngine::new(registry, Arc::new(emitter), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "e2e-events".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; - let result = engine.run(&graph, &config).await; assert!(result.is_err()); @@ -12520,26 +12001,20 @@ async fn e2e_circuit_breaker_does_not_fire_below_limit() { ); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "e2e-below-limit".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; - let outcome = engine.run(&graph, &config).await.unwrap(); assert_eq!( outcome.status, @@ -12622,26 +12097,20 @@ async fn e2e_circuit_breaker_multi_stage_impl_verify_cycle() { ); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "e2e-impl-verify-cycle".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; - let result = engine.run(&graph, &config).await; assert!( result.is_err(), @@ -12725,26 +12194,20 @@ async fn e2e_loop_restart_blocked_for_deterministic_failure() { ); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "e2e-restart-blocked-det".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; - let result = engine.run(&graph, &config).await; assert!( result.is_err(), @@ -12771,26 +12234,20 @@ async fn e2e_loop_restart_blocked_for_structural_failure() { ); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "e2e-restart-blocked-struct".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; - let result = engine.run(&graph, &config).await; assert!( result.is_err(), @@ -12817,26 +12274,20 @@ async fn e2e_loop_restart_blocked_for_budget_exhausted_failure() { ); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "e2e-restart-blocked-budget".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; - let result = engine.run(&graph, &config).await; assert!( result.is_err(), @@ -12863,26 +12314,20 @@ async fn e2e_loop_restart_blocked_for_canceled_failure() { ); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "e2e-restart-blocked-canceled".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; - let result = engine.run(&graph, &config).await; assert!(result.is_err(), "canceled failure should not loop_restart"); let err = result.unwrap_err().to_string(); @@ -12906,26 +12351,20 @@ async fn e2e_loop_restart_blocked_for_compilation_loop_failure() { ); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "e2e-restart-blocked-comploop".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; - let result = engine.run(&graph, &config).await; assert!( result.is_err(), @@ -12953,26 +12392,20 @@ async fn e2e_loop_restart_allowed_for_transient_infra() { ); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "e2e-restart-allowed-transient".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; - let result = engine.run(&graph, &config).await; assert!( result.is_ok(), @@ -13063,26 +12496,20 @@ async fn e2e_stall_watchdog_triggers_from_dot_parsed_pipeline() { }); let engine = WorkflowRunEngine::new(registry, Arc::new(emitter), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "stall-e2e".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; - let result = engine.run(&graph, &config).await; assert!(result.is_err(), "expected stall watchdog error"); let err = result.unwrap_err().to_string(); @@ -13125,26 +12552,20 @@ async fn e2e_stall_watchdog_kept_alive_by_handler_events() { ); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "stall-alive-e2e".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; - let outcome = engine .run(&graph, &config) .await @@ -13177,26 +12598,20 @@ async fn e2e_stall_watchdog_disabled_with_zero_timeout() { registry.register("slow", Box::new(SlowTestHandler { sleep_ms: 50 })); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "stall-disabled-e2e".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; - let outcome = engine .run(&graph, &config) .await @@ -13248,26 +12663,20 @@ async fn e2e_stall_watchdog_with_explicit_timeout_override() { registry.register("hanging", Box::new(HangingHandler)); let engine = WorkflowRunEngine::new(registry, Arc::new(EventEmitter::new()), local_env()); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "stall-override-e2e".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; - let start = std::time::Instant::now(); let result = engine.run(&graph, &config).await; let elapsed = start.elapsed(); @@ -13385,26 +12794,25 @@ async fn asset_collection_local_sandbox_success() { graph.edges.push(Edge::new("start", "create_assets")); graph.edges.push(Edge::new("create_assets", "exit")); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig { + assets: Some(fabro_config::run::AssetsConfig { + include: vec!["test-results/**".to_string()], + }), + ..FabroConfig::default() + }, run_dir: run_dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "asset-test-local".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: vec!["test-results/**".to_string()], workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; - let outcome = engine .run(&graph, &config) .await @@ -13500,26 +12908,25 @@ async fn asset_collection_local_sandbox_on_failure() { graph.edges.push(Edge::new("start", "create_assets")); graph.edges.push(Edge::new("create_assets", "exit")); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig { + assets: Some(fabro_config::run::AssetsConfig { + include: vec!["test-results/**".to_string()], + }), + ..FabroConfig::default() + }, run_dir: run_dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "asset-test-fail".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: vec!["test-results/**".to_string()], workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; - let outcome = engine .run(&graph, &config) .await @@ -13598,26 +13005,25 @@ async fn asset_collection_docker_sandbox() { graph.edges.push(Edge::new("start", "create_assets")); graph.edges.push(Edge::new("create_assets", "exit")); - let run_config = RunConfig { + let run_config = RunSettings { + config: FabroConfig { + assets: Some(fabro_config::run::AssetsConfig { + include: vec!["test-results/**".to_string()], + }), + ..FabroConfig::default() + }, run_dir: run_dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "asset-test-docker".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: vec!["test-results/**".to_string()], workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; - let outcome = engine .run(&graph, &run_config) .await @@ -13673,24 +13079,19 @@ async fn wait_timer_e2e() { Arc::new(EventEmitter::new()), local_env(), ); - let config = RunConfig { + let config = RunSettings { + config: FabroConfig::default(), run_dir: dir.path().to_path_buf(), cancel_token: None, dry_run: false, run_id: "test-run".into(), - git_checkpoint_enabled: false, - host_repo_path: None, - base_sha: None, - run_branch: None, - meta_branch: None, labels: std::collections::HashMap::new(), - checkpoint_exclude_globs: Vec::new(), - github_app: None, git_author: fabro_workflows::git::GitAuthor::default(), - base_branch: None, - pull_request: None, - asset_globs: Vec::new(), workflow_slug: None, + github_app: None, + base_branch: None, + host_repo_path: None, + git: None, }; let outcome = engine.run(&graph, &config).await.expect("run"); assert_eq!(outcome.status, StageStatus::Success);