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; [`WasmBuildInputSnapshot`]
6//! prepares a fixed specification set for concurrent readers under a caller-held
7//! source lease. Independent batches resolve current inputs on each call.
8//!
9//! Successful Wasm and generic artifact records retain their read-only exact
10//! paths against cache replacement and pruning. Retain the record (or a clone)
11//! through consumption; paths and artifact descriptors alone carry no ownership.
12//! Batch reports own their successful records even when later entries fail.
13//!
14//! ```no_run
15//! use ic_build::artifacts::{
16//!     ArtifactCacheOutcome, ArtifactCachePreparation, ArtifactCacheSpec,
17//!     WasmBuildSpec, build_wasm_canisters_cached, prepare_artifact_cache,
18//!     resolve_cargo_build_inputs,
19//! };
20//! use ic_host_artifacts::artifact::hash_reader;
21//! use ic_host_process::tool::{AdmittedTool, ExecutionContext, OutputLimits};
22//! use std::path::Path;
23//!
24//! // The caller holds its source lease and configures the Cargo shim and actual
25//! // compiler identity on spec. The admitted optimizer accepts INPUT -o OUTPUT.
26//! fn build_deployable(
27//!     spec: &WasmBuildSpec, post_cache: &Path, destination: &Path,
28//!     optimizer: &AdmittedTool, context: &ExecutionContext<'_>, limits: OutputLimits,
29//!     max_output_bytes: usize,
30//! ) -> Result<Vec<u8>, Box<dyn std::error::Error>>
31//! {
32//!     let resolved = resolve_cargo_build_inputs(spec)?;
33//!     let wasm = build_wasm_canisters_cached(spec, ic_host_process::child::OwnedChild::spawn_direct)?;
34//!     let input = &wasm.record().artifacts()[0];
35//!     let post_spec = ArtifactCacheSpec::new(post_cache, "deploy", "optimizer/v1")
36//!         .with_cargo_build_inputs("cargo", spec, &resolved)
37//!         .with_input("wasm", input)
38//!         .with_tool("optimizer", optimizer.path())
39//!         .with_arguments(["<input>", "-o", "<output>"])
40//!         .with_environment(context.environment.iter().cloned())
41//!         .with_identity_bytes("optimizer-cwd", context.current_dir.as_os_str().as_encoded_bytes())
42//!         .with_output("deploy", destination);
43//!     let deploy = match prepare_artifact_cache(&post_spec)? {
44//!         ArtifactCachePreparation::Reused(record) => ArtifactCacheOutcome::Reused(record),
45//!         ArtifactCachePreparation::Build(transaction) => {
46//!             let output = transaction.output_path("deploy")?;
47//!             optimizer.run(&[input.into(), "-o".into(), output.clone().into()], context, limits)?.require_success()?;
48//!             hash_reader(std::fs::File::open(&output)?, max_output_bytes as u64)?;
49//!             transaction.commit()?
50//!         }
51//!     };
52//!     drop(wasm); // The post-link transaction has finished consuming the input.
53//!     let bytes = ic_host_fs::read::read_file(
54//!         deploy.record().artifacts()[0].path(), max_output_bytes)?;
55//!     drop(deploy); // Reading is complete; maintenance may now reclaim it.
56//!     Ok(bytes)
57//! }
58//! ```
59
60#[cfg(unix)]
61pub mod candid;
62
63mod cache_fs;
64mod digest;
65mod inputs;
66mod phase;
67mod staging;
68mod transaction;
69mod transaction_batch;
70mod wasm_batch;
71mod wasm_cache;
72
73#[cfg(test)]
74pub(crate) mod test_support;
75
76#[cfg(all(test, unix))]
77mod host_tests;
78
79pub use cache_fs::{ArtifactCacheMaintenance, ArtifactCachePruneReport, CacheRetentionLimits};
80pub use digest::InputDigest;
81pub use inputs::{
82    InputEvidence, InputEvidenceError, InputEvidenceSpec, InputEvidenceValue, parse_cargo_depfile,
83    read_cargo_depfile_inputs,
84};
85pub use phase::WasmBuildPhase;
86pub use staging::{
87    ArtifactStagingDirectory, CaptureRetentionError, CapturedArtifact, produce_and_retain_artifact,
88};
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    ArtifactCacheBatchEntry, ArtifactCacheBatchFailure, ArtifactCacheBatchFailureTimings,
96    ArtifactCacheBatchMetrics, ArtifactCacheBatchReport, LabeledArtifactCacheSpec,
97    build_artifact_caches_batch,
98};
99pub use wasm_batch::{
100    LabeledWasmBuildSpec, WasmBuildBatchConfig, WasmBuildBatchContractError, WasmBuildBatchEntry,
101    WasmBuildBatchMetrics, WasmBuildBatchProgressEvent, WasmBuildBatchReport,
102    WasmBuildInputSnapshot, WasmBuildInputSnapshotMetrics, build_wasm_canisters_cached_batch,
103};
104pub use wasm_cache::{
105    CargoBuildFacts, CargoBuildInput, CargoInputProbePolicy, ResolvedCargoBuildInputs,
106    SharedIncrementalTargetInspection, SharedIncrementalTargetMaintenance,
107    SharedIncrementalTargetMaintenanceConfig, SharedIncrementalTargetMaintenanceFailureMode,
108    SharedIncrementalTargetMaintenanceOutcome, WasmBuildCacheMode, WasmBuildError,
109    WasmBuildFailureDetails, WasmBuildFailureTimings, WasmBuildOutcome, WasmBuildProgressConfig,
110    WasmBuildProgressEvent, WasmBuildProgressOutcome, WasmBuildRecord, WasmBuildSpec,
111    WasmBuildTimings, WasmInputResolutionTimings, build_wasm_canisters_cached,
112    build_wasm_canisters_cached_with_progress, inspect_shared_incremental_target,
113    maintain_shared_incremental_target, maintain_shared_incremental_target_at_most_every,
114    prune_wasm_build_cache, resolve_cargo_build_inputs,
115    resolve_cargo_build_inputs_with_probe_policy,
116};