diff --git a/.gitignore b/.gitignore index d4699c7..7aebe3b 100644 --- a/.gitignore +++ b/.gitignore @@ -29,9 +29,6 @@ coverage.lcov .cargo/* !.cargo/config.toml -# written by `dfe-transform-vector emit-chart chart`; the release assembles the chart from the contract -/chart/ - # Local working files (not committed) docs/superpowers/ .claude/ diff --git a/.hyperi-ci.yaml b/.hyperi-ci.yaml index 2f28d7e..46af8e0 100644 --- a/.hyperi-ci.yaml +++ b/.hyperi-ci.yaml @@ -70,7 +70,7 @@ release: helm: enabled: true contract: emit - library: "2.14.3" + library: "2.14.6" container: enabled: true dockerfile: Dockerfile diff --git a/Cargo.lock b/Cargo.lock index 4ed11d2..86aa53a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2541,7 +2541,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "03da047801ff44bb6a4d407d4860c05fd70bb81714e6b2f3812603d5b145b042" dependencies = [ "heck", - "itertools 0.14.0", + "itertools 0.12.1", "log", "multimap", "petgraph", @@ -2562,7 +2562,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b570b25f7617e43d59005d0990ccb79e950a423952cea19671b7a876da390adf" dependencies = [ "anyhow", - "itertools 0.14.0", + "itertools 0.12.1", "proc-macro2", "quote", "syn 2.0.119", @@ -3204,9 +3204,9 @@ dependencies = [ [[package]] name = "scalo" -version = "2.14.3" +version = "2.14.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1105393fd98b1d95b1809650b5761794a7df88a21a72dddce4ca535d946e983f" +checksum = "c9e521cd4d8b8f5c4acf17cdecacbbf25e7688e812d008439ae09f12f34b43ab" dependencies = [ "backon", "bytes", diff --git a/Cargo.toml b/Cargo.toml index e98251f..c605825 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,7 @@ description = "Kafka-to-Kafka transform pipelines, running Vector.dev as a manag license = "BUSL-1.1" repository = "https://github.com/hyperi-io/dfe-transform-vector" rust-version = "1.95" -exclude = [".github/", "chart/", "docs/"] +exclude = [".github/", "docs/"] [lib] name = "dfe_transform_vector" @@ -63,8 +63,9 @@ tokio-util = { version = ">=0.7.19, <0.8", features = ["rt"] } # holds the generated Kafka source and sink to. Only its config is used: the # image ships no librdkafka, so nothing here may build an rdkafka client. # -# The floor's contract carries no vendor defaults, so the app names its own. -scalo = { version = "2.14.3", features = [ +# The floor moves with `release.helm.library` in .hyperi-ci.yaml: the library +# renders only the contract version its scalo release writes. +scalo = { version = "2.14.6", features = [ "cli-service", "config-reload", "config-schema", @@ -140,7 +141,7 @@ tar = ">=0.4.46, <0.5" chrono = ">=0.4.45, <0.5" testcontainers = ">=0.27.3, <0.28" testcontainers-modules = { version = ">=0.15, <0.16", features = ["kafka"] } -scalo = { version = "2.14.3", features = [ +scalo = { version = "2.14.6", features = [ "transport-kafka", ] } # The repo's own .env for the live-broker tests. The binary's .env is read by scalo's cascade. diff --git a/README.md b/README.md index 24387d1..30bfca5 100644 --- a/README.md +++ b/README.md @@ -93,9 +93,6 @@ cargo build --release # Generate deployment artefacts ./target/release/dfe-transform-vector emit-dockerfile ./target/release/dfe-transform-vector emit-compose - -# scalo's full chart, for local use. emit-chart overwrites the directory it is given. -./target/release/dfe-transform-vector emit-chart chart ``` ### Helm chart @@ -352,10 +349,10 @@ Inbound -- what this repo depends on: Outbound -- what depends on this repo: -- **dfe-infra**, `image-pin`, lockstep. `dfe-infra/helm/charts/dfe-transform-vector/Chart.yaml` - pins this repo's container image as a tag plus the digest that makes the tag - immutable. Bump the tag, re-resolve the digest, and `check_versions_drift.py` - confirms the chart's `appVersion` and the digest mirror agree with the pin. +- **dfe-infra**, `image-pin`, lockstep. `dfe-infra/versions.yaml` pins this + repo's container image as a tag plus the digest that makes the tag + immutable, and the thin chart released here, which Argo deploys. Bump the + tag and re-resolve the digest. Two more relationships that are real but are NOT declared edges in the suite graph, so no gate enforces them: diff --git a/config/defaults.yaml b/config/defaults.yaml deleted file mode 100644 index 98a4c2d..0000000 --- a/config/defaults.yaml +++ /dev/null @@ -1,13 +0,0 @@ -# Project: dfe-transform-vector -# File: config/defaults.yaml -# Purpose: Cascade defaults for `dfe-transform-vector generate-artefacts` -# -# License: BUSL-1.1 -# Copyright: (c) 2026 HYPERI PTY LIMITED - -# generate-artefacts writes no ArgoCD Application without a repo URL, and -# deploys into a namespace named after the app unless one is set here. -deployment: - argocd: - repo_url: https://github.com/hyperi-io/dfe-transform-vector - dest_namespace: dfe diff --git a/docs/DESIGN.md b/docs/DESIGN.md index 93d237b..2f3fa6a 100644 --- a/docs/DESIGN.md +++ b/docs/DESIGN.md @@ -747,7 +747,7 @@ DFE remediation guide. ### 9.1 How the Chart Is Built -No chart is committed. At release, hyperi-ci runs the binary's `generate-artefacts` for the deployment contract and assembles a thin chart from it on the scalo-service library chart, at the version `release.helm.library` names in `.hyperi-ci.yaml`. The library renders the Deployment, Service, ConfigMap, ServiceAccount and KEDA ScaledObject, and its README documents the values. `emit-chart ` still writes scalo's full chart for local use. +No chart is committed. At release, hyperi-ci runs the binary's `generate-artefacts` for the deployment contract and assembles a thin chart from it on the scalo-service library chart, at the version `release.helm.library` names in `.hyperi-ci.yaml`. The library renders the Deployment, Service, ConfigMap, ServiceAccount and KEDA ScaledObject, and its README documents the values. ### 9.2 What the Contract Fixes diff --git a/src/deployment.rs b/src/deployment.rs index 61f23f2..e74ef91 100644 --- a/src/deployment.rs +++ b/src/deployment.rs @@ -15,7 +15,7 @@ use scalo::deployment::{ CONTRACT_SCHEMA_VERSION, DeploymentContract, HealthContract, ImageProfile, KafkaLagTrigger, KedaConfig, KedaContract, NativeDepsContract, PortContract, ResourceList, ResourcesContract, - SecretEnvContract, SecretGroupContract, SecurityContract, WritablePath, + SecretEnvContract, SecretGroupContract, SecurityContract, ServiceAccount, WritablePath, base_image_from_cascade, }; @@ -184,6 +184,7 @@ pub fn contract() -> DeploymentContract { }, security: SecurityContract::default(), singleton: false, + service_account: ServiceAccount::Own, } } diff --git a/src/main.rs b/src/main.rs index a1ca58f..a7b1333 100644 --- a/src/main.rs +++ b/src/main.rs @@ -22,7 +22,7 @@ use std::time::Instant; use clap::{Parser, Subcommand}; use scalo::cli::{CliError, CommonArgs, ServiceApp, StandardCommand, VersionInfo}; -use scalo::deployment::{generate_chart, generate_compose_fragment}; +use scalo::deployment::generate_compose_fragment; use scalo::logger::security::{self, SecurityEvent, SecurityOutcome}; use scalo::version_check::VersionCheckConfig; use tracing::{debug, error, info}; @@ -93,13 +93,6 @@ enum AppCommand { #[command(name = "emit-dockerfile")] EmitDockerfile, - /// Generate Helm chart to the given directory (legacy shortcut; prefer `generate-artefacts`). - #[command(name = "emit-chart")] - EmitChart { - /// Output directory for the chart. - dir: String, - }, - /// Generate Docker Compose fragment to stdout (legacy shortcut; prefer `generate-artefacts`). #[command(name = "emit-compose")] EmitCompose, @@ -193,15 +186,6 @@ async fn main() { println!("{}", deployment::emit_dockerfile()); return; } - AppCommand::EmitChart { dir } => { - let contract = deployment::contract(); - if let Err(e) = generate_chart(&contract, dir, None) { - eprintln!("error: failed to generate Helm chart: {e}"); - std::process::exit(1); - } - eprintln!("Helm chart generated in {dir}/"); - return; - } AppCommand::EmitCompose => { let contract = deployment::contract(); println!("{}", generate_compose_fragment(&contract)); diff --git a/tests/integration/deployment.rs b/tests/integration/deployment.rs index 1a926a6..987758c 100644 --- a/tests/integration/deployment.rs +++ b/tests/integration/deployment.rs @@ -243,38 +243,12 @@ fn contract_uses_standard_mount_path() { ); } -#[test] -fn emit_chart_generates_without_panic() { - let contract = deployment::contract(); - let dir = tempfile::tempdir().expect("create temp dir"); - let dir_path = dir.path().to_str().unwrap(); - - let result = scalo::deployment::generate_chart(&contract, dir_path, None); - assert!( - result.is_ok(), - "chart generation failed: {:?}", - result.err() - ); - - // Chart.yaml must exist - let chart_yaml = dir.path().join("Chart.yaml"); - assert!(chart_yaml.exists(), "Chart.yaml not generated"); - - // values.yaml must exist - let values_yaml = dir.path().join("values.yaml"); - assert!(values_yaml.exists(), "values.yaml not generated"); - - // templates/ directory must exist - let templates = dir.path().join("templates"); - assert!(templates.is_dir(), "templates/ not generated"); -} - /// The contract's default config, with the Kafka Secret mounted into the env /// vars the contract declares, must be a config the app accepts. /// -/// `emit-chart` writes `default_config` into its values, so a chart generated -/// from the contract is only as good as this, and anything `validate()` rejects -/// is a crash-loop before Vector starts. +/// The released chart renders `default_config` as its config, so it is only as +/// good as this, and anything `validate()` rejects is a crash-loop before +/// Vector starts. #[test] fn the_contract_default_config_is_one_the_app_accepts() { use dfe_transform_vector::config::loader::Config; diff --git a/tests/smoke.rs b/tests/smoke.rs index d873d55..d1b31f8 100644 --- a/tests/smoke.rs +++ b/tests/smoke.rs @@ -375,25 +375,3 @@ fn cli_emit_compose_produces_output() { "emit-compose should produce compose fragment" ); } - -#[test] -fn cli_emit_chart_produces_chart_dir() { - let dir = tempfile::tempdir().unwrap(); - let chart_dir = dir.path().join("chart"); - - let output = std::process::Command::new(env!("CARGO_BIN_EXE_dfe-transform-vector")) - .args(["emit-chart", chart_dir.to_str().unwrap()]) - .output() - .expect("failed to run binary"); - - assert!( - output.status.success(), - "emit-chart failed: {}", - String::from_utf8_lossy(&output.stderr) - ); - assert!(chart_dir.join("Chart.yaml").exists(), "Chart.yaml missing"); - assert!( - chart_dir.join("values.yaml").exists(), - "values.yaml missing" - ); -}