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) <noreply@anthropic.com>
This commit is contained in:
Bryan Helmkamp 2026-03-15 21:51:52 -04:00
parent cf7ceb4665
commit 2cd12471f9
2 changed files with 64 additions and 57 deletions

View file

@ -7,6 +7,7 @@ root = "fabro/"
retros = false
[pull_request]
enabled = true
draft = false
[sandbox]

View file

@ -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<String> = None;
let mut pr_url: Option<String> = 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:")
);
}
}
}
}