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 icp;
64mod inputs;
65mod staging;
66mod transaction;
67mod transaction_batch;
68mod wasm;
69mod wasm_batch;
70mod wasm_cache;
71mod workspace;
72
73#[cfg(test)]
74pub(crate) mod test_support;
75
76#[cfg(all(test, unix))]
77mod host_tests;
78
79pub use cache_fs::{ArtifactCacheMaintenance, ArtifactCachePrunePolicy, ArtifactCachePruneReport};
80pub use digest::InputDigest;
81pub use icp::{
82    WatchedInputSnapshot, icp_artifact_ready_for_build, icp_artifact_ready_with_snapshot,
83};
84pub use inputs::{
85    InputEvidence, InputEvidenceError, InputEvidenceSpec, InputEvidenceValue,
86    discover_cargo_depfile_inputs, parse_cargo_depfile,
87};
88pub use staging::{ArtifactStagingDirectory, CapturedArtifact};
89pub use transaction::{
90    ArtifactBuildTransaction, ArtifactCacheArtifact, ArtifactCacheError, ArtifactCacheOutcome,
91    ArtifactCachePreparation, ArtifactCacheRecord, ArtifactCacheSpec, ArtifactCacheTimings,
92    ArtifactOutputValidation, prepare_artifact_cache, prune_artifact_cache,
93};
94pub use transaction_batch::{
95    ArtifactCacheBatchContractError, ArtifactCacheBatchEntry, ArtifactCacheBatchFailedEntry,
96    ArtifactCacheBatchFailure, ArtifactCacheBatchFailurePhase, ArtifactCacheBatchFailureTimings,
97    ArtifactCacheBatchMetrics, ArtifactCacheBatchOutcomeEntry, ArtifactCacheBatchReport,
98    LabeledArtifactCacheSpec, build_artifact_caches_batch,
99};
100pub use wasm::{wasm_artifacts_ready, wasm_path};
101pub use wasm_batch::{
102    LabeledWasmBuildSpec, WasmBuildBatchConfig, WasmBuildBatchContractError, WasmBuildBatchEntry,
103    WasmBuildBatchFailure, WasmBuildBatchMaintenanceEntry, WasmBuildBatchMetrics,
104    WasmBuildBatchOutcomeEntry, WasmBuildBatchProgressEvent, WasmBuildBatchReport,
105    WasmBuildInputSnapshot, WasmBuildInputSnapshotMetrics, WasmBuildSession,
106    WasmBuildSessionMetrics, build_wasm_canisters_cached_batch,
107    build_wasm_canisters_cached_batch_with_config,
108    build_wasm_canisters_cached_batch_with_config_and_progress,
109    build_wasm_canisters_cached_batch_with_progress,
110};
111pub use wasm_cache::{
112    CargoBuildInput, ResolvedCargoBuildInputs, SharedIncrementalTargetInspection,
113    SharedIncrementalTargetMaintenance, SharedIncrementalTargetMaintenanceConfig,
114    SharedIncrementalTargetMaintenanceFailureMode, SharedIncrementalTargetMaintenanceOutcome,
115    SharedIncrementalTargetPrunePolicy, WasmBuildCacheMode, WasmBuildError,
116    WasmBuildFailureDetails, WasmBuildFailurePhase, WasmBuildFailureTimings, WasmBuildOutcome,
117    WasmBuildOutputStream, WasmBuildPhase, WasmBuildProgressConfig, WasmBuildProgressEvent,
118    WasmBuildProgressOutcome, WasmBuildProgressPhase, WasmBuildRecord, WasmBuildSpec,
119    WasmBuildTimings, WasmInputResolutionTimings, build_wasm_canisters_cached,
120    build_wasm_canisters_cached_with_progress, inspect_shared_incremental_target,
121    maintain_shared_incremental_target, maintain_shared_incremental_target_at_most_every,
122    prune_wasm_build_cache, resolve_cargo_build_inputs,
123};
124pub use workspace::{test_target_dir, workspace_root_for};