1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
// Project: hyperi-rustlib
// File: src/deployment/registry.rs
// Purpose: Config-cascade-driven container registry resolution
// Language: Rust
//
// License: FSL-1.1-ALv2
// Copyright: (c) 2026 HYPERI PTY LIMITED
//! Container registry resolution for deployment contracts.
//!
//! The publish-target registry (where the built image is pushed) and the
//! base image (the `FROM` line) are org-wide decisions, not per-app. This
//! module reads them from the config cascade so they live in YAML config
//! rather than being hardcoded in each app's contract source.
//!
//! # Cascade keys
//!
//! ```yaml
//! deployment:
//! image_registry: ghcr.io/hyperi-io # default: ghcr.io/hyperi-io
//! base_image: ubuntu:24.04 # default: ubuntu:24.04
//! ```
//!
//! # Defaults
//!
//! - [`DEFAULT_IMAGE_REGISTRY`] = `ghcr.io/hyperi-io` — where built images go
//! - [`DEFAULT_BASE_IMAGE`] = `ubuntu:24.04` — what the runtime stage builds on
//!
//! When (eventually) a curated GHCR base image lands at
//! `ghcr.io/hyperi-io/dfe-base:ubuntu-24.04`, ops can override
//! `deployment.base_image` in the cascade without rebuilding the apps.
/// Default publish-target registry for HyperI org.
///
/// Combined with the contract's `app_name` to produce
/// `<DEFAULT_IMAGE_REGISTRY>/<app_name>:<version>`.
pub const DEFAULT_IMAGE_REGISTRY: &str = "ghcr.io/hyperi-io";
/// Default base image for the runtime stage.
///
/// Pulled from Docker Hub (no registry prefix). To use a curated GHCR base,
/// set `deployment.base_image` in the YAML cascade to e.g.
/// `ghcr.io/hyperi-io/dfe-base:ubuntu-24.04` once that image exists.
pub const DEFAULT_BASE_IMAGE: &str = "ubuntu:24.04";
/// Read the publish-target image registry from the config cascade.
///
/// Reads `deployment.image_registry` from the YAML cascade. Falls back to
/// [`DEFAULT_IMAGE_REGISTRY`] when not set, when config isn't loaded, or
/// when the `config` feature is disabled.
///
/// # Example
///
/// ```rust,no_run
/// use hyperi_rustlib::deployment::{DeploymentContract, image_registry_from_cascade};
/// # fn dummy() -> DeploymentContract { unimplemented!() }
/// let mut contract = dummy();
/// contract.image_registry = image_registry_from_cascade();
/// ```
/// Read the runtime base image from the config cascade.
///
/// Reads `deployment.base_image` from the YAML cascade. Falls back to
/// [`DEFAULT_BASE_IMAGE`] when not set.
/// Read the git repo URL for ArgoCD generation from the config cascade.
///
/// Reads `deployment.argocd.repo_url` from the YAML cascade. Falls back to
/// `https://github.com/hyperi-io/{app_name}` if not set — matches the org
/// convention.