Skip to main content

ic_build/artifacts/
mod.rs

1//! Host-side artifact discovery, freshness, and Wasm build helpers.
2//!
3//! These functions keep integration-test artifacts in caller-selected target
4//! directories and contain no application-specific package or profile policy.
5//! Independent Wasm batches remain sequential; [`WasmBuildSession`] adds
6//! explicit cross-call resolution reuse, while [`WasmBuildInputSnapshot`]
7//! prepares a fixed specification set for concurrent readers. Both require a
8//! caller-held source lease.
9//!
10//! Successful Wasm and generic artifact records retain their read-only exact
11//! paths against cache replacement and pruning. Retain the record (or a clone)
12//! through consumption; paths and artifact descriptors alone carry no ownership.
13//! Batch reports own their successful records even when later entries fail.
14//!
15//! ```no_run
16//! use ic_build::artifacts::{
17//!     ArtifactCacheOutcome, ArtifactCachePreparation, ArtifactCacheSpec,
18//!     WasmBuildSpec, build_wasm_canisters_cached, prepare_artifact_cache,
19//!     resolve_cargo_build_inputs,
20//! };
21//! use ic_host_artifacts::artifact::hash_reader;
22//! use ic_host_process::tool::{AdmittedTool, ExecutionContext, OutputLimits};
23//! use std::path::Path;
24//!
25//! // The caller holds its source lease and configures the Cargo shim and actual
26//! // compiler identity on spec. The admitted optimizer accepts INPUT -o OUTPUT.
27//! fn build_deployable(
28//!     spec: &WasmBuildSpec, post_cache: &Path, destination: &Path,
29//!     optimizer: &AdmittedTool, context: &ExecutionContext<'_>, limits: OutputLimits,
30//!     max_output_bytes: usize,
31//! ) -> Result<Vec<u8>, Box<dyn std::error::Error>>
32//! {
33//!     let resolved = resolve_cargo_build_inputs(spec)?;
34//!     let wasm = build_wasm_canisters_cached(spec)?;
35//!     let input = &wasm.record().artifacts()[0];
36//!     let post_spec = ArtifactCacheSpec::new(post_cache, "deploy", "optimizer/v1")
37//!         .with_cargo_build_inputs("cargo", spec, &resolved)
38//!         .with_input("wasm", input)
39//!         .with_tool("optimizer", optimizer.path())
40//!         .with_arguments(["<input>", "-o", "<output>"])
41//!         .with_environment(context.environment.iter().cloned())
42//!         .with_identity_bytes("optimizer-cwd", context.current_dir.as_os_str().as_encoded_bytes())
43//!         .with_output("deploy", destination);
44//!     let deploy = match prepare_artifact_cache(&post_spec)? {
45//!         ArtifactCachePreparation::Reused(record) => ArtifactCacheOutcome::Reused(record),
46//!         ArtifactCachePreparation::Build(transaction) => {
47//!             let output = transaction.output_path("deploy")?;
48//!             optimizer.run(&[input.into(), "-o".into(), output.clone().into()], context, limits)?.require_success()?;
49//!             hash_reader(std::fs::File::open(&output)?, max_output_bytes as u64)?;
50//!             transaction.commit()?
51//!         }
52//!     };
53//!     drop(wasm); // The post-link transaction has finished consuming the input.
54//!     let bytes = ic_host_fs::read::read_file(
55//!         deploy.record().artifacts()[0].path(), max_output_bytes)?;
56//!     drop(deploy); // Reading is complete; maintenance may now reclaim it.
57//!     Ok(bytes)
58//! }
59//! ```
60
61mod cache_fs;
62mod digest;
63mod inputs;
64mod staging;
65mod transaction;
66mod transaction_batch;
67mod wasm;
68mod wasm_batch;
69mod wasm_cache;
70mod workspace;
71
72#[cfg(test)]
73pub(crate) mod test_support;
74
75#[cfg(all(test, unix))]
76mod host_tests;
77
78pub use cache_fs::{ArtifactCacheMaintenance, ArtifactCachePrunePolicy, ArtifactCachePruneReport};
79pub use digest::InputDigest;
80pub use inputs::{
81    InputEvidence, InputEvidenceError, InputEvidenceSpec, InputEvidenceValue,
82    discover_cargo_depfile_inputs, parse_cargo_depfile, read_cargo_depfile_inputs,
83};
84pub use staging::{ArtifactStagingDirectory, CapturedArtifact};
85pub use transaction::{
86    ArtifactBuildTransaction, ArtifactCacheArtifact, ArtifactCacheError, ArtifactCacheOutcome,
87    ArtifactCachePreparation, ArtifactCacheRecord, ArtifactCacheSpec, ArtifactCacheTimings,
88    ArtifactOutputValidation, prepare_artifact_cache, prune_artifact_cache,
89};
90pub use transaction_batch::{
91    ArtifactCacheBatchContractError, ArtifactCacheBatchEntry, ArtifactCacheBatchFailedEntry,
92    ArtifactCacheBatchFailure, ArtifactCacheBatchFailurePhase, ArtifactCacheBatchFailureTimings,
93    ArtifactCacheBatchMetrics, ArtifactCacheBatchOutcomeEntry, ArtifactCacheBatchReport,
94    LabeledArtifactCacheSpec, build_artifact_caches_batch,
95};
96pub use wasm::{wasm_artifacts_ready, wasm_path};
97pub use wasm_batch::{
98    LabeledWasmBuildSpec, WasmBuildBatchConfig, WasmBuildBatchContractError, WasmBuildBatchEntry,
99    WasmBuildBatchFailure, WasmBuildBatchMaintenanceEntry, WasmBuildBatchMetrics,
100    WasmBuildBatchOutcomeEntry, WasmBuildBatchProgressEvent, WasmBuildBatchReport,
101    WasmBuildInputSnapshot, WasmBuildInputSnapshotMetrics, WasmBuildSession,
102    WasmBuildSessionMetrics, build_wasm_canisters_cached_batch,
103    build_wasm_canisters_cached_batch_with_config,
104    build_wasm_canisters_cached_batch_with_config_and_progress,
105    build_wasm_canisters_cached_batch_with_progress,
106};
107pub use wasm_cache::{
108    CargoBuildInput, CargoInputProbePolicy, ResolvedCargoBuildInputs,
109    SharedIncrementalTargetInspection, SharedIncrementalTargetMaintenance,
110    SharedIncrementalTargetMaintenanceConfig, SharedIncrementalTargetMaintenanceFailureMode,
111    SharedIncrementalTargetMaintenanceOutcome, SharedIncrementalTargetPrunePolicy,
112    WasmBuildCacheMode, WasmBuildError, WasmBuildFailureDetails, WasmBuildFailurePhase,
113    WasmBuildFailureTimings, WasmBuildOutcome, WasmBuildOutputStream, WasmBuildPhase,
114    WasmBuildProgressConfig, WasmBuildProgressEvent, WasmBuildProgressOutcome,
115    WasmBuildProgressPhase, WasmBuildRecord, WasmBuildSpec, WasmBuildTimings,
116    WasmInputResolutionTimings, build_wasm_canisters_cached,
117    build_wasm_canisters_cached_with_progress, inspect_shared_incremental_target,
118    maintain_shared_incremental_target, maintain_shared_incremental_target_at_most_every,
119    prune_wasm_build_cache, resolve_cargo_build_inputs,
120    resolve_cargo_build_inputs_with_probe_policy,
121};
122pub use workspace::{test_target_dir, workspace_root_for};