mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-09-05 08:10:39 +00:00
refactor: rename local variables/fields to align with Options suffix
Follow-up to fafc0a3c. Renames local variables, function parameters,
and struct fields that hold renamed types (ExecutorOptions, RunCreateOptions,
RunOptions) from config/settings to options/run_options for consistency.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
fafc0a3c39
commit
e6e913eabc
20 changed files with 505 additions and 478 deletions
|
|
@ -653,7 +653,7 @@ async fn execute_run(state: Arc<AppState>, run_id: String) {
|
|||
}
|
||||
};
|
||||
let run_record = persisted.run_record().clone();
|
||||
let config = RunOptions {
|
||||
let run_options = RunOptions {
|
||||
config: run_record.config,
|
||||
run_dir: run_dir.clone(),
|
||||
cancel_token: Some(cancel_token),
|
||||
|
|
@ -673,7 +673,7 @@ async fn execute_run(state: Arc<AppState>, run_id: String) {
|
|||
let sandbox = Arc::clone(&sandbox);
|
||||
let registry = Arc::new(registry);
|
||||
let run_id = run_id.clone();
|
||||
let config = config.clone();
|
||||
let run_options = run_options.clone();
|
||||
let hooks = state.hooks.clone();
|
||||
let dry_run = state.dry_run;
|
||||
async move {
|
||||
|
|
@ -690,7 +690,7 @@ async fn execute_run(state: Arc<AppState>, run_id: String) {
|
|||
setup_command_timeout_ms: 300_000,
|
||||
devcontainer_phases: Vec::new(),
|
||||
},
|
||||
run_options: config,
|
||||
run_options,
|
||||
hooks: fabro_hooks::HookConfig { hooks },
|
||||
sandbox_env: HashMap::new(),
|
||||
checkpoint: None,
|
||||
|
|
@ -719,13 +719,13 @@ async fn execute_run(state: Arc<AppState>, run_id: String) {
|
|||
};
|
||||
|
||||
// Save final checkpoint
|
||||
let checkpoint = Checkpoint::load(&config.run_dir.join("checkpoint.json")).ok();
|
||||
let checkpoint = Checkpoint::load(&run_options.run_dir.join("checkpoint.json")).ok();
|
||||
|
||||
// Auto-derive retro and accumulate aggregate usage
|
||||
if let Some(ref cp) = checkpoint {
|
||||
let failed = result.is_err();
|
||||
let completed_stages = fabro_workflows::build_completed_stages(cp, failed);
|
||||
let stage_durations = fabro_retro::retro::extract_stage_durations(&config.run_dir);
|
||||
let stage_durations = fabro_retro::retro::extract_stage_durations(&run_options.run_dir);
|
||||
let retro = fabro_retro::retro::derive_retro(
|
||||
&run_id,
|
||||
"workflow",
|
||||
|
|
@ -734,7 +734,7 @@ async fn execute_run(state: Arc<AppState>, run_id: String) {
|
|||
0,
|
||||
&stage_durations,
|
||||
);
|
||||
let _ = retro.save(&config.run_dir);
|
||||
let _ = retro.save(&run_options.run_dir);
|
||||
|
||||
// Accumulate aggregate usage
|
||||
let mut agg = state
|
||||
|
|
@ -778,7 +778,7 @@ async fn execute_run(state: Arc<AppState>, run_id: String) {
|
|||
if let Some(ctx) = final_context {
|
||||
managed_run.context = Some(ctx);
|
||||
}
|
||||
managed_run.run_dir = Some(config.run_dir.clone());
|
||||
managed_run.run_dir = Some(run_options.run_dir.clone());
|
||||
managed_run.event_tx = None;
|
||||
}
|
||||
drop(runs);
|
||||
|
|
|
|||
|
|
@ -107,7 +107,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<EventEmitter>,
|
||||
settings: RunOptions,
|
||||
run_options: RunOptions,
|
||||
setup_commands: Vec<String>,
|
||||
/// Devcontainer lifecycle phases (on_create, post_create, post_start) resolved from config.
|
||||
devcontainer_phases: Vec<(String, Vec<fabro_devcontainer::Command>)>,
|
||||
|
|
@ -459,7 +459,7 @@ async fn prepare_from_checkpoint(
|
|||
};
|
||||
let sandbox: Arc<dyn Sandbox> = Arc::new(fabro_agent::ReadBeforeWriteSandbox::new(sandbox));
|
||||
|
||||
let settings = RunOptions {
|
||||
let run_options = RunOptions {
|
||||
config: settings_config,
|
||||
run_dir: run_dir.clone(),
|
||||
cancel_token: None,
|
||||
|
|
@ -497,7 +497,7 @@ async fn prepare_from_checkpoint(
|
|||
run_cfg,
|
||||
sandbox,
|
||||
emitter,
|
||||
settings,
|
||||
run_options,
|
||||
setup_commands,
|
||||
devcontainer_phases,
|
||||
devcontainer_env,
|
||||
|
|
@ -940,7 +940,7 @@ async fn prepare_from_branch(
|
|||
.unwrap_or_default();
|
||||
setup_commands.extend(sandbox.resume_setup_commands(&run_branch));
|
||||
|
||||
let settings = RunOptions {
|
||||
let run_options = RunOptions {
|
||||
config: settings_config,
|
||||
run_dir: run_dir.clone(),
|
||||
cancel_token: None,
|
||||
|
|
@ -981,7 +981,7 @@ async fn prepare_from_branch(
|
|||
run_cfg,
|
||||
sandbox,
|
||||
emitter,
|
||||
settings,
|
||||
run_options,
|
||||
setup_commands,
|
||||
devcontainer_phases,
|
||||
devcontainer_env,
|
||||
|
|
@ -1009,7 +1009,7 @@ async fn run_resumed(
|
|||
mut run_cfg,
|
||||
sandbox,
|
||||
emitter,
|
||||
mut settings,
|
||||
mut run_options,
|
||||
setup_commands,
|
||||
devcontainer_phases,
|
||||
devcontainer_env,
|
||||
|
|
@ -1195,7 +1195,7 @@ async fn run_resumed(
|
|||
}
|
||||
}
|
||||
};
|
||||
settings.dry_run = dry_run_mode;
|
||||
run_options.dry_run = dry_run_mode;
|
||||
|
||||
if let Some(ref mut cfg) = run_cfg {
|
||||
run_config::resolve_sandbox_env(cfg)?;
|
||||
|
|
@ -1314,7 +1314,7 @@ async fn run_resumed(
|
|||
let pr_config = if dry_run_mode {
|
||||
None
|
||||
} else {
|
||||
settings.pull_request().cloned()
|
||||
run_options.pull_request().cloned()
|
||||
};
|
||||
let started = start(
|
||||
persisted,
|
||||
|
|
@ -1326,7 +1326,7 @@ async fn run_resumed(
|
|||
sandbox: Arc::clone(&sandbox),
|
||||
registry: Arc::new(registry),
|
||||
lifecycle,
|
||||
run_options: settings,
|
||||
run_options,
|
||||
hooks: fabro_hooks::HookConfig {
|
||||
hooks: run_cfg
|
||||
.as_ref()
|
||||
|
|
|
|||
|
|
@ -1645,7 +1645,7 @@ async fn run_command_impl(
|
|||
None
|
||||
};
|
||||
|
||||
let config = RunOptions {
|
||||
let run_options = RunOptions {
|
||||
config: settings_config,
|
||||
run_dir: run_dir.clone(),
|
||||
cancel_token: None,
|
||||
|
|
@ -1691,7 +1691,7 @@ async fn run_command_impl(
|
|||
let pr_config = if dry_run_mode {
|
||||
None
|
||||
} else {
|
||||
config.pull_request().cloned()
|
||||
run_options.pull_request().cloned()
|
||||
};
|
||||
let started = start(
|
||||
persisted,
|
||||
|
|
@ -1703,7 +1703,7 @@ async fn run_command_impl(
|
|||
sandbox: Arc::clone(&sandbox),
|
||||
registry: Arc::new(registry),
|
||||
lifecycle,
|
||||
run_options: config,
|
||||
run_options,
|
||||
hooks: fabro_hooks::HookConfig {
|
||||
hooks: run_cfg
|
||||
.as_ref()
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ pub struct ExecutorOptions {
|
|||
pub struct Executor<G: Graph> {
|
||||
handler: Arc<dyn NodeHandler<G>>,
|
||||
lifecycle: Box<dyn RunLifecycle<G>>,
|
||||
settings: ExecutorOptions,
|
||||
options: ExecutorOptions,
|
||||
}
|
||||
|
||||
enum NextStep {
|
||||
|
|
@ -38,7 +38,7 @@ enum NextStep {
|
|||
pub struct ExecutorBuilder<G: Graph> {
|
||||
handler: Arc<dyn NodeHandler<G>>,
|
||||
lifecycle: Option<Box<dyn RunLifecycle<G>>>,
|
||||
settings: ExecutorOptions,
|
||||
options: ExecutorOptions,
|
||||
}
|
||||
|
||||
impl<G: Graph + 'static> ExecutorBuilder<G> {
|
||||
|
|
@ -46,7 +46,7 @@ impl<G: Graph + 'static> ExecutorBuilder<G> {
|
|||
Self {
|
||||
handler,
|
||||
lifecycle: None,
|
||||
settings: ExecutorOptions::default(),
|
||||
options: ExecutorOptions::default(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -56,17 +56,17 @@ impl<G: Graph + 'static> ExecutorBuilder<G> {
|
|||
}
|
||||
|
||||
pub fn cancel_token(mut self, token: Arc<AtomicBool>) -> Self {
|
||||
self.settings.cancel_token = Some(token);
|
||||
self.options.cancel_token = Some(token);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn stall_token(mut self, token: CancellationToken) -> Self {
|
||||
self.settings.stall_token = Some(token);
|
||||
self.options.stall_token = Some(token);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn max_node_visits(mut self, limit: usize) -> Self {
|
||||
self.settings.max_node_visits = Some(limit);
|
||||
self.options.max_node_visits = Some(limit);
|
||||
self
|
||||
}
|
||||
|
||||
|
|
@ -74,7 +74,7 @@ impl<G: Graph + 'static> ExecutorBuilder<G> {
|
|||
Executor {
|
||||
handler: self.handler,
|
||||
lifecycle: self.lifecycle.unwrap_or_else(|| Box::new(NoopLifecycle)),
|
||||
settings: self.settings,
|
||||
options: self.options,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -89,7 +89,7 @@ impl<G: Graph + 'static> Executor<G> {
|
|||
|
||||
loop {
|
||||
// Check cancellation
|
||||
if let Some(ref token) = self.settings.cancel_token {
|
||||
if let Some(ref token) = self.options.cancel_token {
|
||||
if token.load(Ordering::Relaxed) {
|
||||
state.cancelled = true;
|
||||
let outcome = Outcome::fail("run cancelled");
|
||||
|
|
@ -151,7 +151,7 @@ impl<G: Graph + 'static> Executor<G> {
|
|||
});
|
||||
}
|
||||
}
|
||||
if let Some(global_max) = self.settings.max_node_visits {
|
||||
if let Some(global_max) = self.options.max_node_visits {
|
||||
if visits >= global_max {
|
||||
return Err(CoreError::VisitLimitExceeded {
|
||||
node_id: node.id().to_string(),
|
||||
|
|
@ -176,7 +176,7 @@ impl<G: Graph + 'static> Executor<G> {
|
|||
}
|
||||
NodeDecision::Continue => {
|
||||
// Execute with retry, racing against stall token
|
||||
let mut result = if let Some(ref stall) = self.settings.stall_token {
|
||||
let mut result = if let Some(ref stall) = self.options.stall_token {
|
||||
tokio::select! {
|
||||
r = self.execute_with_retry(&node, &state, graph) => r?,
|
||||
() = stall.cancelled() => {
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ impl Handler for SubWorkflowHandler {
|
|||
let child_cancel = Arc::clone(&cancel_token);
|
||||
|
||||
let git_state = services.git_state();
|
||||
let child_config = RunOptions {
|
||||
let child_run_options = RunOptions {
|
||||
config: fabro_config::FabroConfig::default(),
|
||||
run_dir: child_logs,
|
||||
cancel_token: Some(cancel_token),
|
||||
|
|
@ -184,7 +184,7 @@ impl Handler for SubWorkflowHandler {
|
|||
let initialized = Initialized {
|
||||
graph: child_graph,
|
||||
source: String::new(),
|
||||
settings: child_config,
|
||||
run_options: child_run_options,
|
||||
checkpoint: None,
|
||||
seed_context: Some(child_context),
|
||||
emitter,
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ pub struct DiskLifecycle {
|
|||
pub run_dir: PathBuf,
|
||||
pub run_id: String,
|
||||
pub graph: Arc<fabro_graphviz::graph::types::Graph>,
|
||||
pub config: Arc<RunOptions>,
|
||||
pub run_options: Arc<RunOptions>,
|
||||
pub emitter: Arc<EventEmitter>,
|
||||
pub circuit_breaker: Arc<CircuitBreakerLifecycle>,
|
||||
pub checkpoint_enabled: bool,
|
||||
|
|
@ -39,7 +39,7 @@ impl RunLifecycle<WorkflowGraph> for DiskLifecycle {
|
|||
_state: &WfRunState,
|
||||
) -> fabro_core::error::Result<()> {
|
||||
// Write start.json
|
||||
write_start_record(&self.run_dir, &self.config);
|
||||
write_start_record(&self.run_dir, &self.run_options);
|
||||
// Write run status as Running
|
||||
crate::run_status::write_run_status(
|
||||
&self.run_dir,
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ pub struct GitLifecycle {
|
|||
pub emitter: Arc<EventEmitter>,
|
||||
pub run_dir: PathBuf,
|
||||
pub run_id: String,
|
||||
pub config: Arc<RunOptions>,
|
||||
pub run_options: Arc<RunOptions>,
|
||||
pub start_node_id: Option<String>,
|
||||
// Cross-lifecycle data (shared with EventLifecycle)
|
||||
pub checkpoint_git_result: Arc<Mutex<Option<GitCheckpointResult>>>,
|
||||
|
|
@ -55,13 +55,13 @@ impl RunLifecycle<WorkflowGraph> for GitLifecycle {
|
|||
|
||||
// Init metadata branch (best-effort)
|
||||
if let (Some(_), Some(repo_path)) = (
|
||||
self.config
|
||||
self.run_options
|
||||
.git
|
||||
.as_ref()
|
||||
.and_then(|g| g.meta_branch.as_ref()),
|
||||
self.config.host_repo_path.as_ref(),
|
||||
self.run_options.host_repo_path.as_ref(),
|
||||
) {
|
||||
let store = crate::git::MetadataStore::new(repo_path, &self.config.git_author);
|
||||
let store = crate::git::MetadataStore::new(repo_path, &self.run_options.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();
|
||||
let sandbox_json = std::fs::read(self.run_dir.join("sandbox.json")).ok();
|
||||
|
|
@ -97,20 +97,20 @@ impl RunLifecycle<WorkflowGraph> 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.is_none() {
|
||||
if self.start_node_id.as_deref() == Some(node_id) || self.run_options.git.is_none() {
|
||||
*self.checkpoint_git_result.lock().unwrap() = None;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// Shadow commit (best-effort, metadata branch)
|
||||
let shadow_sha: Option<String> = if let (Some(_), Some(repo_path)) = (
|
||||
self.config
|
||||
self.run_options
|
||||
.git
|
||||
.as_ref()
|
||||
.and_then(|g| g.meta_branch.as_ref()),
|
||||
self.config.host_repo_path.as_ref(),
|
||||
self.run_options.host_repo_path.as_ref(),
|
||||
) {
|
||||
let store = crate::git::MetadataStore::new(repo_path, &self.config.git_author);
|
||||
let store = crate::git::MetadataStore::new(repo_path, &self.run_options.git_author);
|
||||
// Build checkpoint JSON for shadow branch
|
||||
let checkpoint_path = self.run_dir.join("checkpoint.json");
|
||||
std::fs::read(&checkpoint_path).ok().and_then(|cp_json| {
|
||||
|
|
@ -158,8 +158,8 @@ impl RunLifecycle<WorkflowGraph> for GitLifecycle {
|
|||
&result.outcome.status.to_string(),
|
||||
completed_count,
|
||||
shadow_sha,
|
||||
self.config.checkpoint_exclude_globs(),
|
||||
&self.config.git_author,
|
||||
self.run_options.checkpoint_exclude_globs(),
|
||||
&self.run_options.git_author,
|
||||
)
|
||||
.await;
|
||||
|
||||
|
|
@ -186,18 +186,21 @@ impl RunLifecycle<WorkflowGraph> for GitLifecycle {
|
|||
}
|
||||
|
||||
// Push run branch (skip in dry-run mode)
|
||||
if !self.config.dry_run {
|
||||
if let Some(branch) =
|
||||
self.config.git.as_ref().and_then(|g| g.run_branch.as_ref())
|
||||
if !self.run_options.dry_run {
|
||||
if let Some(branch) = self
|
||||
.run_options
|
||||
.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(repo_path) = self.config.host_repo_path.as_ref() {
|
||||
} else if let Some(repo_path) = self.run_options.host_repo_path.as_ref() {
|
||||
let refspec = format!("refs/heads/{branch}");
|
||||
git_push_host(
|
||||
repo_path,
|
||||
&refspec,
|
||||
&self.config.github_app,
|
||||
&self.run_options.github_app,
|
||||
"run branch",
|
||||
)
|
||||
.await
|
||||
|
|
@ -208,17 +211,17 @@ impl RunLifecycle<WorkflowGraph> for GitLifecycle {
|
|||
}
|
||||
// Push metadata branch (always from host)
|
||||
if let (Some(meta_branch), Some(repo_path)) = (
|
||||
self.config
|
||||
self.run_options
|
||||
.git
|
||||
.as_ref()
|
||||
.and_then(|g| g.meta_branch.as_ref()),
|
||||
self.config.host_repo_path.as_ref(),
|
||||
self.run_options.host_repo_path.as_ref(),
|
||||
) {
|
||||
let refspec = format!("refs/heads/{meta_branch}");
|
||||
let meta_push_ok = git_push_host(
|
||||
repo_path,
|
||||
&refspec,
|
||||
&self.config.github_app,
|
||||
&self.run_options.github_app,
|
||||
"metadata branch",
|
||||
)
|
||||
.await;
|
||||
|
|
@ -235,7 +238,12 @@ impl RunLifecycle<WorkflowGraph> for GitLifecycle {
|
|||
.lock()
|
||||
.unwrap()
|
||||
.clone()
|
||||
.or_else(|| self.config.git.as_ref().and_then(|g| g.base_sha.clone()))
|
||||
.or_else(|| {
|
||||
self.run_options
|
||||
.git
|
||||
.as_ref()
|
||||
.and_then(|g| g.base_sha.clone())
|
||||
})
|
||||
.unwrap_or_else(|| sha.clone());
|
||||
let diff_dest = node_dir(&self.run_dir, node_id, visit).join("diff.patch");
|
||||
|
||||
|
|
@ -275,9 +283,14 @@ impl RunLifecycle<WorkflowGraph> 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.is_some()
|
||||
&& self.run_options.git.is_some()
|
||||
{
|
||||
if let Some(base_sha) = self.config.git.as_ref().and_then(|g| g.base_sha.clone()) {
|
||||
if let Some(base_sha) = self
|
||||
.run_options
|
||||
.git
|
||||
.as_ref()
|
||||
.and_then(|g| g.base_sha.clone())
|
||||
{
|
||||
let diff_dest = self.run_dir.join("final.patch");
|
||||
match git_diff(&*self.sandbox, &base_sha).await {
|
||||
Ok(patch) if !patch.is_empty() => {
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ impl WorkflowLifecycle {
|
|||
sandbox: Arc<dyn Sandbox>,
|
||||
graph: Arc<fabro_graphviz::graph::types::Graph>,
|
||||
run_dir: PathBuf,
|
||||
config: Arc<RunOptions>,
|
||||
run_options: Arc<RunOptions>,
|
||||
is_resume: bool,
|
||||
) -> Self {
|
||||
let restarted_from: Arc<Mutex<Option<(String, String)>>> = Arc::new(Mutex::new(None));
|
||||
|
|
@ -91,7 +91,7 @@ impl WorkflowLifecycle {
|
|||
|
||||
let circuit_breaker = Arc::new(CircuitBreakerLifecycle::new(loop_restart_signature_limit));
|
||||
|
||||
let has_run_branch = config
|
||||
let has_run_branch = run_options
|
||||
.git
|
||||
.as_ref()
|
||||
.and_then(|g| g.run_branch.as_ref())
|
||||
|
|
@ -106,11 +106,11 @@ impl WorkflowLifecycle {
|
|||
let event = EventLifecycle {
|
||||
emitter: Arc::clone(&emitter),
|
||||
graph_name: graph.name.clone(),
|
||||
run_id: config.run_id.clone(),
|
||||
run_id: run_options.run_id.clone(),
|
||||
run_start: Mutex::new(Instant::now()),
|
||||
restarted_from: Arc::clone(&restarted_from),
|
||||
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()),
|
||||
base_sha: run_options.git.as_ref().and_then(|g| g.base_sha.clone()),
|
||||
run_branch: run_options.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),
|
||||
|
|
@ -122,7 +122,7 @@ impl WorkflowLifecycle {
|
|||
hook_runner,
|
||||
sandbox: Arc::clone(&sandbox),
|
||||
hook_work_dir: working_directory.clone().map(PathBuf::from),
|
||||
run_id: config.run_id.clone(),
|
||||
run_id: run_options.run_id.clone(),
|
||||
graph_name: graph.name.clone(),
|
||||
};
|
||||
|
||||
|
|
@ -130,9 +130,9 @@ impl WorkflowLifecycle {
|
|||
|
||||
let disk = DiskLifecycle {
|
||||
run_dir: run_dir.clone(),
|
||||
run_id: config.run_id.clone(),
|
||||
run_id: run_options.run_id.clone(),
|
||||
graph: Arc::clone(&graph),
|
||||
config: Arc::clone(&config),
|
||||
run_options: Arc::clone(&run_options),
|
||||
emitter: Arc::clone(&emitter),
|
||||
circuit_breaker: Arc::clone(&circuit_breaker),
|
||||
checkpoint_enabled: true,
|
||||
|
|
@ -145,8 +145,8 @@ impl WorkflowLifecycle {
|
|||
artifact_store: Arc::clone(&artifact_store),
|
||||
emitter: Arc::clone(&emitter),
|
||||
run_dir: run_dir.clone(),
|
||||
run_id: config.run_id.clone(),
|
||||
config: Arc::clone(&config),
|
||||
run_id: run_options.run_id.clone(),
|
||||
run_options: Arc::clone(&run_options),
|
||||
start_node_id,
|
||||
checkpoint_git_result: Arc::clone(&checkpoint_git_result),
|
||||
last_git_sha: Arc::clone(&last_git_sha),
|
||||
|
|
@ -158,7 +158,7 @@ impl WorkflowLifecycle {
|
|||
Some(run_dir.clone()),
|
||||
Arc::clone(&emitter),
|
||||
run_dir,
|
||||
config.asset_globs().to_vec(),
|
||||
run_options.asset_globs().to_vec(),
|
||||
);
|
||||
|
||||
Self {
|
||||
|
|
@ -174,7 +174,7 @@ impl WorkflowLifecycle {
|
|||
checkpoint_git_result,
|
||||
is_initial_resume: AtomicBool::new(is_resume),
|
||||
graph,
|
||||
run_id: config.run_id.clone(),
|
||||
run_id: run_options.run_id.clone(),
|
||||
working_directory,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,13 +62,13 @@ pub fn validate_from_file(path: &Path) -> Result<Validated, FabroError> {
|
|||
}
|
||||
|
||||
/// Parse, transform, validate, normalize config, and persist a run.
|
||||
pub fn create(dot_source: &str, settings: RunCreateOptions) -> Result<Persisted, FabroError> {
|
||||
pub fn create(dot_source: &str, options: RunCreateOptions) -> Result<Persisted, FabroError> {
|
||||
let validated = preprocess_and_validate(
|
||||
dot_source,
|
||||
settings.base_dir.clone(),
|
||||
options.base_dir.clone(),
|
||||
Vec::new(),
|
||||
Some(&settings.config),
|
||||
settings.goal_override.as_deref(),
|
||||
Some(&options.config),
|
||||
options.goal_override.as_deref(),
|
||||
)?;
|
||||
|
||||
if validated.has_errors() {
|
||||
|
|
@ -77,19 +77,19 @@ pub fn create(dot_source: &str, settings: RunCreateOptions) -> Result<Persisted,
|
|||
});
|
||||
}
|
||||
|
||||
persist_validated(validated, settings)
|
||||
persist_validated(validated, options)
|
||||
}
|
||||
|
||||
/// Read a DOT file, apply file inlining from its parent directory, then create.
|
||||
pub fn create_from_file(
|
||||
path: &Path,
|
||||
mut settings: RunCreateOptions,
|
||||
mut options: RunCreateOptions,
|
||||
) -> Result<Persisted, FabroError> {
|
||||
let source = std::fs::read_to_string(path)
|
||||
.map_err(|e| FabroError::Parse(format!("Failed to read {}: {e}", path.display())))?;
|
||||
let base_dir = path.parent().unwrap_or(Path::new("."));
|
||||
settings.base_dir = Some(base_dir.to_path_buf());
|
||||
create(&source, settings)
|
||||
options.base_dir = Some(base_dir.to_path_buf());
|
||||
create(&source, options)
|
||||
}
|
||||
|
||||
/// Build a persisted workflow from an already-materialized graph.
|
||||
|
|
@ -99,13 +99,13 @@ pub fn create_from_file(
|
|||
#[doc(hidden)]
|
||||
pub fn create_from_graph(
|
||||
mut graph: Graph,
|
||||
settings: RunCreateOptions,
|
||||
options: RunCreateOptions,
|
||||
) -> Result<Persisted, FabroError> {
|
||||
if let Some(goal_override) = settings.goal_override.as_deref() {
|
||||
if let Some(goal_override) = options.goal_override.as_deref() {
|
||||
apply_goal_override(&mut graph, Some(goal_override));
|
||||
}
|
||||
let validated = Validated::new(graph, String::new(), vec![]);
|
||||
persist_validated(validated, settings)
|
||||
persist_validated(validated, options)
|
||||
}
|
||||
|
||||
fn preprocess_and_validate(
|
||||
|
|
@ -150,7 +150,7 @@ fn apply_goal_override(graph: &mut Graph, goal_override: Option<&str>) {
|
|||
|
||||
fn persist_validated(
|
||||
validated: Validated,
|
||||
settings: RunCreateOptions,
|
||||
options: RunCreateOptions,
|
||||
) -> Result<Persisted, FabroError> {
|
||||
let RunCreateOptions {
|
||||
mut config,
|
||||
|
|
@ -163,7 +163,7 @@ fn persist_validated(
|
|||
host_repo_path,
|
||||
goal_override: _,
|
||||
base_dir: _,
|
||||
} = settings;
|
||||
} = options;
|
||||
|
||||
finalize_config(&mut config, validated.graph());
|
||||
|
||||
|
|
|
|||
|
|
@ -78,10 +78,10 @@ pub async fn start(persisted: Persisted, options: StartOptions) -> Result<Starte
|
|||
);
|
||||
|
||||
let retro_opts = RetroOptions {
|
||||
run_id: executed.settings.run_id.clone(),
|
||||
run_id: executed.run_options.run_id.clone(),
|
||||
workflow_name: executed.graph.name.clone(),
|
||||
goal: executed.graph.goal().to_string(),
|
||||
run_dir: executed.settings.run_dir.clone(),
|
||||
run_dir: executed.run_options.run_dir.clone(),
|
||||
sandbox: Arc::clone(&executed.sandbox),
|
||||
emitter: Some(Arc::clone(&executed.emitter)),
|
||||
failed,
|
||||
|
|
@ -98,15 +98,15 @@ pub async fn start(persisted: Persisted, options: StartOptions) -> Result<Starte
|
|||
let retro_duration = retro_start.elapsed();
|
||||
|
||||
let finalize_opts = FinalizeOptions {
|
||||
run_dir: retroed.settings.run_dir.clone(),
|
||||
run_id: retroed.settings.run_id.clone(),
|
||||
run_dir: retroed.run_options.run_dir.clone(),
|
||||
run_id: retroed.run_options.run_id.clone(),
|
||||
workflow_name: retroed.graph.name.clone(),
|
||||
hook_runner: retroed.hook_runner.clone(),
|
||||
preserve_sandbox: options.finalize.preserve_sandbox,
|
||||
last_git_sha: last_git_sha.lock().unwrap().clone(),
|
||||
};
|
||||
let pr_opts = PullRequestOptions {
|
||||
run_dir: retroed.settings.run_dir.clone(),
|
||||
run_dir: retroed.run_options.run_dir.clone(),
|
||||
pr_config: options.pull_request.pr_config,
|
||||
github_app: options.pull_request.github_app,
|
||||
origin_url: options.pull_request.origin_url,
|
||||
|
|
@ -369,7 +369,7 @@ mod tests {
|
|||
.unwrap()
|
||||
}
|
||||
|
||||
fn test_settings(run_dir: &std::path::Path) -> RunOptions {
|
||||
fn test_run_options(run_dir: &std::path::Path) -> RunOptions {
|
||||
RunOptions {
|
||||
config: FabroConfig::default(),
|
||||
run_dir: run_dir.to_path_buf(),
|
||||
|
|
@ -410,7 +410,7 @@ mod tests {
|
|||
sandbox,
|
||||
registry,
|
||||
lifecycle,
|
||||
run_options: test_settings(run_dir),
|
||||
run_options: test_run_options(run_dir),
|
||||
hooks: fabro_hooks::HookConfig { hooks: vec![] },
|
||||
sandbox_env: HashMap::new(),
|
||||
checkpoint: None,
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ pub async fn execute(init: Initialized) -> Executed {
|
|||
let Initialized {
|
||||
graph,
|
||||
source: _,
|
||||
settings,
|
||||
run_options,
|
||||
checkpoint,
|
||||
seed_context,
|
||||
emitter,
|
||||
|
|
@ -48,15 +48,15 @@ pub async fn execute(init: Initialized) -> Executed {
|
|||
let graph_arc = Arc::new(graph.clone());
|
||||
let wf_graph = WorkflowGraph(Arc::clone(&graph_arc));
|
||||
|
||||
let git_state = settings.git.as_ref().and_then(|git| {
|
||||
let git_state = run_options.git.as_ref().and_then(|git| {
|
||||
let base_sha = git.base_sha.clone()?;
|
||||
Some(Arc::new(GitState {
|
||||
run_id: settings.run_id.clone(),
|
||||
run_id: run_options.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(),
|
||||
checkpoint_exclude_globs: run_options.checkpoint_exclude_globs().to_vec(),
|
||||
git_author: run_options.git_author.clone(),
|
||||
}))
|
||||
});
|
||||
|
||||
|
|
@ -72,17 +72,17 @@ pub async fn execute(init: Initialized) -> Executed {
|
|||
|
||||
let handler = Arc::new(WorkflowNodeHandler {
|
||||
services: shared_services,
|
||||
run_dir: settings.run_dir.clone(),
|
||||
run_dir: run_options.run_dir.clone(),
|
||||
graph: Arc::clone(&graph_arc),
|
||||
});
|
||||
|
||||
let settings_arc = Arc::new(settings.clone());
|
||||
let settings_arc = Arc::new(run_options.clone());
|
||||
let lifecycle = WorkflowLifecycle::new(
|
||||
Arc::clone(&emitter),
|
||||
hook_runner.clone(),
|
||||
Arc::clone(&sandbox),
|
||||
graph_arc,
|
||||
settings.run_dir.clone(),
|
||||
run_options.run_dir.clone(),
|
||||
settings_arc,
|
||||
checkpoint.is_some(),
|
||||
);
|
||||
|
|
@ -134,7 +134,7 @@ pub async fn execute(init: Initialized) -> Executed {
|
|||
return Executed {
|
||||
graph,
|
||||
outcome: Err(err),
|
||||
settings,
|
||||
run_options,
|
||||
hook_runner,
|
||||
emitter,
|
||||
sandbox,
|
||||
|
|
@ -155,7 +155,7 @@ pub async fn execute(init: Initialized) -> Executed {
|
|||
return Executed {
|
||||
graph,
|
||||
outcome: Err(err),
|
||||
settings,
|
||||
run_options,
|
||||
hook_runner,
|
||||
emitter,
|
||||
sandbox,
|
||||
|
|
@ -171,7 +171,7 @@ pub async fn execute(init: Initialized) -> Executed {
|
|||
return Executed {
|
||||
graph,
|
||||
outcome: Err(err),
|
||||
settings,
|
||||
run_options,
|
||||
hook_runner,
|
||||
emitter,
|
||||
sandbox,
|
||||
|
|
@ -187,7 +187,7 @@ pub async fn execute(init: Initialized) -> Executed {
|
|||
let graph_max = graph.max_node_visits();
|
||||
let max_node_visits = if graph_max > 0 {
|
||||
Some(graph_max as usize)
|
||||
} else if settings.dry_run {
|
||||
} else if run_options.dry_run {
|
||||
Some(10)
|
||||
} else {
|
||||
None
|
||||
|
|
@ -235,7 +235,7 @@ pub async fn execute(init: Initialized) -> Executed {
|
|||
ExecutorBuilder::new(handler as Arc<dyn fabro_core::handler::NodeHandler<WorkflowGraph>>)
|
||||
.lifecycle(Box::new(lifecycle));
|
||||
|
||||
if let Some(ref cancel) = settings.cancel_token {
|
||||
if let Some(ref cancel) = run_options.cancel_token {
|
||||
builder = builder.cancel_token(cancel.clone());
|
||||
}
|
||||
if let Some(token) = stall_token.clone() {
|
||||
|
|
@ -290,7 +290,7 @@ pub async fn execute(init: Initialized) -> Executed {
|
|||
Executed {
|
||||
graph,
|
||||
outcome,
|
||||
settings,
|
||||
run_options,
|
||||
hook_runner,
|
||||
emitter,
|
||||
sandbox,
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ fn make_registry() -> HandlerRegistry {
|
|||
registry
|
||||
}
|
||||
|
||||
fn test_settings(run_dir: &Path, run_id: &str) -> RunOptions {
|
||||
fn test_run_options(run_dir: &Path, run_id: &str) -> RunOptions {
|
||||
RunOptions {
|
||||
run_dir: run_dir.to_path_buf(),
|
||||
cancel_token: None,
|
||||
|
|
@ -160,7 +160,7 @@ async fn execute_runs_start_to_exit_and_returns_final_context() {
|
|||
setup_command_timeout_ms: 1_000,
|
||||
devcontainer_phases: vec![],
|
||||
},
|
||||
run_options: test_settings(&run_dir, "run-test"),
|
||||
run_options: test_run_options(&run_dir, "run-test"),
|
||||
hooks: HookConfig { hooks: vec![] },
|
||||
sandbox_env: HashMap::new(),
|
||||
checkpoint: None,
|
||||
|
|
@ -189,22 +189,22 @@ async fn run_with_lifecycle(
|
|||
emitter: Arc<EventEmitter>,
|
||||
sandbox: Arc<dyn Sandbox>,
|
||||
graph: &Graph,
|
||||
settings: RunOptions,
|
||||
run_options: RunOptions,
|
||||
lifecycle: LifecycleOptions,
|
||||
) -> Result<Outcome, FabroError> {
|
||||
let run_dir = settings.run_dir.clone();
|
||||
let run_id = settings.run_id.clone();
|
||||
let run_dir = run_options.run_dir.clone();
|
||||
let run_id = run_options.run_id.clone();
|
||||
std::fs::create_dir_all(&run_dir).unwrap();
|
||||
let initialized = initialize(
|
||||
persisted_workflow(graph.clone(), String::new(), &run_dir, &run_id),
|
||||
InitOptions {
|
||||
run_id,
|
||||
dry_run: settings.dry_run,
|
||||
dry_run: run_options.dry_run,
|
||||
emitter,
|
||||
sandbox,
|
||||
registry: Arc::new(registry),
|
||||
lifecycle,
|
||||
run_options: settings,
|
||||
run_options,
|
||||
hooks: HookConfig { hooks: vec![] },
|
||||
sandbox_env: HashMap::new(),
|
||||
checkpoint: None,
|
||||
|
|
@ -375,7 +375,7 @@ async fn execute_runs_simple_workflow() {
|
|||
Arc::new(EventEmitter::new()),
|
||||
local_env(),
|
||||
&simple_graph(),
|
||||
&test_settings(dir.path(), "test-run"),
|
||||
&test_run_options(dir.path(), "test-run"),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
|
@ -390,7 +390,7 @@ async fn execute_saves_checkpoint() {
|
|||
Arc::new(EventEmitter::new()),
|
||||
local_env(),
|
||||
&simple_graph(),
|
||||
&test_settings(dir.path(), "test-run"),
|
||||
&test_run_options(dir.path(), "test-run"),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
|
@ -412,7 +412,7 @@ async fn execute_emits_events() {
|
|||
Arc::new(emitter),
|
||||
local_env(),
|
||||
&simple_graph(),
|
||||
&test_settings(dir.path(), "test-run"),
|
||||
&test_run_options(dir.path(), "test-run"),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
|
@ -428,7 +428,7 @@ async fn execute_error_when_no_start_node() {
|
|||
Arc::new(EventEmitter::new()),
|
||||
local_env(),
|
||||
&Graph::new("empty"),
|
||||
&test_settings(dir.path(), "test-run"),
|
||||
&test_run_options(dir.path(), "test-run"),
|
||||
)
|
||||
.await;
|
||||
assert!(result.is_err());
|
||||
|
|
@ -442,7 +442,7 @@ async fn execute_mirrors_graph_goal_to_context() {
|
|||
Arc::new(EventEmitter::new()),
|
||||
local_env(),
|
||||
&simple_graph(),
|
||||
&test_settings(dir.path(), "test-run"),
|
||||
&test_run_options(dir.path(), "test-run"),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
|
@ -491,7 +491,7 @@ async fn execute_conditional_routing_uses_unconditional_success_path() {
|
|||
Arc::new(EventEmitter::new()),
|
||||
local_env(),
|
||||
&g,
|
||||
&test_settings(dir.path(), "test-run"),
|
||||
&test_run_options(dir.path(), "test-run"),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
|
@ -504,8 +504,8 @@ async fn execute_conditional_routing_uses_unconditional_success_path() {
|
|||
#[tokio::test]
|
||||
async fn execute_writes_start_json_and_node_status() {
|
||||
let dir = tempfile::tempdir().unwrap();
|
||||
let mut settings = test_settings(dir.path(), "test-run");
|
||||
settings.git = Some(GitCheckpointOptions {
|
||||
let mut run_options = test_run_options(dir.path(), "test-run");
|
||||
run_options.git = Some(GitCheckpointOptions {
|
||||
base_sha: Some("abc123".into()),
|
||||
run_branch: Some("fabro/run/test-run".into()),
|
||||
meta_branch: None,
|
||||
|
|
@ -516,7 +516,7 @@ async fn execute_writes_start_json_and_node_status() {
|
|||
Arc::new(EventEmitter::new()),
|
||||
local_env(),
|
||||
&simple_graph(),
|
||||
&settings,
|
||||
&run_options,
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
|
@ -575,7 +575,7 @@ async fn timeout_causes_fail_status_json() {
|
|||
Arc::new(EventEmitter::new()),
|
||||
local_env(),
|
||||
&g,
|
||||
&test_settings(dir.path(), "test-run"),
|
||||
&test_run_options(dir.path(), "test-run"),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
|
@ -604,8 +604,8 @@ async fn execute_cancelled_mid_run() {
|
|||
let cancel_token_clone = Arc::clone(&cancel_token);
|
||||
let mut registry = make_registry();
|
||||
registry.register("slow", Box::new(SlowHandler { sleep_ms: 200 }));
|
||||
let mut settings = test_settings(dir.path(), "test-run");
|
||||
settings.cancel_token = Some(cancel_token);
|
||||
let mut run_options = test_run_options(dir.path(), "test-run");
|
||||
run_options.cancel_token = Some(cancel_token);
|
||||
|
||||
tokio::spawn(async move {
|
||||
tokio::time::sleep(Duration::from_millis(50)).await;
|
||||
|
|
@ -617,7 +617,7 @@ async fn execute_cancelled_mid_run() {
|
|||
Arc::new(EventEmitter::new()),
|
||||
local_env(),
|
||||
&g,
|
||||
&settings,
|
||||
&run_options,
|
||||
)
|
||||
.await;
|
||||
assert!(matches!(result, Err(FabroError::Cancelled)));
|
||||
|
|
@ -635,7 +635,7 @@ async fn max_node_visits_errors_on_cycle() {
|
|||
Arc::new(EventEmitter::new()),
|
||||
local_env(),
|
||||
&g,
|
||||
&test_settings(dir.path(), "test-run"),
|
||||
&test_run_options(dir.path(), "test-run"),
|
||||
)
|
||||
.await;
|
||||
let err = result.unwrap_err().to_string();
|
||||
|
|
@ -670,7 +670,7 @@ async fn panic_handler_writes_panic_txt() {
|
|||
Arc::new(EventEmitter::new()),
|
||||
local_env(),
|
||||
&g,
|
||||
&test_settings(dir.path(), "test-run"),
|
||||
&test_run_options(dir.path(), "test-run"),
|
||||
)
|
||||
.await;
|
||||
|
||||
|
|
@ -691,7 +691,7 @@ async fn loop_circuit_breaker_aborts_on_repeated_failure() {
|
|||
Arc::new(EventEmitter::new()),
|
||||
local_env(),
|
||||
&looping_fail_graph(),
|
||||
&test_settings(dir.path(), "test-run"),
|
||||
&test_run_options(dir.path(), "test-run"),
|
||||
)
|
||||
.await;
|
||||
let err = result.unwrap_err().to_string();
|
||||
|
|
@ -740,7 +740,7 @@ async fn stall_watchdog_triggers_on_hung_handler() {
|
|||
Arc::new(EventEmitter::new()),
|
||||
local_env(),
|
||||
&g,
|
||||
&test_settings(dir.path(), "test-run"),
|
||||
&test_run_options(dir.path(), "test-run"),
|
||||
)
|
||||
.await;
|
||||
let err = result.unwrap_err().to_string();
|
||||
|
|
@ -804,7 +804,7 @@ async fn retry_emits_stage_started_per_attempt() {
|
|||
Arc::new(emitter),
|
||||
local_env(),
|
||||
&g,
|
||||
&test_settings(dir.path(), "retry-events-test"),
|
||||
&test_run_options(dir.path(), "retry-events-test"),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
|
@ -845,7 +845,7 @@ async fn run_with_lifecycle_emits_initialize_and_setup_events() {
|
|||
Arc::new(emitter),
|
||||
local_env(),
|
||||
&simple_graph(),
|
||||
test_settings(dir.path(), "order-test"),
|
||||
test_run_options(dir.path(), "order-test"),
|
||||
test_lifecycle(vec!["echo ok".to_string()]),
|
||||
)
|
||||
.await
|
||||
|
|
@ -916,17 +916,23 @@ async fn git_checkpoint_skips_start_node() {
|
|||
});
|
||||
|
||||
let sandbox: Arc<dyn Sandbox> = Arc::new(fabro_agent::LocalSandbox::new(repo.to_path_buf()));
|
||||
let mut settings = test_settings(run_tmp.path(), "git-cp-test");
|
||||
settings.git = Some(GitCheckpointOptions {
|
||||
let mut run_options = test_run_options(run_tmp.path(), "git-cp-test");
|
||||
run_options.git = Some(GitCheckpointOptions {
|
||||
base_sha: Some(base_sha),
|
||||
run_branch: None,
|
||||
meta_branch: Some(crate::git::MetadataStore::branch_name("git-cp-test")),
|
||||
});
|
||||
settings.host_repo_path = Some(repo.to_path_buf());
|
||||
run_options.host_repo_path = Some(repo.to_path_buf());
|
||||
|
||||
run_graph(make_registry(), Arc::new(emitter), sandbox, &g, &settings)
|
||||
.await
|
||||
.unwrap();
|
||||
run_graph(
|
||||
make_registry(),
|
||||
Arc::new(emitter),
|
||||
sandbox,
|
||||
&g,
|
||||
&run_options,
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let collected = events.lock().unwrap();
|
||||
let checkpoint_node_ids: Vec<&str> = collected
|
||||
|
|
|
|||
|
|
@ -151,15 +151,18 @@ pub fn persist_terminal_outcome(
|
|||
///
|
||||
/// This captures the last diff.patch (written after the final checkpoint) and retro.json.
|
||||
/// Best-effort: errors are logged as warnings.
|
||||
pub async fn write_finalize_commit(config: &RunOptions, run_dir: &Path) {
|
||||
pub async fn write_finalize_commit(run_options: &RunOptions, run_dir: &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(),
|
||||
run_options
|
||||
.git
|
||||
.as_ref()
|
||||
.and_then(|g| g.meta_branch.as_ref()),
|
||||
run_options.host_repo_path.as_ref(),
|
||||
) else {
|
||||
return;
|
||||
};
|
||||
|
||||
let store = crate::git::MetadataStore::new(repo_path, &config.git_author);
|
||||
let store = crate::git::MetadataStore::new(repo_path, &run_options.git_author);
|
||||
let mut entries = crate::git::scan_node_files(run_dir);
|
||||
if let Ok(retro_bytes) = std::fs::read(run_dir.join("retro.json")) {
|
||||
entries.push(("retro.json".to_string(), retro_bytes));
|
||||
|
|
@ -168,14 +171,19 @@ pub async fn write_finalize_commit(config: &RunOptions, run_dir: &Path) {
|
|||
.iter()
|
||||
.map(|(k, v)| (k.as_str(), v.as_slice()))
|
||||
.collect();
|
||||
if let Err(e) = store.write_files(&config.run_id, &refs, "finalize run") {
|
||||
if let Err(e) = store.write_files(&run_options.run_id, &refs, "finalize run") {
|
||||
tracing::warn!(error = %e, "Failed to write finalize commit to metadata branch");
|
||||
return;
|
||||
}
|
||||
|
||||
let refspec = format!("refs/heads/{meta_branch}");
|
||||
crate::sandbox_git::git_push_host(repo_path, &refspec, &config.github_app, "finalize metadata")
|
||||
.await;
|
||||
crate::sandbox_git::git_push_host(
|
||||
repo_path,
|
||||
&refspec,
|
||||
&run_options.github_app,
|
||||
"finalize metadata",
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
async fn run_hooks(
|
||||
|
|
@ -220,7 +228,7 @@ pub async fn finalize(
|
|||
let Retroed {
|
||||
graph,
|
||||
outcome,
|
||||
settings,
|
||||
run_options,
|
||||
hook_runner,
|
||||
emitter,
|
||||
sandbox,
|
||||
|
|
@ -238,7 +246,7 @@ pub async fn finalize(
|
|||
options.last_git_sha.clone(),
|
||||
);
|
||||
|
||||
write_finalize_commit(&settings, &options.run_dir).await;
|
||||
write_finalize_commit(&run_options, &options.run_dir).await;
|
||||
|
||||
if options.preserve_sandbox {
|
||||
let info = sandbox.sandbox_info();
|
||||
|
|
@ -279,12 +287,12 @@ pub async fn finalize(
|
|||
persist_terminal_outcome(&options.run_dir, &conclusion, run_status, status_reason);
|
||||
|
||||
Ok(Concluded {
|
||||
run_id: settings.run_id.clone(),
|
||||
run_id: run_options.run_id.clone(),
|
||||
outcome,
|
||||
conclusion,
|
||||
pushed_branch: settings.git.as_ref().and_then(|g| g.run_branch.clone()),
|
||||
pushed_branch: run_options.git.as_ref().and_then(|g| g.run_branch.clone()),
|
||||
graph,
|
||||
settings,
|
||||
run_options,
|
||||
emitter,
|
||||
})
|
||||
}
|
||||
|
|
@ -301,7 +309,7 @@ mod tests {
|
|||
use crate::pipeline::types::Retroed;
|
||||
use crate::run_options::RunOptions;
|
||||
|
||||
fn test_settings(run_dir: &std::path::Path) -> RunOptions {
|
||||
fn test_run_options(run_dir: &std::path::Path) -> RunOptions {
|
||||
RunOptions {
|
||||
config: FabroConfig::default(),
|
||||
run_dir: run_dir.to_path_buf(),
|
||||
|
|
@ -326,7 +334,7 @@ mod tests {
|
|||
let retroed = Retroed {
|
||||
graph: Graph::new("test"),
|
||||
outcome: Ok(Outcome::success()),
|
||||
settings: test_settings(&run_dir),
|
||||
run_options: test_run_options(&run_dir),
|
||||
hook_runner: None,
|
||||
emitter: Arc::new(EventEmitter::new()),
|
||||
sandbox: Arc::new(fabro_agent::LocalSandbox::new(
|
||||
|
|
|
|||
|
|
@ -173,7 +173,7 @@ pub async fn initialize(
|
|||
Ok(Initialized {
|
||||
graph,
|
||||
source,
|
||||
settings: options.run_options,
|
||||
run_options: options.run_options,
|
||||
checkpoint: options.checkpoint,
|
||||
seed_context: options.seed_context,
|
||||
emitter: options.emitter,
|
||||
|
|
@ -298,7 +298,7 @@ mod tests {
|
|||
.await
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(initialized.settings.run_dir, run_dir);
|
||||
assert_eq!(initialized.run_options.run_dir, run_dir);
|
||||
assert_eq!(initialized.source, source);
|
||||
assert!(initialized.hook_runner.is_none());
|
||||
assert_eq!(
|
||||
|
|
@ -402,7 +402,7 @@ mod tests {
|
|||
.await
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(initialized.settings.run_dir, run_dir);
|
||||
assert_eq!(initialized.run_options.run_dir, run_dir);
|
||||
assert_eq!(initialized.source, source);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -482,7 +482,7 @@ pub async fn pull_request(concluded: Concluded, options: &PullRequestOptions) ->
|
|||
conclusion,
|
||||
pushed_branch,
|
||||
graph,
|
||||
settings,
|
||||
run_options,
|
||||
emitter,
|
||||
} = concluded;
|
||||
|
||||
|
|
@ -499,7 +499,7 @@ pub async fn pull_request(concluded: Concluded, options: &PullRequestOptions) ->
|
|||
.await
|
||||
.unwrap_or_default();
|
||||
if let (Some(base_branch), Some(run_branch), Some(creds), Some(origin)) = (
|
||||
&settings.base_branch,
|
||||
&run_options.base_branch,
|
||||
pushed_branch.as_deref(),
|
||||
&options.github_app,
|
||||
&options.origin_url,
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ pub async fn retro(executed: Executed, options: &RetroOptions) -> Retroed {
|
|||
let Executed {
|
||||
graph,
|
||||
outcome,
|
||||
settings,
|
||||
run_options,
|
||||
hook_runner,
|
||||
emitter,
|
||||
sandbox,
|
||||
|
|
@ -133,7 +133,7 @@ pub async fn retro(executed: Executed, options: &RetroOptions) -> Retroed {
|
|||
Retroed {
|
||||
graph,
|
||||
outcome,
|
||||
settings,
|
||||
run_options,
|
||||
hook_runner,
|
||||
emitter,
|
||||
sandbox,
|
||||
|
|
@ -176,7 +176,7 @@ mod tests {
|
|||
checkpoint.save(&run_dir.join("checkpoint.json")).unwrap();
|
||||
}
|
||||
|
||||
fn test_settings(run_dir: &std::path::Path) -> RunOptions {
|
||||
fn test_run_options(run_dir: &std::path::Path) -> RunOptions {
|
||||
RunOptions {
|
||||
config: FabroConfig::default(),
|
||||
run_dir: run_dir.to_path_buf(),
|
||||
|
|
@ -207,7 +207,7 @@ mod tests {
|
|||
let executed = Executed {
|
||||
graph: Graph::new("test"),
|
||||
outcome: Ok(crate::outcome::Outcome::success()),
|
||||
settings: test_settings(&run_dir),
|
||||
run_options: test_run_options(&run_dir),
|
||||
hook_runner: None,
|
||||
emitter: Arc::clone(&emitter),
|
||||
sandbox: Arc::clone(&sandbox),
|
||||
|
|
|
|||
|
|
@ -208,7 +208,7 @@ pub struct InitOptions {
|
|||
pub struct Initialized {
|
||||
pub graph: Graph,
|
||||
pub source: String,
|
||||
pub settings: RunOptions,
|
||||
pub run_options: RunOptions,
|
||||
pub(crate) checkpoint: Option<Checkpoint>,
|
||||
pub(crate) seed_context: Option<Context>,
|
||||
pub emitter: Arc<EventEmitter>,
|
||||
|
|
@ -224,7 +224,7 @@ pub struct Initialized {
|
|||
pub struct Executed {
|
||||
pub graph: Graph,
|
||||
pub outcome: Result<Outcome, FabroError>,
|
||||
pub settings: RunOptions,
|
||||
pub run_options: RunOptions,
|
||||
pub hook_runner: Option<Arc<HookRunner>>,
|
||||
pub emitter: Arc<EventEmitter>,
|
||||
pub sandbox: Arc<dyn Sandbox>,
|
||||
|
|
@ -237,7 +237,7 @@ pub struct Executed {
|
|||
pub struct Retroed {
|
||||
pub graph: Graph,
|
||||
pub outcome: Result<Outcome, FabroError>,
|
||||
pub settings: RunOptions,
|
||||
pub run_options: RunOptions,
|
||||
pub hook_runner: Option<Arc<HookRunner>>,
|
||||
pub emitter: Arc<EventEmitter>,
|
||||
pub sandbox: Arc<dyn Sandbox>,
|
||||
|
|
@ -253,7 +253,7 @@ pub struct Concluded {
|
|||
pub conclusion: Conclusion,
|
||||
pub pushed_branch: Option<String>,
|
||||
pub graph: Graph,
|
||||
pub settings: RunOptions,
|
||||
pub run_options: RunOptions,
|
||||
pub emitter: Arc<EventEmitter>,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,14 +23,14 @@ fn initialized(
|
|||
emitter: Arc<EventEmitter>,
|
||||
sandbox: Arc<dyn Sandbox>,
|
||||
graph: &fabro_graphviz::graph::Graph,
|
||||
settings: &RunOptions,
|
||||
run_options: &RunOptions,
|
||||
options: InitializedOptions,
|
||||
) -> Initialized {
|
||||
std::fs::create_dir_all(&settings.run_dir).expect("failed to create run dir");
|
||||
std::fs::create_dir_all(&run_options.run_dir).expect("failed to create run dir");
|
||||
Initialized {
|
||||
graph: graph.clone(),
|
||||
source: String::new(),
|
||||
settings: settings.clone(),
|
||||
run_options: run_options.clone(),
|
||||
checkpoint: options.checkpoint,
|
||||
seed_context: None,
|
||||
emitter,
|
||||
|
|
@ -38,7 +38,7 @@ fn initialized(
|
|||
registry: Arc::new(registry),
|
||||
hook_runner: options.hook_runner,
|
||||
env: options.env,
|
||||
dry_run: settings.dry_run,
|
||||
dry_run: run_options.dry_run,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -47,14 +47,14 @@ pub async fn run_graph(
|
|||
emitter: Arc<EventEmitter>,
|
||||
sandbox: Arc<dyn Sandbox>,
|
||||
graph: &fabro_graphviz::graph::Graph,
|
||||
settings: &RunOptions,
|
||||
run_options: &RunOptions,
|
||||
) -> Result<Outcome> {
|
||||
let executed = pipeline::execute(initialized(
|
||||
registry,
|
||||
emitter,
|
||||
sandbox,
|
||||
graph,
|
||||
settings,
|
||||
run_options,
|
||||
InitializedOptions {
|
||||
hook_runner: None,
|
||||
env: HashMap::new(),
|
||||
|
|
@ -70,7 +70,7 @@ pub async fn run_graph_with_hooks(
|
|||
emitter: Arc<EventEmitter>,
|
||||
sandbox: Arc<dyn Sandbox>,
|
||||
graph: &fabro_graphviz::graph::Graph,
|
||||
settings: &RunOptions,
|
||||
run_options: &RunOptions,
|
||||
hook_runner: Arc<fabro_hooks::HookRunner>,
|
||||
env: Option<HashMap<String, String>>,
|
||||
) -> Result<Outcome> {
|
||||
|
|
@ -79,7 +79,7 @@ pub async fn run_graph_with_hooks(
|
|||
emitter,
|
||||
sandbox,
|
||||
graph,
|
||||
settings,
|
||||
run_options,
|
||||
InitializedOptions {
|
||||
hook_runner: Some(hook_runner),
|
||||
env: env.unwrap_or_default(),
|
||||
|
|
@ -95,7 +95,7 @@ pub async fn run_graph_from_checkpoint(
|
|||
emitter: Arc<EventEmitter>,
|
||||
sandbox: Arc<dyn Sandbox>,
|
||||
graph: &fabro_graphviz::graph::Graph,
|
||||
settings: &RunOptions,
|
||||
run_options: &RunOptions,
|
||||
checkpoint: &Checkpoint,
|
||||
) -> Result<Outcome> {
|
||||
let executed = pipeline::execute(initialized(
|
||||
|
|
@ -103,7 +103,7 @@ pub async fn run_graph_from_checkpoint(
|
|||
emitter,
|
||||
sandbox,
|
||||
graph,
|
||||
settings,
|
||||
run_options,
|
||||
InitializedOptions {
|
||||
hook_runner: None,
|
||||
env: HashMap::new(),
|
||||
|
|
@ -137,7 +137,7 @@ impl WorkflowRunner {
|
|||
pub async fn run(
|
||||
&self,
|
||||
graph: &fabro_graphviz::graph::Graph,
|
||||
settings: &RunOptions,
|
||||
run_options: &RunOptions,
|
||||
) -> Result<Outcome> {
|
||||
let registry = self
|
||||
.registry
|
||||
|
|
@ -150,7 +150,7 @@ impl WorkflowRunner {
|
|||
Arc::clone(&self.emitter),
|
||||
Arc::clone(&self.sandbox),
|
||||
graph,
|
||||
settings,
|
||||
run_options,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
|
@ -158,7 +158,7 @@ impl WorkflowRunner {
|
|||
pub async fn run_from_checkpoint(
|
||||
&self,
|
||||
graph: &fabro_graphviz::graph::Graph,
|
||||
settings: &RunOptions,
|
||||
run_options: &RunOptions,
|
||||
checkpoint: &Checkpoint,
|
||||
) -> Result<Outcome> {
|
||||
let registry = self
|
||||
|
|
@ -172,7 +172,7 @@ impl WorkflowRunner {
|
|||
Arc::clone(&self.emitter),
|
||||
Arc::clone(&self.sandbox),
|
||||
graph,
|
||||
settings,
|
||||
run_options,
|
||||
checkpoint,
|
||||
)
|
||||
.await
|
||||
|
|
|
|||
|
|
@ -388,7 +388,7 @@ async fn daytona_pipeline_artifact_offload_and_sync() {
|
|||
registry.register("exit", Box::new(ExitHandler));
|
||||
|
||||
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::new()), env.clone());
|
||||
let config = RunOptions {
|
||||
let run_options = RunOptions {
|
||||
config: FabroConfig::default(),
|
||||
run_dir: dir.path().to_path_buf(),
|
||||
cancel_token: None,
|
||||
|
|
@ -403,7 +403,7 @@ async fn daytona_pipeline_artifact_offload_and_sync() {
|
|||
git: None,
|
||||
};
|
||||
let outcome = engine
|
||||
.run(&graph, &config)
|
||||
.run(&graph, &run_options)
|
||||
.await
|
||||
.expect("pipeline should succeed");
|
||||
assert_eq!(outcome.status, StageStatus::Success);
|
||||
|
|
@ -579,7 +579,7 @@ async fn daytona_git_checkpoint_remote_emits_events() {
|
|||
registry.register("exit", Box::new(ExitHandler));
|
||||
|
||||
let engine = WorkflowRunner::new(registry, Arc::new(emitter), env.clone());
|
||||
let config = RunOptions {
|
||||
let run_options = RunOptions {
|
||||
config: FabroConfig::default(),
|
||||
run_dir: dir.path().to_path_buf(),
|
||||
cancel_token: None,
|
||||
|
|
@ -598,7 +598,7 @@ async fn daytona_git_checkpoint_remote_emits_events() {
|
|||
}),
|
||||
};
|
||||
let outcome = engine
|
||||
.run(&graph, &config)
|
||||
.run(&graph, &run_options)
|
||||
.await
|
||||
.expect("pipeline should succeed");
|
||||
assert_eq!(outcome.status, StageStatus::Success);
|
||||
|
|
@ -765,7 +765,7 @@ async fn daytona_parallel_git_branching_e2e() {
|
|||
|
||||
let engine = WorkflowRunner::new(registry, Arc::new(emitter), Arc::clone(&env));
|
||||
|
||||
let config = RunOptions {
|
||||
let run_options = RunOptions {
|
||||
config: FabroConfig::default(),
|
||||
run_dir: run_tmp.path().to_path_buf(),
|
||||
cancel_token: None,
|
||||
|
|
@ -784,7 +784,7 @@ async fn daytona_parallel_git_branching_e2e() {
|
|||
}),
|
||||
};
|
||||
let outcome = engine
|
||||
.run(&graph, &config)
|
||||
.run(&graph, &run_options)
|
||||
.await
|
||||
.expect("daytona parallel pipeline should succeed");
|
||||
assert_eq!(
|
||||
|
|
@ -1141,7 +1141,7 @@ async fn daytona_git_checkpoint_with_shadow_branch() {
|
|||
|
||||
let meta_branch = MetadataStore::branch_name(&run_id);
|
||||
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::new()), env.clone());
|
||||
let config = RunOptions {
|
||||
let run_options = RunOptions {
|
||||
config: FabroConfig::default(),
|
||||
run_dir: dir.path().to_path_buf(),
|
||||
cancel_token: None,
|
||||
|
|
@ -1160,7 +1160,7 @@ async fn daytona_git_checkpoint_with_shadow_branch() {
|
|||
}),
|
||||
};
|
||||
let outcome = engine
|
||||
.run(&graph, &config)
|
||||
.run(&graph, &run_options)
|
||||
.await
|
||||
.expect("pipeline should succeed");
|
||||
assert_eq!(outcome.status, StageStatus::Success);
|
||||
|
|
@ -1281,7 +1281,7 @@ async fn daytona_asset_collection() {
|
|||
graph.edges.push(Edge::new("start", "create_assets"));
|
||||
graph.edges.push(Edge::new("create_assets", "exit"));
|
||||
|
||||
let config = RunOptions {
|
||||
let run_options = RunOptions {
|
||||
config: FabroConfig {
|
||||
assets: Some(fabro_config::run::AssetsConfig {
|
||||
include: vec!["test-results/**".to_string()],
|
||||
|
|
@ -1301,7 +1301,7 @@ async fn daytona_asset_collection() {
|
|||
git: None,
|
||||
};
|
||||
let outcome = engine
|
||||
.run(&graph, &config)
|
||||
.run(&graph, &run_options)
|
||||
.await
|
||||
.expect("pipeline should succeed");
|
||||
assert_eq!(outcome.status, StageStatus::Success);
|
||||
|
|
@ -1537,7 +1537,7 @@ async fn daytona_git_push_run_branch_to_origin() {
|
|||
registry.register("exit", Box::new(ExitHandler));
|
||||
|
||||
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::new()), env.clone());
|
||||
let config = RunOptions {
|
||||
let run_options = RunOptions {
|
||||
config: FabroConfig::default(),
|
||||
run_dir: dir.path().to_path_buf(),
|
||||
cancel_token: None,
|
||||
|
|
@ -1556,7 +1556,7 @@ async fn daytona_git_push_run_branch_to_origin() {
|
|||
}),
|
||||
};
|
||||
let outcome = engine
|
||||
.run(&graph, &config)
|
||||
.run(&graph, &run_options)
|
||||
.await
|
||||
.expect("pipeline should succeed");
|
||||
assert_eq!(outcome.status, StageStatus::Success);
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue