Skip to main content

smbcloud_model/
artifact_deployment.rs

1//! Static deploy over HTTPS: the shapes shared by the CLI and the API.
2//!
3//! The server validates and owns all of this; the client builds the manifest
4//! and reads the status back.
5
6use serde::{Deserialize, Serialize};
7
8/// One file in a deployment manifest. `path` is relative, `/`-separated.
9#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
10pub struct ArtifactFile {
11    pub path: String,
12    pub sha256: String,
13    pub size: u64,
14}
15
16/// `POST /v1/apps/:app_id/artifact_deployments`.
17#[derive(Debug, Clone, Serialize)]
18pub struct CreateArtifactDeployment {
19    pub manifest: Vec<ArtifactFile>,
20    #[serde(skip_serializing_if = "Option::is_none")]
21    pub commit_sha: Option<String>,
22}
23
24/// An artifact deployment as the API returns it. `missing` and
25/// `upload_url_base` are only present on the create response.
26#[derive(Debug, Clone, Deserialize)]
27pub struct ArtifactDeployment {
28    pub id: String,
29    pub status: String,
30    #[serde(default)]
31    pub error: Option<String>,
32    #[serde(default)]
33    pub url: Option<String>,
34    #[serde(default)]
35    pub missing: Vec<String>,
36    #[serde(default)]
37    pub upload_url_base: Option<String>,
38    #[serde(default)]
39    pub file_count: Option<u64>,
40    #[serde(default)]
41    pub total_bytes: Option<u64>,
42    #[serde(default)]
43    pub commit_sha: Option<String>,
44}
45
46impl ArtifactDeployment {
47    /// `live`, `failed`, `expired` and `superseded` end a deploy's wait.
48    pub fn is_terminal(&self) -> bool {
49        matches!(
50            self.status.as_str(),
51            "live" | "failed" | "expired" | "superseded"
52        )
53    }
54}
55
56#[cfg(test)]
57mod tests {
58    use super::*;
59
60    #[test]
61    fn parses_a_create_response() {
62        let d: ArtifactDeployment = serde_json::from_str(
63            r#"{"id":"x","status":"uploading","missing":["ab"],"upload_url_base":"https://h/blobs","url":null}"#,
64        )
65        .unwrap();
66        assert_eq!(d.missing, ["ab"]);
67        assert!(!d.is_terminal());
68    }
69}