huskies: merge 982
This commit is contained in:
@@ -11,8 +11,8 @@ use std::path::Path;
|
||||
use std::process::Command;
|
||||
|
||||
use crate::pipeline_state::{
|
||||
ApplyError, ArchiveReason, BranchName, GitSha, PipelineEvent, Stage, TransitionFired,
|
||||
apply_transition, stage_label,
|
||||
ApplyError, ArchiveReason, BranchName, GitSha, MergeFailureKind, PipelineEvent, Stage,
|
||||
TransitionFired, apply_transition, stage_label,
|
||||
};
|
||||
use crate::slog;
|
||||
|
||||
@@ -246,10 +246,12 @@ pub fn transition_to_blocked(story_id: &str, reason: &str) -> Result<(), String>
|
||||
/// Transition a story from `Stage::Merge` (or `Stage::MergeFailure`) 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 the typed `MergeJob.error` CRDT register so it survives server
|
||||
/// restarts (story 929: the legacy YAML write of `merge_failure: "..."` is gone).
|
||||
/// Builds a `PipelineEvent::MergeFailed { kind }`, validates the transition,
|
||||
/// writes the resulting `Stage::MergeFailure` to the CRDT, and persists two
|
||||
/// display-only copies for status tools:
|
||||
/// - `ContentKey::GateOutput`: the kind's gate-output string so the CRDT
|
||||
/// projection layer can reconstruct the kind after a server restart.
|
||||
/// - `MergeJob.error`: human-readable description for status renderers.
|
||||
///
|
||||
/// When the story is already in `MergeFailure`, this is a silent self-loop: the
|
||||
/// returned `TransitionFired::before` will be `Stage::MergeFailure`. Callers
|
||||
@@ -258,26 +260,27 @@ pub fn transition_to_blocked(story_id: &str, reason: &str) -> Result<(), String>
|
||||
/// Returns `Err` on `TransitionError` — callers must NOT fall back to direct register writes.
|
||||
pub fn transition_to_merge_failure(
|
||||
story_id: &str,
|
||||
reason: &str,
|
||||
kind: MergeFailureKind,
|
||||
) -> Result<TransitionFired, String> {
|
||||
let fired = apply_transition(
|
||||
story_id,
|
||||
PipelineEvent::MergeFailed {
|
||||
reason: reason.to_string(),
|
||||
},
|
||||
None,
|
||||
)
|
||||
.map_err(|e| e.to_string())?;
|
||||
let display = kind.display_reason();
|
||||
let gate_output = kind.to_gate_output();
|
||||
|
||||
// Persist the failure reason on the MergeJob CRDT entry so display tools
|
||||
// (status_tools, chat status renderer, pipeline.rs::load_pipeline_state)
|
||||
// can surface it without re-parsing YAML.
|
||||
let fired = apply_transition(story_id, PipelineEvent::MergeFailed { kind }, None)
|
||||
.map_err(|e| e.to_string())?;
|
||||
|
||||
// Persist gate-output string so the CRDT projection can reconstruct the
|
||||
// MergeFailureKind on server restart (display-only; scheduling uses the
|
||||
// typed kind from the Stage variant).
|
||||
crate::db::write_content(crate::db::ContentKey::GateOutput(story_id), &gate_output);
|
||||
|
||||
// Persist human-readable description on the MergeJob CRDT entry so display
|
||||
// tools (status renderer, pipeline state view) can surface it.
|
||||
crate::crdt_state::write_merge_job(
|
||||
story_id,
|
||||
"failed",
|
||||
chrono::Utc::now().timestamp() as f64,
|
||||
None,
|
||||
Some(reason),
|
||||
Some(&display),
|
||||
);
|
||||
|
||||
Ok(fired)
|
||||
|
||||
Reference in New Issue
Block a user