use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Artifact {
pub id: Uuid,
pub run_id: Uuid,
pub step_id: Uuid,
pub name: String,
pub storage_key: String,
pub content_type: String,
pub size_bytes: u64,
pub sha256: String,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct NewArtifact {
pub id: Uuid,
pub run_id: Uuid,
pub step_id: Uuid,
pub name: String,
pub storage_key: String,
pub content_type: String,
pub size_bytes: u64,
pub sha256: String,
}
#[derive(Debug, Clone)]
pub struct ArtifactLookup {
pub run_id: Uuid,
pub attempt: u32,
pub before_position: u32,
pub step_name: String,
pub name: String,
}
#[cfg(test)]
mod tests {
use super::*;
fn sample() -> Artifact {
Artifact {
id: Uuid::now_v7(),
run_id: Uuid::now_v7(),
step_id: Uuid::now_v7(),
name: "report.html".to_string(),
storage_key: "artifacts/a/b/c".to_string(),
content_type: "text/html".to_string(),
size_bytes: 142,
sha256: "0".repeat(64),
created_at: Utc::now(),
updated_at: Utc::now(),
}
}
#[test]
fn artifact_serde_roundtrips() {
let artifact = sample();
let json = serde_json::to_string(&artifact).expect("serialize");
let parsed: Artifact = serde_json::from_str(&json).expect("deserialize");
assert_eq!(parsed.name, artifact.name);
assert_eq!(parsed.sha256, artifact.sha256);
assert_eq!(parsed.size_bytes, artifact.size_bytes);
}
#[test]
fn artifact_exposes_the_storage_key() {
let json = serde_json::to_string(&sample()).expect("serialize");
assert!(json.contains("storage_key"));
}
#[test]
fn new_artifact_serde_roundtrips() {
let req = NewArtifact {
id: Uuid::now_v7(),
run_id: Uuid::now_v7(),
step_id: Uuid::now_v7(),
name: "build.log".to_string(),
storage_key: "artifacts/a/b/c".to_string(),
content_type: "text/plain".to_string(),
size_bytes: 0,
sha256: "0".repeat(64),
};
let json = serde_json::to_string(&req).expect("serialize");
let parsed: NewArtifact = serde_json::from_str(&json).expect("deserialize");
assert_eq!(parsed.name, "build.log");
assert_eq!(parsed.size_bytes, 0);
}
}