huskies: merge 868
This commit is contained in:
@@ -248,6 +248,28 @@ pub fn transition_to_blocked(story_id: &str, reason: &str) -> Result<(), String>
|
||||
.map_err(|e| e.to_string())
|
||||
}
|
||||
|
||||
/// Transition a story from `Stage::Merge` to `Stage::MergeFailure` via the state machine.
|
||||
///
|
||||
/// Builds a `PipelineEvent::MergeFailed { reason }`, validates the transition, writes
|
||||
/// the resulting `Stage::MergeFailure` to the CRDT, and persists the reason to front
|
||||
/// matter so it survives server restarts.
|
||||
/// Returns `Err` on `TransitionError` — callers must NOT fall back to direct register writes.
|
||||
pub fn transition_to_merge_failure(story_id: &str, reason: &str) -> Result<(), String> {
|
||||
let reason_owned = reason.to_string();
|
||||
let transform: Box<dyn Fn(&str) -> String> = Box::new(move |content: &str| {
|
||||
crate::io::story_metadata::write_merge_failure_in_content(content, &reason_owned)
|
||||
});
|
||||
apply_transition(
|
||||
story_id,
|
||||
PipelineEvent::MergeFailed {
|
||||
reason: reason.to_string(),
|
||||
},
|
||||
Some(&*transform),
|
||||
)
|
||||
.map(|_| ())
|
||||
.map_err(|e| e.to_string())
|
||||
}
|
||||
|
||||
/// Transition a story out of `Blocked` back to `Coding` via the state machine.
|
||||
///
|
||||
/// Builds a `PipelineEvent::Unblock`, validates the transition, writes the
|
||||
@@ -301,6 +323,7 @@ fn map_stage_move_to_event(
|
||||
}),
|
||||
(Stage::Coding | Stage::Qa | Stage::Backlog, "done") => Ok(PipelineEvent::Close),
|
||||
(Stage::Blocked { .. }, "current") => Ok(PipelineEvent::Unblock),
|
||||
(Stage::MergeFailure { .. }, "backlog") => Ok(PipelineEvent::Unblock),
|
||||
(
|
||||
Stage::Archived {
|
||||
reason: ArchiveReason::Blocked { .. },
|
||||
@@ -388,6 +411,7 @@ fn stage_to_name(s: &Stage) -> &'static str {
|
||||
Stage::Blocked { .. } => "blocked",
|
||||
Stage::Qa => "qa",
|
||||
Stage::Merge { .. } => "merge",
|
||||
Stage::MergeFailure { .. } => "merge_failure",
|
||||
Stage::Done { .. } => "done",
|
||||
Stage::Archived { .. } => "archived",
|
||||
Stage::Frozen { .. } => "frozen",
|
||||
|
||||
@@ -114,16 +114,6 @@ impl AgentPool {
|
||||
Err(e) => e.clone(),
|
||||
};
|
||||
let is_no_commits = reason.contains("no commits to merge");
|
||||
if !is_no_commits {
|
||||
// Write merge_failure to content for non-blocking failures.
|
||||
if let Some(contents) = crate::db::read_content(&sid) {
|
||||
let updated = crate::io::story_metadata::write_merge_failure_in_content(
|
||||
&contents, &reason,
|
||||
);
|
||||
crate::db::write_content(&sid, &updated);
|
||||
crate::db::write_item_with_content(&sid, "4_merge", &updated);
|
||||
}
|
||||
}
|
||||
if is_no_commits {
|
||||
if let Err(e) = crate::agents::lifecycle::transition_to_blocked(&sid, &reason) {
|
||||
crate::slog_error!("[merge] Failed to transition '{sid}' to Blocked: {e}");
|
||||
@@ -135,6 +125,14 @@ impl AgentPool {
|
||||
reason,
|
||||
});
|
||||
} else {
|
||||
// Transition through the state machine (Merge → MergeFailure).
|
||||
if let Err(e) =
|
||||
crate::agents::lifecycle::transition_to_merge_failure(&sid, &reason)
|
||||
{
|
||||
crate::slog_error!(
|
||||
"[merge] Failed to transition '{sid}' to MergeFailure: {e}"
|
||||
);
|
||||
}
|
||||
let _ = pool
|
||||
.watcher_tx
|
||||
.send(crate::io::watcher::WatcherEvent::MergeFailure {
|
||||
|
||||
Reference in New Issue
Block a user