Files
huskies/server/src/agents/merge/mod.rs
T

89 lines
2.8 KiB
Rust
Raw Normal View History

//! Merge operations — rebases agent work onto master and runs post-merge validation.
2026-04-28 10:19:43 +00:00
use serde::{Deserialize, Serialize};
mod squash;
pub(crate) use squash::run_squash_merge;
2026-05-13 16:26:09 +00:00
/// Typed outcome of a completed squash-merge operation.
///
/// Each variant captures only the fields relevant to that outcome, eliminating
/// the four-bool soup of the old `MergeReport`.
#[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(tag = "kind")]
pub enum MergeResult {
/// Squash commit landed on the base branch and all quality gates passed.
Success {
/// `true` when conflicts were detected and automatically resolved.
conflicts_resolved: bool,
conflict_details: Option<String>,
/// Human-readable output from the quality-gate run.
gate_output: String,
},
/// Merge was aborted due to unresolvable conflicts; base branch is untouched.
Conflict {
details: Option<String>,
output: String,
},
/// Squash commit produced but quality gates failed; base branch may carry the commit.
GateFailure {
output: String,
#[serde(default)]
failure_kind: Option<crate::agents::gates::GateFailureKind>,
},
/// Feature branch had zero commits ahead of the base branch.
NoCommits { output: String },
/// Unclassified failure (cherry-pick failed, git error, etc.).
Other {
output: String,
conflict_details: Option<String>,
},
}
impl MergeResult {
/// Extract the human-readable output string from any variant.
pub fn output(&self) -> &str {
match self {
Self::Success { gate_output, .. } => gate_output,
Self::Conflict { output, .. }
| Self::GateFailure { output, .. }
| Self::NoCommits { output }
| Self::Other { output, .. } => output,
}
}
}
/// Status of an async merge job.
#[derive(Debug, Clone, Serialize)]
pub enum MergeJobStatus {
Running,
Completed(MergeReport),
Failed(String),
}
/// Tracks a background merge job started by `merge_agent_work`.
#[derive(Debug, Clone, Serialize)]
pub struct MergeJob {
pub story_id: String,
pub status: MergeJobStatus,
/// Server start-time (Unix seconds) of the server instance that started
/// this job.
///
/// Used by stale-lock recovery: on a new merge attempt the system checks
/// every Running entry and removes any whose recorded start-time is older
/// than the current server's boot time. This survives `rebuild_and_restart`
/// (which re-execs and keeps the same PID).
pub server_start_time: f64,
}
/// Result of a mergemaster merge operation.
2026-04-28 10:19:43 +00:00
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct MergeReport {
pub story_id: String,
2026-05-13 16:26:09 +00:00
/// Typed outcome of the merge operation.
pub result: MergeResult,
pub worktree_cleaned_up: bool,
pub story_archived: bool,
}