use chrono::{DateTime, Utc};
use schemars::JsonSchema as DeriveJsonSchema;
use serde::{Deserialize, Serialize};
use uuid::Uuid;
use crate::executor::SnapshotRef;
#[derive(
Debug,
Clone,
Copy,
PartialEq,
Eq,
Serialize,
Deserialize,
DeriveJsonSchema,
derive_more::IsVariant,
)]
#[serde(rename_all = "snake_case")]
pub enum StdStream {
Stdout,
Stderr,
}
#[derive(
Debug, Clone, PartialEq, Eq, Serialize, Deserialize, DeriveJsonSchema, derive_more::IsVariant,
)]
#[serde(tag = "kind", rename_all = "snake_case")]
#[non_exhaustive]
pub enum BuildEvent {
BuildStart {
run_id: Uuid,
plan: PlanSummary,
started_at: DateTime<Utc>,
},
BuildAccepted {
build: BuildRef,
watch_url: Option<String>,
},
StepQueued {
step_id: Uuid,
key: String,
chain_idx: usize,
parent_key: Option<String>,
display_name: String,
},
StepStart {
step_id: Uuid,
runner: String,
image: Option<String>,
},
StepLog {
step_id: Uuid,
stream: StdStream,
line: String,
ts: DateTime<Utc>,
},
StepCacheHit {
step_id: Uuid,
key: String,
tag: String,
},
StepEnd {
step_id: Uuid,
exit_code: i32,
duration_ms: u64,
snapshot: Option<SnapshotRef>,
},
ChainFailed {
chain_idx: usize,
failed_step_id: Uuid,
failed_step_key: String,
exit_code: i32,
message: String,
ts: DateTime<Utc>,
},
BuildEnd {
exit_code: i32,
duration_ms: u64,
},
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, DeriveJsonSchema)]
pub struct BuildRef {
pub run_id: Uuid,
pub number: Option<i64>,
pub org: Option<String>,
pub pipeline: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, DeriveJsonSchema)]
pub struct PlanSummary {
pub step_count: usize,
pub chain_count: usize,
pub default_runner: String,
}
#[cfg(test)]
mod tests {
use super::*;
#[allow(clippy::unwrap_used)]
#[test]
fn build_accepted_round_trips() {
let ev = BuildEvent::BuildAccepted {
build: BuildRef {
run_id: uuid::Uuid::nil(),
number: Some(42),
org: Some("acme".into()),
pipeline: "ci".into(),
},
watch_url: Some("https://app.harmont.dev/acme/ci/builds/42".into()),
};
let s = serde_json::to_string(&ev).unwrap();
let back: BuildEvent = serde_json::from_str(&s).unwrap();
assert!(matches!(back, BuildEvent::BuildAccepted { .. }));
}
}