From 2cd12471f9d59fbca75485d9f59a2c0605f7436b Mon Sep 17 00:00:00 2001 From: Bryan Helmkamp Date: Sun, 15 Mar 2026 21:51:52 -0400 Subject: [PATCH] Enable auto PR creation and add debug logging for skipped PR cases The `[pull_request]` config in fabro.toml was missing `enabled = true`, so workflow runs silently skipped PR creation. Additionally, four skip paths in the PR creation logic had no logging at all, making it hard to diagnose why a PR wasn't opened. Added debug-level logs for: config not enabled, dry-run mode, engine error, and non-success run status. Co-Authored-By: Claude Opus 4.6 (1M context) --- fabro.toml | 1 + lib/crates/fabro-workflows/src/cli/run.rs | 120 ++++++++++++---------- 2 files changed, 64 insertions(+), 57 deletions(-) diff --git a/fabro.toml b/fabro.toml index 9e58abca0..e823e6866 100644 --- a/fabro.toml +++ b/fabro.toml @@ -7,6 +7,7 @@ root = "fabro/" retros = false [pull_request] +enabled = true draft = false [sandbox] diff --git a/lib/crates/fabro-workflows/src/cli/run.rs b/lib/crates/fabro-workflows/src/cli/run.rs index e0ab146b8..749f8882d 100644 --- a/lib/crates/fabro-workflows/src/cli/run.rs +++ b/lib/crates/fabro-workflows/src/cli/run.rs @@ -1416,67 +1416,73 @@ pub async fn run_command( // Auto-create PR on successful completion (skip in dry-run mode) let mut pushed_branch: Option = None; let mut pr_url: Option = None; - if config.pull_request_enabled && !dry_run_mode { - if let Ok(ref outcome) = engine_result { - if matches!( - outcome.status, - StageStatus::Success | StageStatus::PartialSuccess + if !config.pull_request_enabled { + debug!("Skipping PR creation: pull_request not enabled in config"); + } else if dry_run_mode { + debug!("Skipping PR creation: dry-run mode"); + } else if let Err(ref e) = engine_result { + debug!(error = %e, "Skipping PR creation: engine returned an error"); + } else if let Ok(ref outcome) = engine_result { + if !matches!( + outcome.status, + StageStatus::Success | StageStatus::PartialSuccess + ) { + debug!(status = ?outcome.status, "Skipping PR creation: run status is not success"); + } else { + let diff = tokio::fs::read_to_string(run_dir.join("final.patch")) + .await + .unwrap_or_default(); + if let ( + Some(ref base_branch), + Some(ref run_branch), + Some(ref creds), + Some(ref origin), + ) = ( + &config.base_branch, + &config.run_branch, + &github_app, + &origin_url, ) { - let diff = tokio::fs::read_to_string(run_dir.join("final.patch")) - .await - .unwrap_or_default(); - if let ( - Some(ref base_branch), - Some(ref run_branch), - Some(ref creds), - Some(ref origin), - ) = ( - &config.base_branch, - &config.run_branch, - &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()); - } + // 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()); + } - match crate::pull_request::maybe_open_pull_request( - creds, - origin, - base_branch, - run_branch, - graph.goal(), - &diff, - &model, - config.pull_request_draft, - &run_dir, - ) - .await - { - Ok(Some(record)) => { - emitter.emit(&crate::event::WorkflowRunEvent::PullRequestCreated { - pr_url: record.html_url.clone(), - pr_number: record.number, - draft: config.pull_request_draft, - }); - pr_url = Some(record.html_url.clone()); - if let Err(e) = record.save(&run_dir.join("pull_request.json")) { - tracing::warn!(error = %e, "Failed to save pull_request.json"); - } - } - Ok(None) => {} // empty diff, logged at DEBUG - Err(e) => { - emitter.emit(&crate::event::WorkflowRunEvent::PullRequestFailed { - error: e.to_string(), - }); - eprintln!( - "{} PR creation failed: {e}", - styles.yellow.apply_to("Warning:") - ); + match crate::pull_request::maybe_open_pull_request( + creds, + origin, + base_branch, + run_branch, + graph.goal(), + &diff, + &model, + config.pull_request_draft, + &run_dir, + ) + .await + { + Ok(Some(record)) => { + emitter.emit(&crate::event::WorkflowRunEvent::PullRequestCreated { + pr_url: record.html_url.clone(), + pr_number: record.number, + draft: config.pull_request_draft, + }); + pr_url = Some(record.html_url.clone()); + if let Err(e) = record.save(&run_dir.join("pull_request.json")) { + tracing::warn!(error = %e, "Failed to save pull_request.json"); } } + Ok(None) => {} // empty diff, logged at DEBUG + Err(e) => { + emitter.emit(&crate::event::WorkflowRunEvent::PullRequestFailed { + error: e.to_string(), + }); + eprintln!( + "{} PR creation failed: {e}", + styles.yellow.apply_to("Warning:") + ); + } } } }