canic-host 0.68.2

Host-side build, install, deployment, and fleet-template library for Canic workspaces
Documentation
use super::InstallRootOptions;
use super::phase_receipts::{completed_phase_role_receipt, receipt_with_execution_context};
use super::receipt_io::write_artifact_promotion_execution_receipt;
use crate::deployment_truth::{
    ArtifactPromotionExecutionReceiptRequest, ArtifactPromotionPlanV1,
    ArtifactPromotionProvenanceReportRequest, DeploymentCheckV1, DeploymentCommandResultV1,
    DeploymentExecutionContextV1, DeploymentExecutionStatusV1, DeploymentReceiptV1,
    ObservationStatusV1, RolePhaseResultV1, artifact_promotion_execution_receipt,
    artifact_promotion_provenance_report, deployment_receipt_from_check_with_status, phase_receipt,
};
use std::path::{Path, PathBuf};

pub(super) fn write_artifact_promotion_execution_receipt_for_install(
    options: &InstallRootOptions,
    icp_root: &Path,
    network: &str,
    deployment_name: &str,
    check: &DeploymentCheckV1,
    execution_context: &DeploymentExecutionContextV1,
) -> Result<Option<PathBuf>, Box<dyn std::error::Error>> {
    let Some(promotion_plan) = &options.artifact_promotion_plan_override else {
        return Ok(None);
    };
    let deployment_receipt =
        promotion_install_deployment_receipt(check, execution_context, promotion_plan)?;
    let provenance_report =
        artifact_promotion_provenance_report(ArtifactPromotionProvenanceReportRequest {
            report_id: format!("{}:execution-provenance", promotion_plan.plan_id),
            artifact_promotion_plan: promotion_plan.clone(),
            wasm_store_identity_report: None,
            wasm_store_catalog_verification: None,
            materialization_identity_report: None,
        })?;
    let receipt = artifact_promotion_execution_receipt(ArtifactPromotionExecutionReceiptRequest {
        receipt_id: format!("{}:execution-receipt", promotion_plan.plan_id),
        provenance_report,
        deployment_receipt,
    })?;
    let path =
        write_artifact_promotion_execution_receipt(icp_root, network, deployment_name, &receipt)?;
    println!(
        "Artifact promotion execution receipt JSON: {}",
        path.display()
    );
    Ok(Some(path))
}

fn promotion_install_deployment_receipt(
    check: &DeploymentCheckV1,
    execution_context: &DeploymentExecutionContextV1,
    promotion_plan: &ArtifactPromotionPlanV1,
) -> Result<DeploymentReceiptV1, Box<dyn std::error::Error>> {
    let started_at = super::current_unix_timestamp_label()?;
    let finished_at = super::current_unix_timestamp_label()?;
    let phase = phase_receipt(
        "promoted_plan_install",
        started_at.clone(),
        Some(finished_at.clone()),
        "execute promoted deployment plan through current install runner",
        ObservationStatusV1::Observed,
        vec![
            format!("artifact_promotion_plan:{}", promotion_plan.plan_id),
            format!(
                "artifact_promotion_plan_digest:{}",
                promotion_plan.artifact_promotion_plan_digest
            ),
            format!(
                "promotion_plan_lineage_digest:{}",
                promotion_plan.promotion_plan_lineage_digest
            ),
        ],
    );
    let role_phase_receipts = promotion_plan
        .transform
        .roles
        .iter()
        .map(|role| {
            completed_phase_role_receipt(
                check,
                "promoted_plan_install",
                &role.role,
                RolePhaseResultV1::Applied,
                None,
            )
            .ok_or_else(|| {
                format!(
                    "promoted role {} is missing from deployment plan artifacts",
                    role.role
                )
            })
        })
        .collect::<Result<Vec<_>, _>>()?;
    Ok(receipt_with_execution_context(
        deployment_receipt_from_check_with_status(
            check,
            format!("{}:promoted_plan_install", check.check_id),
            DeploymentExecutionStatusV1::Complete,
            started_at,
            Some(finished_at),
            vec![phase],
            role_phase_receipts,
            DeploymentCommandResultV1::Succeeded,
        ),
        execution_context,
    ))
}