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, ic_host_process::child::OwnedChild::spawn_direct)?;
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
61#[cfg(unix)]
62pub mod candid;
63
64mod cache_fs;
65mod digest;
66mod inputs;
67mod phase;
68mod staging;
69mod transaction;
70mod transaction_batch;
71mod wasm_batch;
72mod wasm_cache;
73
74#[cfg(test)]
75pub(crate) mod test_support;
76
77#[cfg(all(test, unix))]
78mod host_tests;
79
80pub use cache_fs::{ArtifactCacheMaintenance, ArtifactCachePruneReport, CacheRetentionLimits};
81pub use digest::InputDigest;
82pub use inputs::{
83 InputEvidence, InputEvidenceError, InputEvidenceSpec, InputEvidenceValue, parse_cargo_depfile,
84 read_cargo_depfile_inputs,
85};
86pub use phase::WasmBuildPhase;
87pub use staging::{
88 ArtifactStagingDirectory, CaptureRetentionError, CapturedArtifact, produce_and_retain_artifact,
89};
90pub use transaction::{
91 ArtifactBuildTransaction, ArtifactCacheArtifact, ArtifactCacheError, ArtifactCacheOutcome,
92 ArtifactCachePreparation, ArtifactCacheRecord, ArtifactCacheSpec, ArtifactCacheTimings,
93 ArtifactOutputValidation, prepare_artifact_cache, prune_artifact_cache,
94};
95pub use transaction_batch::{
96 ArtifactCacheBatchEntry, ArtifactCacheBatchFailure, ArtifactCacheBatchFailureTimings,
97 ArtifactCacheBatchMetrics, ArtifactCacheBatchReport, LabeledArtifactCacheSpec,
98 build_artifact_caches_batch,
99};
100pub use wasm_batch::{
101 LabeledWasmBuildSpec, WasmBuildBatchConfig, WasmBuildBatchContractError, WasmBuildBatchEntry,
102 WasmBuildBatchMetrics, WasmBuildBatchProgressEvent, WasmBuildBatchReport,
103 WasmBuildInputSnapshot, WasmBuildInputSnapshotMetrics, WasmBuildSession,
104 WasmBuildSessionMetrics, build_wasm_canisters_cached_batch,
105};
106pub use wasm_cache::{
107 CargoBuildInput, CargoInputProbePolicy, ResolvedCargoBuildInputs,
108 SharedIncrementalTargetInspection, SharedIncrementalTargetMaintenance,
109 SharedIncrementalTargetMaintenanceConfig, SharedIncrementalTargetMaintenanceFailureMode,
110 SharedIncrementalTargetMaintenanceOutcome, WasmBuildCacheMode, WasmBuildError,
111 WasmBuildFailureDetails, WasmBuildFailureTimings, WasmBuildOutcome, WasmBuildProgressConfig,
112 WasmBuildProgressEvent, WasmBuildProgressOutcome, WasmBuildRecord, WasmBuildSpec,
113 WasmBuildTimings, WasmInputResolutionTimings, build_wasm_canisters_cached,
114 build_wasm_canisters_cached_with_progress, inspect_shared_incremental_target,
115 maintain_shared_incremental_target, maintain_shared_incremental_target_at_most_every,
116 prune_wasm_build_cache, resolve_cargo_build_inputs,
117 resolve_cargo_build_inputs_with_probe_policy,
118};