diff --git a/.githooks/pre-push b/.githooks/pre-push new file mode 100755 index 00000000..e88a29ec --- /dev/null +++ b/.githooks/pre-push @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +# Pre-push hook — `task fmt:check` + `task lint` before letting code +# leave the laptop. Skip with `git push --no-verify` if you must. +# +# Install: `task hooks:install` (sets `core.hooksPath = .githooks`). + +set -e + +if ! command -v task >/dev/null 2>&1; then + echo "pre-push: \`task\` not on PATH; install via \`mise install\` or skip with --no-verify" >&2 + exit 1 +fi + +echo "pre-push: fmt:check" +task fmt:check + +echo "pre-push: lint" +task lint diff --git a/CHANGELOG.md b/CHANGELOG.md index a968ba54..59c319bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,62 @@ minor bump in the SDK. > single-file/total-package cap is incompatible with the bundled napi > addon (~129 MB compressed across the per-platform packages). +## [0.7.0] — 2026-04-28 + +The `pkg.render` round: a synchronous engine plugin that mirrors +`helm.template` / `kustomize.build`, plus the supporting work to +make composition first-class (path-deps + OCI Akua-package deps, +budget guards, structured error codes, a worked install-as-Package +example). + +### Added + +- **`pkg.render` is a synchronous engine plugin.** Returns a real + `[{str:}]` list, not a deferred sentinel. List-comprehension + patches (`[r | overlay for r in pkg.render(...)]`), filter + expressions, and slicing all work natively. Requires the akua + KCL fork (`cnap-tech/kcl@akua-wasm32`, commit `d584c0bc`) which + copies `PLUGIN_HANDLER_FN_PTR` out of its mutex before invoking + the plugin callback so reentrant KCL eval no longer deadlocks. +- **OCI Akua-package deps.** `[dependencies] upstream = { oci = "..." }` + resolves to a `KclModule` even when the artifact carries + `package.k` (no `kcl.mod`) and `dev.akua.*` annotations. +- **Budget header for `pkg.render`.** `BudgetSnapshot { deadline, + max_depth }` propagated through the render stack and checked + before nested invocations. Default depth cap is 16; outermost + callers can install an explicit deadline via + `RenderScope::enter_with_budget`. Catches recursive-composition + runaway. +- **Structured error codes** for plugin failures: + `E_RENDER_CYCLE`, `E_RENDER_BUDGET_DEPTH`, + `E_RENDER_BUDGET_DEADLINE`. Routed through a marker→code lookup + table. +- **`examples/11-install-as-package/`** — worked install-as-Package + shape: outer Package overlays a tenant label, filters out a kind, + and appends an extras ConfigMap on top of `pkg.render`'d upstream. +- **`renovate.json`** — pre-1.0 cargo bumps no longer batch into a + single PR. + +### Changed + +- Render-worker rebuild trigger now watches `akua-render-worker/src` + + `akua-core/src` and emits a `cargo:warning=` when the staged + `.cwasm` is stale. +- `akua init .` derives the package name from `basename($PWD)` + instead of writing `name = "."`. +- `E_PATH_ESCAPE` errors now carry a `hint` field with both + remediations (vendor under the Package or declare in + `akua.toml`). +- `akua render --debug` (under `--json`) emits `evalResult` + alongside the summary — the post-eval resources list before + YAML normalization. + +### Removed + +- The `pkg.render` deferred-sentinel mechanism + the + `E_PKG_RENDER_PATCH_UNSUPPORTED` fail-loud arm. Patching the + return is now native, so the workaround retired. + ## @akua-dev/sdk — [0.6.0] — 2026-04-27 The SDK moves from JSR to npm and renames to `@akua-dev/sdk`. This is diff --git a/CLAUDE.md b/CLAUDE.md index 564000a6..fe9e56ec 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -117,6 +117,8 @@ akua policy check # when policy changed; verdict must be allow All are embedded — no installation of `opa` / `kcl` / `regal` needed. +**Pre-push hook.** `task hooks:install` wires `.githooks/` into this repo (`core.hooksPath`). The pre-push hook runs `task fmt:check` + `task lint` so CI's `Rust (fmt + clippy + test)` job doesn't catch drift the laptop already saw. Skip with `git push --no-verify` only when you mean it. + ## Development stance - The project is **pre-alpha** (v0.x). APIs churn. Every change should be reviewed against the invariants above before shipping. diff --git a/Cargo.lock b/Cargo.lock index 7d51e68c..1a1130e4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -51,7 +51,7 @@ dependencies = [ [[package]] name = "akua-cli" -version = "0.6.0" +version = "0.7.0" dependencies = [ "akua-core", "clap", @@ -73,7 +73,7 @@ dependencies = [ [[package]] name = "akua-core" -version = "0.6.0" +version = "0.7.0" dependencies = [ "base64 0.22.1", "flate2", @@ -103,7 +103,7 @@ dependencies = [ [[package]] name = "akua-napi" -version = "0.6.0" +version = "0.7.0" dependencies = [ "akua-cli", "akua-core", @@ -117,7 +117,7 @@ dependencies = [ [[package]] name = "akua-render-worker" -version = "0.6.0" +version = "0.7.0" dependencies = [ "akua-core", "serde", @@ -127,7 +127,7 @@ dependencies = [ [[package]] name = "akua-wasm" -version = "0.6.0" +version = "0.7.0" dependencies = [ "akua-core", "chrono", @@ -1333,7 +1333,7 @@ dependencies = [ [[package]] name = "engine-host-wasm" -version = "0.6.0" +version = "0.7.0" dependencies = [ "thiserror 2.0.18", "wasmtime", @@ -2637,7 +2637,7 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "helm-engine-wasm" -version = "0.6.0" +version = "0.7.0" dependencies = [ "base64 0.22.1", "engine-host-wasm", @@ -3775,7 +3775,7 @@ dependencies = [ [[package]] name = "kustomize-engine-wasm" -version = "0.6.0" +version = "0.7.0" dependencies = [ "base64 0.22.1", "engine-host-wasm", diff --git a/Cargo.toml b/Cargo.toml index 5e6ab4a5..b588ab88 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ members = [ ] [workspace.package] -version = "0.6.0" +version = "0.7.0" edition = "2021" license = "Apache-2.0" repository = "https://github.com/cnap-tech/akua" diff --git a/Taskfile.yml b/Taskfile.yml index e21d0e2d..57dc837c 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -45,6 +45,12 @@ tasks: - cargo check --workspace - cargo clippy --workspace --all-targets -- -D warnings + hooks:install: + desc: Wire `.githooks/` as this repo's hooks dir (sets `core.hooksPath`) + cmds: + - git config core.hooksPath .githooks + - echo "git hooks → .githooks (run \`git config --unset core.hooksPath\` to disable)" + fmt: desc: Format Rust code cmds: diff --git a/crates/akua-cli/src/verbs/render.rs b/crates/akua-cli/src/verbs/render.rs index 32cbd7da..339e826a 100644 --- a/crates/akua-cli/src/verbs/render.rs +++ b/crates/akua-cli/src/verbs/render.rs @@ -65,7 +65,11 @@ const DEADLINE_BUDGET_SUGGESTION: &str = /// `render_error_markers_are_substring_disjoint` test pins the /// markers as pairwise-disjoint so any order would be correct. const KCL_EVAL_MARKER_TABLE: &[(&str, &str, &str)] = &[ - (STRICT_MARKER, codes::E_STRICT_UNTYPED_CHART, STRICT_SUGGESTION), + ( + STRICT_MARKER, + codes::E_STRICT_UNTYPED_CHART, + STRICT_SUGGESTION, + ), (ESCAPE_MARKER, codes::E_PATH_ESCAPE, PATH_ESCAPE_SUGGESTION), (CYCLE_MARKER, codes::E_RENDER_CYCLE, CYCLE_SUGGESTION), ( diff --git a/crates/akua-core/src/oci_fetcher.rs b/crates/akua-core/src/oci_fetcher.rs index 9bee2ad6..0fb9b046 100644 --- a/crates/akua-core/src/oci_fetcher.rs +++ b/crates/akua-core/src/oci_fetcher.rs @@ -513,8 +513,7 @@ fn find_package_root(cache_dir: &Path, kind: PackageKind) -> Result &["Chart.yaml"], PackageKind::KclModule => &["kcl.mod", "package.k"], }; - let has_marker = - |dir: &Path| -> bool { markers.iter().any(|m| dir.join(m).is_file()) }; + let has_marker = |dir: &Path| -> bool { markers.iter().any(|m| dir.join(m).is_file()) }; if has_marker(cache_dir) { return Ok(cache_dir.to_path_buf()); diff --git a/crates/akua-core/src/pkg_render.rs b/crates/akua-core/src/pkg_render.rs index ffb794ac..dda94014 100644 --- a/crates/akua-core/src/pkg_render.rs +++ b/crates/akua-core/src/pkg_render.rs @@ -461,5 +461,4 @@ resources = pkg.render({{ path = "{next}" }})"# "expected depth-limit rejection, got: {err}" ); } - } diff --git a/crates/akua-napi/npm/darwin-arm64/package.json b/crates/akua-napi/npm/darwin-arm64/package.json index e0e2e70b..b77a78be 100644 --- a/crates/akua-napi/npm/darwin-arm64/package.json +++ b/crates/akua-napi/npm/darwin-arm64/package.json @@ -1,6 +1,6 @@ { "name": "@akua-dev/native-darwin-arm64", - "version": "0.6.0", + "version": "0.7.0", "cpu": [ "arm64" ], diff --git a/crates/akua-napi/npm/darwin-x64/package.json b/crates/akua-napi/npm/darwin-x64/package.json index 47cec488..261bcf6a 100644 --- a/crates/akua-napi/npm/darwin-x64/package.json +++ b/crates/akua-napi/npm/darwin-x64/package.json @@ -1,6 +1,6 @@ { "name": "@akua-dev/native-darwin-x64", - "version": "0.6.0", + "version": "0.7.0", "cpu": [ "x64" ], diff --git a/crates/akua-napi/npm/linux-arm64-gnu/package.json b/crates/akua-napi/npm/linux-arm64-gnu/package.json index 5e691386..2d46fedc 100644 --- a/crates/akua-napi/npm/linux-arm64-gnu/package.json +++ b/crates/akua-napi/npm/linux-arm64-gnu/package.json @@ -1,6 +1,6 @@ { "name": "@akua-dev/native-linux-arm64-gnu", - "version": "0.6.0", + "version": "0.7.0", "cpu": [ "arm64" ], diff --git a/crates/akua-napi/npm/linux-arm64-musl/package.json b/crates/akua-napi/npm/linux-arm64-musl/package.json index 082fc2ab..90b30520 100644 --- a/crates/akua-napi/npm/linux-arm64-musl/package.json +++ b/crates/akua-napi/npm/linux-arm64-musl/package.json @@ -1,6 +1,6 @@ { "name": "@akua-dev/native-linux-arm64-musl", - "version": "0.6.0", + "version": "0.7.0", "cpu": [ "arm64" ], diff --git a/crates/akua-napi/npm/linux-x64-gnu/package.json b/crates/akua-napi/npm/linux-x64-gnu/package.json index c9cec37a..b72f2c01 100644 --- a/crates/akua-napi/npm/linux-x64-gnu/package.json +++ b/crates/akua-napi/npm/linux-x64-gnu/package.json @@ -1,6 +1,6 @@ { "name": "@akua-dev/native-linux-x64-gnu", - "version": "0.6.0", + "version": "0.7.0", "cpu": [ "x64" ], diff --git a/crates/akua-napi/npm/linux-x64-musl/package.json b/crates/akua-napi/npm/linux-x64-musl/package.json index 909b6547..3bfdba73 100644 --- a/crates/akua-napi/npm/linux-x64-musl/package.json +++ b/crates/akua-napi/npm/linux-x64-musl/package.json @@ -1,6 +1,6 @@ { "name": "@akua-dev/native-linux-x64-musl", - "version": "0.6.0", + "version": "0.7.0", "cpu": [ "x64" ], diff --git a/crates/akua-napi/npm/win32-x64-msvc/package.json b/crates/akua-napi/npm/win32-x64-msvc/package.json index 34413063..83fe823e 100644 --- a/crates/akua-napi/npm/win32-x64-msvc/package.json +++ b/crates/akua-napi/npm/win32-x64-msvc/package.json @@ -1,6 +1,6 @@ { "name": "@akua-dev/native-win32-x64-msvc", - "version": "0.6.0", + "version": "0.7.0", "cpu": [ "x64" ], diff --git a/crates/akua-napi/package.json b/crates/akua-napi/package.json index 1a7f351b..5fd5e5c8 100644 --- a/crates/akua-napi/package.json +++ b/crates/akua-napi/package.json @@ -1,6 +1,6 @@ { "name": "@akua-dev/native", - "version": "0.6.0", + "version": "0.7.0", "description": "Native Node.js + Bun + Deno addon for akua-core. Loaded by @akua-dev/sdk; not a public surface.", "main": "loader.js", "types": "index.d.ts", @@ -47,7 +47,7 @@ "version": "napi version" }, "dependencies": { - "@akua-dev/native-engines": "0.6.0" + "@akua-dev/native-engines": "0.7.0" }, "devDependencies": { "@napi-rs/cli": "^3.2.0" diff --git a/crates/akua-native-engines-npm/package.json b/crates/akua-native-engines-npm/package.json index 343d51b4..135bbcd3 100644 --- a/crates/akua-native-engines-npm/package.json +++ b/crates/akua-native-engines-npm/package.json @@ -1,6 +1,6 @@ { "name": "@akua-dev/native-engines", - "version": "0.6.0", + "version": "0.7.0", "description": "Embedded helm + kustomize wasm engines for @akua-dev/native. Platform-agnostic; one copy shared across every per-platform native addon.", "license": "Apache-2.0", "repository": { diff --git a/packages/sdk/package.json b/packages/sdk/package.json index 5600f221..02243272 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -1,6 +1,6 @@ { "name": "@akua-dev/sdk", - "version": "0.6.0", + "version": "0.7.0", "description": "TypeScript SDK for akua — render Kubernetes Packages in-process. Helm + Kustomize engines, OCI fetch, cosign verify, JSON Schema export. No `akua` binary required.", "license": "Apache-2.0", "repository": { @@ -31,7 +31,7 @@ "prepublishOnly": "bun run build" }, "dependencies": { - "@akua-dev/native": "0.6.0", + "@akua-dev/native": "0.7.0", "@standard-schema/spec": "^1.1.0", "ajv": "^8.18.0", "yaml": "^2.8.3"