1use alloc::{string::String, vec::Vec};
4use core::hash::BuildHasherDefault;
5use fnv::FnvHasher;
6use indexmap::IndexMap;
7
8#[cfg(feature = "schemars")]
9use schemars::JsonSchema;
10#[cfg(feature = "serde")]
11use serde::{Deserialize, Serialize};
12use serde_json::Value;
13
14#[cfg(feature = "time")]
15use time::OffsetDateTime;
16
17use crate::{
18 ArtifactRef, AttestationId, AttestationRef, BranchRef, BuildLogRef, BuildRef, CommitRef,
19 ComponentRef, RegistryRef, RepoRef, SbomRef, ScanRef, SignatureRef, SigningKeyRef,
20 StatementRef, StoreRef, TenantCtx, VersionRef,
21};
22
23pub type SupplyHasher = BuildHasherDefault<FnvHasher>;
25
26#[derive(Clone, Debug, PartialEq)]
28#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
29#[cfg_attr(feature = "schemars", derive(JsonSchema))]
30pub struct BuildPlan {
31 pub build_id: BuildRef,
33 pub component: ComponentRef,
35 #[cfg_attr(
37 feature = "serde",
38 serde(default, skip_serializing_if = "Option::is_none")
39 )]
40 pub branch: Option<BranchRef>,
41 pub source_repo: RepoRef,
43 pub commit: String,
45 #[cfg_attr(
47 feature = "serde",
48 serde(default, skip_serializing_if = "Option::is_none")
49 )]
50 pub commit_ref: Option<CommitRef>,
51 pub language: String,
53 pub entrypoint: String,
55 #[cfg_attr(
57 feature = "serde",
58 serde(default, skip_serializing_if = "IndexMap::is_empty")
59 )]
60 #[cfg_attr(
61 feature = "schemars",
62 schemars(
63 with = "alloc::collections::BTreeMap<String, String>",
64 description = "Environment variables"
65 )
66 )]
67 pub env: IndexMap<String, String, SupplyHasher>,
68 #[cfg_attr(
70 feature = "serde",
71 serde(default, skip_serializing_if = "Vec::is_empty")
72 )]
73 pub outputs: Vec<ArtifactRef>,
74 #[cfg_attr(feature = "serde", serde(default))]
76 pub metadata: Value,
77}
78
79#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
81#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
82#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
83#[cfg_attr(feature = "schemars", derive(JsonSchema))]
84pub enum BuildStatusKind {
85 Pending,
87 Running,
89 Succeeded,
91 Failed,
93 Cancelled,
95}
96
97#[derive(Clone, Debug, PartialEq)]
99#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
100#[cfg_attr(feature = "schemars", derive(JsonSchema))]
101pub struct BuildStatus {
102 pub build_id: BuildRef,
104 pub status: BuildStatusKind,
106 #[cfg_attr(
108 all(feature = "schemars", feature = "time"),
109 schemars(with = "Option<String>", description = "RFC3339 timestamp in UTC")
110 )]
111 #[cfg_attr(
112 feature = "serde",
113 serde(default, skip_serializing_if = "Option::is_none")
114 )]
115 #[cfg(feature = "time")]
116 pub started_at_utc: Option<OffsetDateTime>,
117 #[cfg_attr(
119 all(feature = "schemars", feature = "time"),
120 schemars(with = "Option<String>", description = "RFC3339 timestamp in UTC")
121 )]
122 #[cfg_attr(
123 feature = "serde",
124 serde(default, skip_serializing_if = "Option::is_none")
125 )]
126 #[cfg(feature = "time")]
127 pub finished_at_utc: Option<OffsetDateTime>,
128 #[cfg_attr(
130 feature = "serde",
131 serde(default, skip_serializing_if = "Vec::is_empty")
132 )]
133 pub artifacts: Vec<ArtifactRef>,
134 #[cfg_attr(
136 feature = "serde",
137 serde(default, skip_serializing_if = "Option::is_none")
138 )]
139 pub logs_ref: Option<String>,
140 #[cfg_attr(
142 feature = "serde",
143 serde(default, skip_serializing_if = "Vec::is_empty")
144 )]
145 pub log_refs: Vec<BuildLogRef>,
146 #[cfg_attr(feature = "serde", serde(default))]
148 pub metadata: Value,
149}
150
151#[derive(Clone, Debug, PartialEq, Eq, Hash)]
153#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
154#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
155#[cfg_attr(feature = "schemars", derive(JsonSchema))]
156pub enum ScanKind {
157 Source,
159 Dependencies,
161 Artifact,
163 Custom(String),
165}
166
167#[derive(Clone, Debug, PartialEq)]
169#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
170#[cfg_attr(feature = "schemars", derive(JsonSchema))]
171pub struct ScanRequest {
172 pub scan_id: ScanRef,
174 pub component: ComponentRef,
176 pub kind: ScanKind,
178 #[cfg_attr(
180 feature = "serde",
181 serde(default, skip_serializing_if = "Option::is_none")
182 )]
183 pub commit_ref: Option<CommitRef>,
184 #[cfg_attr(
186 feature = "serde",
187 serde(default, skip_serializing_if = "Option::is_none")
188 )]
189 pub artifact: Option<ArtifactRef>,
190 #[cfg_attr(feature = "serde", serde(default))]
192 pub metadata: Value,
193}
194
195#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
197#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
198#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
199#[cfg_attr(feature = "schemars", derive(JsonSchema))]
200pub enum ScanStatusKind {
201 Pending,
203 Running,
205 Succeeded,
207 Failed,
209}
210
211#[derive(Clone, Debug, PartialEq)]
213#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
214#[cfg_attr(feature = "schemars", derive(JsonSchema))]
215pub struct ScanResult {
216 pub scan_id: ScanRef,
218 pub component: ComponentRef,
220 pub kind: ScanKind,
222 pub status: ScanStatusKind,
224 #[cfg_attr(
226 feature = "serde",
227 serde(default, skip_serializing_if = "Option::is_none")
228 )]
229 pub sbom: Option<SbomRef>,
230 #[cfg_attr(feature = "serde", serde(default))]
232 pub findings: Value,
233 #[cfg_attr(
235 all(feature = "schemars", feature = "time"),
236 schemars(with = "Option<String>", description = "RFC3339 timestamp in UTC")
237 )]
238 #[cfg_attr(
239 feature = "serde",
240 serde(default, skip_serializing_if = "Option::is_none")
241 )]
242 #[cfg(feature = "time")]
243 pub started_at_utc: Option<OffsetDateTime>,
244 #[cfg_attr(
246 all(feature = "schemars", feature = "time"),
247 schemars(with = "Option<String>", description = "RFC3339 timestamp in UTC")
248 )]
249 #[cfg_attr(
250 feature = "serde",
251 serde(default, skip_serializing_if = "Option::is_none")
252 )]
253 #[cfg(feature = "time")]
254 pub finished_at_utc: Option<OffsetDateTime>,
255}
256
257#[derive(Clone, Debug, PartialEq)]
259#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
260#[cfg_attr(feature = "schemars", derive(JsonSchema))]
261pub struct SignRequest {
262 pub signing_key: SigningKeyRef,
264 pub artifact: ArtifactRef,
266 #[cfg_attr(feature = "serde", serde(default))]
268 pub payload: Value,
269 #[cfg_attr(feature = "serde", serde(default))]
271 pub metadata: Value,
272}
273
274#[derive(Clone, Debug, PartialEq)]
276#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
277#[cfg_attr(feature = "schemars", derive(JsonSchema))]
278pub struct VerifyRequest {
279 pub signature: SignatureRef,
281 pub artifact: ArtifactRef,
283 #[cfg_attr(feature = "serde", serde(default))]
285 pub metadata: Value,
286}
287
288#[derive(Clone, Debug, PartialEq)]
290#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
291#[cfg_attr(feature = "schemars", derive(JsonSchema))]
292pub struct VerifyResult {
293 pub signature: SignatureRef,
295 pub valid: bool,
297 #[cfg_attr(
299 feature = "serde",
300 serde(default, skip_serializing_if = "Option::is_none")
301 )]
302 pub message: Option<String>,
303 #[cfg_attr(feature = "serde", serde(default))]
305 pub metadata: Value,
306}
307
308#[derive(Clone, Debug, PartialEq, Eq, Hash)]
310#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
311#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
312#[cfg_attr(feature = "schemars", derive(JsonSchema))]
313pub enum PredicateType {
314 Slsa,
316 Vulnerability,
318 Custom(String),
320}
321
322#[derive(Clone, Debug, PartialEq)]
324#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
325#[cfg_attr(feature = "schemars", derive(JsonSchema))]
326pub struct AttestationStatement {
327 #[cfg_attr(
329 feature = "serde",
330 serde(default, skip_serializing_if = "Option::is_none")
331 )]
332 pub attestation_id: Option<AttestationId>,
333 pub attestation: AttestationRef,
335 pub predicate_type: PredicateType,
337 pub statement: StatementRef,
339 #[cfg_attr(
341 feature = "serde",
342 serde(default, skip_serializing_if = "Option::is_none")
343 )]
344 pub registry: Option<RegistryRef>,
345 #[cfg_attr(
347 feature = "serde",
348 serde(default, skip_serializing_if = "Option::is_none")
349 )]
350 pub store: Option<StoreRef>,
351 #[cfg_attr(feature = "serde", serde(default))]
353 pub metadata: Value,
354}
355
356#[derive(Clone, Debug, PartialEq)]
358#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
359#[cfg_attr(feature = "schemars", derive(JsonSchema))]
360pub struct MetadataRecord {
361 #[cfg_attr(
363 feature = "serde",
364 serde(default, skip_serializing_if = "Option::is_none")
365 )]
366 pub version: Option<VersionRef>,
367 #[cfg_attr(
369 feature = "serde",
370 serde(default, skip_serializing_if = "Option::is_none")
371 )]
372 pub namespace: Option<String>,
373 pub key: String,
375 pub value: Value,
377}
378
379#[derive(Clone, Debug, PartialEq)]
381#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
382#[cfg_attr(feature = "schemars", derive(JsonSchema))]
383pub struct RepoContext {
384 pub tenant: TenantCtx,
386 pub repo: RepoRef,
388}
389
390#[derive(Clone, Debug, PartialEq)]
392#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
393#[cfg_attr(feature = "schemars", derive(JsonSchema))]
394pub struct StoreContext {
395 pub tenant: TenantCtx,
397 pub store: StoreRef,
399}