1use std::path::PathBuf;
2
3use canic_core::ids::BuildNetwork;
4use serde::{Deserialize, Serialize};
5
6use crate::{
7 canister_build::{CanisterArtifactBuildOutput, CanisterBuildProfile},
8 evidence_envelope::{
9 CommandProvenanceV1, EvidenceMessageV1, InputFingerprintV1, InputPathDisplayV1,
10 },
11};
12
13pub const BUILD_PROVENANCE_SCHEMA_ID: &str = "canic.build_provenance.v1";
14pub(super) const WASM_TARGET: &str = "wasm32-unknown-unknown";
15pub(super) const DIRTY_SUMMARY_ALGORITHM: &str = "git-status-porcelain-v1-z-sha256";
16
17#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
21pub struct BuildProvenanceV1 {
22 pub schema_version: u8,
23 pub generated_at: String,
24 pub canic_version: String,
25 pub command: CommandProvenanceV1,
26 pub build_status: BuildProvenanceStatusV1,
27 pub source: SourceProvenanceV1,
28 pub cargo: CargoProvenanceV1,
29 pub protocol_profile: ProtocolProfileProvenanceV1,
30 pub artifacts: Vec<ArtifactProvenanceV1>,
31 pub transforms: Vec<ArtifactTransformProvenanceV1>,
32 pub warnings: Vec<EvidenceMessageV1>,
33}
34
35#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
37pub struct ProtocolProfileProvenanceV1 {
38 pub candid_sha256: String,
39 pub protocol_profile_digest: String,
40}
41
42#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
46#[serde(rename_all = "snake_case")]
47pub enum BuildProvenanceStatusV1 {
48 Success,
49 Failed,
50 NotRecorded,
51}
52
53#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
57pub struct SourceProvenanceV1 {
58 pub schema_version: u8,
59 pub vcs: SourceVcsV1,
60 pub revision: Option<String>,
61 pub branch: Option<String>,
62 pub dirty: Option<bool>,
63 pub dirty_policy: SourceDirtyPolicyV1,
64 pub dirty_summary_digest: Option<String>,
65 pub dirty_summary_algorithm: Option<String>,
66}
67
68#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
72#[serde(rename_all = "snake_case")]
73pub enum SourceVcsV1 {
74 Git,
75 Unknown,
76}
77
78#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
82#[serde(rename_all = "snake_case")]
83pub enum SourceDirtyPolicyV1 {
84 Clean,
85 DirtyRecorded,
86 Unknown,
87}
88
89#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
93pub struct CargoProvenanceV1 {
94 pub cargo_lock_sha256: Option<String>,
95 pub package_manifest_sha256: Option<String>,
96 pub package_name: String,
97 pub package_manifest: String,
98 pub package_metadata_app: String,
99 pub package_metadata_role: String,
100 pub rustc_version: Option<String>,
101 pub cargo_version: Option<String>,
102 pub target: Option<String>,
103 pub profile: String,
104 pub features: Vec<String>,
105 pub default_features: Option<bool>,
106 pub rustflags_digest: Option<String>,
107 pub rustflags_digest_algorithm: Option<String>,
108 pub cargo_config_fingerprints: Vec<InputFingerprintV1>,
109 pub build_script_inputs: BuildScriptInputStateV1,
110}
111
112#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
116#[serde(rename_all = "snake_case")]
117pub enum BuildScriptInputStateV1 {
118 NotRecorded,
119 Recorded,
120 Unknown,
121}
122
123#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
127pub struct ArtifactProvenanceV1 {
128 pub role: String,
129 pub app: String,
130 pub artifact_kind: ArtifactProvenanceKindV1,
131 pub path: Option<String>,
132 pub path_display: InputPathDisplayV1,
133 pub hash_algorithm: String,
134 pub sha256: String,
135 pub size_bytes: u64,
136 pub produced_by: String,
137}
138
139#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
143#[serde(rename_all = "snake_case")]
144pub enum ArtifactProvenanceKindV1 {
145 Wasm,
146 WasmGzip,
147 Candid,
148 Metadata,
149 Other,
150}
151
152#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
156pub struct ArtifactTransformProvenanceV1 {
157 pub role: String,
158 pub transform: ArtifactTransformKindV1,
159 pub tool: String,
160 pub tool_version: Option<String>,
161 pub outcome: ArtifactTransformOutcomeV1,
162}
163
164#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
166#[serde(rename_all = "snake_case")]
167pub enum ArtifactTransformKindV1 {
168 Shrink,
169 CandidMetadata,
170}
171
172#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
174#[serde(rename_all = "snake_case")]
175pub enum ArtifactTransformOutcomeV1 {
176 Applied,
177 ToolUnavailable,
178 NotRequested,
179}
180
181#[derive(Clone, Debug)]
185pub struct BuildProvenanceRequest {
186 pub app: String,
187 pub role: String,
188 pub environment: String,
189 pub build_network: BuildNetwork,
190 pub profile: CanisterBuildProfile,
191 pub workspace_root: PathBuf,
192 pub config_path: PathBuf,
193 pub output: CanisterArtifactBuildOutput,
194 pub command: CommandProvenanceV1,
195 pub generated_at: String,
196 pub canic_version: String,
197}