Skip to content
Release Radar

Kube Resource Orchestrator for composing Kubernetes APIs

v0.9.439 days after v0.9.3
View on GitHub

Release history

v0.9.4

CompareGitHub

What's Changed

New Contributors

Full Changelog: https://github.com/kubernetes-sigs/kro/compare/v0.9.3...v0.9.4

What's Changed

New Contributors

Full Changelog: https://github.com/kubernetes-sigs/kro/compare/v0.9.2...v0.9.3

What's Changed

New Contributors

Full Changelog: https://github.com/kubernetes-sigs/kro/compare/v0.9.1...v0.9.2

What's Changed

Full Changelog: https://github.com/kubernetes-sigs/kro/compare/v0.9.0...v0.9.1

๐Ÿ”† Highlights

Cluster-Scoped Instance CRDs (KREP-10)

RGDs can now generate cluster-scoped instance CRDs. Add scope: Cluster to your schema and kro produces a non-namespaced CRD. Namespaced child resources must explicitly declare metadata.namespace when the instance is cluster-scoped. The field defaults to Namespaced and is immutable after creation. Docs

includeWhen Can Reference Upstream Resources

includeWhen expressions are no longer limited to schema fields - they can now reference other resources in the graph. kro treats these references as real dependencies that participate in DAG construction and cycle detection. Docs.

Decorators - External Collections (KREP-008)

ExternalRef previously only supported name and namespace for scalar lookups. They now support full matchLabels and matchExpressions selectors, so a single externalRef can match multiple resources dynamically. Selector values accept CEL expressions. Docs

Reactive Watches on External References and Decorators (KREP-003)

kro now watches external references - both scalar and collections โ€” and re-reconciles instances instantly when an external resource is created, updated, or deleted. (Docs)

omit() CEL Function ( โš ๏ธ feature-gated: CELOmitFunction)

A new CEL omit() function lets you conditionally remove fields from rendered templates. Use ${schema.spec.kmsKeyID != "" ? schema.spec.kmsKeyID : omit()} and the field is dropped entirely from the SSA payload - important for APIs that distinguish between field absence and an empty value. omit() is rejected on required metadata fields (name, namespace, apiVersion, kind). Alpha, default off. Docs

Instance Status Condition Events (โš ๏ธ feature-gated: InstanceConditionEvents)

kro can now emit Kubernetes Events when instance status conditions transition between reconciliation cycles. Events show the transition as "False โ†’ True: ResourcesReady" and are typed Normal for transitions to True, Warning for everything else. Visible via kubectl describe on any instance. Alpha, default off. Docs

CEL Libraries Enrichment

The CEL environment gained nine new capabilities:

  • json: json.marshal() and json.unmarshal() for working with JSON payloads directly in expressions
  • maps: map.merge() to combine two maps with second-map-wins semantics
  • lists: lists.setAtIndex(), lists.insertAtIndex(), lists.removeAtIndex() for immutable list mutations; k8s Lists library for lists.concat() and friends
  • quantity: parse and manipulate Kubernetes Quantities ("500m", "2Gi") natively
  • bind: cel.bind(varName, init, body) to name intermediate values and reduce repetition
  • comprehensions: TwoVarComprehensions (transformMap, transformList) and sortBy for stable ordering by arbitrary expressions
  • random: random.seededInt(min, max, seed) for deterministic integer generation from resource UIDs

Graph Revisions (KREP-013)

RGD specs are now versioned. Each spec change creates an immutable GraphRevision snapshot (kubectl get gr) that is compiled and validated independently before instances can use it. If a new spec breaks compilation, instances block with a clear status instead of failing silently โ€” you see exactly which revision failed and why via kubectl describe gr. kro retains the last 5 revisions per RGD (configurable), giving you an audit trail of every spec change. More importantly, Graph Revisions lay the foundation for progressive rollouts and revision pinning in future releases. Docs. Docs

โœจ Features

  • feat: implement KREP-10 - support cluster-scoped instance CRDs by @antcybersec in #1152
  • feat: external ref watches and external ref collections by @jakobmoellerdev in #1079
  • feat: support CEL expressions in LabelSelectors for external collections by @jakobmoellerdev in #1079
  • feat: disable instance reconciliation when a kro.run/reconcile:"disabled" label is present by @NickKeller in #1062
  • feat(cel): add omit() for conditional field omission in templates by @michaelhtm in #1139
  • feat(events): Add events for instance status condition transition by @spattk in #1151
  • feat(#510): implement standard Kubernetes feature gates via component-base by @jakobmoellerdev in #1172
  • feat(helm): expose feature gates in chart values by @a-hilaly in #1187
  • feat(graph): gate omit() behind CELOmitFunction feature flag by @a-hilaly in #1185
  • feat(graph): reject omit() on required resource metadata fields by @michaelhtm in #1167
  • feat: allow includeWhen to reference other resources by @a-hilaly in #1104
  • feat(cel): add json.marshal and json.unmarshal CEL functions by @NicholasBlaskey in #1033
  • feat(cel): add map library with merge functionality by @a-hilaly in #1068
  • feat(cel): add index-mutation functions to the lists library by @pnz1990 in #1148
  • feat(cel): add k8s Lists library support by @NicholasBlaskey in #1178
  • feat(cel): add k8s Quantity library support by @NicholasBlaskey in #1177
  • feat(cel): add cel.bind() support to default environment and AST inspector by @pnz1990 in #1145
  • feat(cel): add support for TwoVarComprehensions in CEL environment by @jakobmoellerdev in #1136
  • feat(cel/ast): improve loop variable scoping and support sortBy comprehension by @jakobmoellerdev in #1136
  • feat(cel): add deterministic seeded integer generation function by @a-hilaly in #1108
  • feat(cel): add version support for the cel json library by @NicholasBlaskey in #1033
  • feat(compat): detect default value changes as non-breaking in schema comparison by @michaelhtm in #1098
  • feat(instance): block graph propagation on terminating managed resources by @a-hilaly in #1132
  • feat(helm): add topologySpreadConstraints in deployment by @QuentinBtd in #1137
  • feat: Add opt-in pprof profiling support via build tags by @a-hilaly in #922
  • feat: make instance requeue interval configurable by @a-hilaly in #1184
  • feat: expose leader election tuning flags in helm chart by @a-hilaly in #1205
  • feat: add metrics for pkg/runtime by @NicholasBlaskey in #1053
  • feat: Add RGD controller metrics by @NicholasBlaskey in #1063
  • feat: Add instance controller metrics by @NicholasBlaskey in #1056
  • feat(cel): add metrics for CEL cache hit/miss tracking by @a-hilaly in #1142
  • feat: Add client-go and reflector metrics registration by @a-hilaly in #1143
  • feat: Use expressive histogram buckets for controller reconciliation metrics by @a-hilaly in #1157
  • feat: Implementation of Graph Revisions (KREP-013) by @a-hilaly in #1085
  • feat: Watch owned GraphRevisions from the RGD controller by @a-hilaly in #1200
  • feat: watch graph revisions by spec.snapshot.name for orphan adoption by @a-hilaly in #1206
  • feat: Limit collection size to 1000 to protect cluster performance by @NicholasBlaskey in #1036
  • feat: limit collection dimension to 5 by @michaelhtm in #1045
  • feat: disable instance reconciliation with annotation instead of label by @michaelhtm in #1191
  • feat: KREP-15 label/annotation migration to internal.kro.run/ prefix by @michaelhtm in #1094

๐Ÿ› Bug Fixes

  • fix: flaky validate RGD status test by @michaelhtm in #1034
  • fix: flaky validate RGD status integration test by @Aman-Cool in #1041
  • fix(docs): Wrong schema apiVersion definition in RGD chaining by @gagahsyuja in #1050
  • fix: properly return error in simpleschema parsing when the marker does by @NickKeller in #1073
  • fix: remove the rgd labels from managed resources by @jakobmoellerdev in #1075
  • fix(applyset): preserve prune scope on UID conflicts and requeue retry by @a-hilaly in #1081
  • fix: pass up expressive error by @fabianburth in #1078
  • fix(runtime): schema-aware CEL value conversion by @jakobmoellerdev in #1080
  • fix: show root cause error by @fabianburth in #1160
  • fix(dynamic): skip parent instance events with unchanged generation by @jakobmoellerdev in #1173
  • fix(metadata): skip instance-namespace label for cluster-scoped instances by @a-hilaly in #1175
  • fix(docs): correct RGD conditions by @a-hilaly in #1181
  • fix(collections): register collection watch for all expanded resources by @a-hilaly in #1182
  • fix(cel): handle oneOf string|number schemas in UnstructuredToVal by @a-hilaly in #1179
  • fix: return a requeue error when waiting for readiness by @fabianburth in #1090
  • fix: do not count requeue signals as handler errors in dynamic_controller_handler_errors_total by @Avr8 in #1059
  • fix(cel): sort transformList result before comparison in TwoVar test by @a-hilaly in #1141
  • fix: add instance state in progress case by @fabianburth in #1090
  • fix(graph/resolver): expose schema resolver metrics on controller-runtime registry by @a-hilaly in #1113
  • fix: ResourceGraphDefinition delete predicate handling by @a-hilaly in #1097
  • fix(externalref): allow external collections to list across all namespaces by @a-hilaly in #1180
  • fix: tighten cluster-scoped instance namespace validation by @a-hilaly in #1152
  • fix: handle cluster-scoped instances in reconciliation and SSA patches by @a-hilaly in #1152
  • fix(instance): surface graph resolution failures in conditions and metrics by @a-hilaly in #1201
  • fix: get rid of cel build caches due to problems during stabilization by @jakobmoellerdev in #1195
  • fix: missing dynamic controller registration, and wire up missing metrics by @jakobmoellerdev in #1146

โšก Performan

โ€ฆ(truncated)

Highlight

  • Fixed context building to properly distinguish between "not yet observed" (nil) and "observed but empty" ([]) collections. This was causing instances with empty forEach results to get stuck in IN_PROGRESS forever - dependents couldn't evaluate CEL expressions like size(entries) because empty collections were being excluded from context entirely.

  • CEL programs are now compiled once at build time and reused across reconciles. Previously we were re-parsing, re-compiling, and throwing away the program on every single evaluation. The new runtime now holds both the original string and the compiled program, so runtime skips straight to evaluation.

  • Schema lookups now handle additionalProperties, which is how Kubernetes represents map types like ConfigMap.data. Without this, the CEL type checker couldn't validate writes to map fields and silently missed type mismatches.

๐Ÿš€ Features

๐Ÿ› Bug fixes

๐Ÿ”ง Refactoring

๐Ÿงน Chores

New Contributors

Full Changelog: https://github.com/kubernetes-sigs/kro/compare/v0.8.4...v0.8.5

Highlight

Fixed child resource events triggering reconciliation on the wrong instance controller, and fixed release builds getting tagged with a dirty suffix.

๐Ÿ› bug fixes

๐ŸŒฑ Other

New Contributors

Full Changelog: https://github.com/kubernetes-sigs/kro/compare/v0.8.1...v0.8.2

๐Ÿ”† Highlights

Collections Support (KREP-002)

RGDs now support Collections: define one template and kro expands it into many resources at runtime. Collections introduce a new forEach directive that lets a CEL expression drive the iteration, and the controller keeps each generated resource in sync as items are added, changed, or removed. This makes multiโ€‘resource expansion practical without handโ€‘authoring repeated blocks. (Docs, #936, #679)

Recursive Custom Types in RGD Schema

RGD schemas now allow custom types to reference other custom types, so you can build reusable, nested data structures instead of duplicating field definitions. This improves schema hygiene for complex specs and statuses while keeping validation intact. (Docs, #950)

Breaking Schema Change Detection

kro now diffs RGD schemas before updating CRDs and blocks incompatible changes (like removing fields, changing types, or adding required properties) by default. This prevents accidental breaking updates to existing instances; use the kro.run/allow-breaking-changes: "true" annotation to intentionally override. (Docs, #352)

โœจ Features

  • feat: add Collections support + runtime/controller rewrite by @a-hilaly in #936
  • feat: KREP-002 declarative resource collections support by @a-hilaly in #679
  • feat(simpleschema): add support for recursive custom types by @shivansh-gohem in #950
  • feat(crd): Detect and prevent breaking schema changes in RGDs by @a-hilaly in #352
  • feat: add early validation for apiVersion and kind to fail fast by @antcybersec in #980
  • feat: add controller warmup support for faster leader failover by @a-hilaly in #955
  • feat: add DurationType and TimestampType conversion to go native types by @shabbskagalwala in #960
  • feat: add bytes conversion to go native types by @shabbskagalwala in #951
  • feat: add support for labels and annotations in the generated CRDs by @cnvergence in #916

๐Ÿ› Bugfixes

  • fix(graph): reject cluster-scoped resources with namespace set by @a-hilaly in #976
  • fix(schema): preserve nested array/object paths in status schema by @a-hilaly in #972
  • fix(schema): use date-time format for timestamps by @a-hilaly in #973
  • fix(dag): preserve vertex order when dependencies are satisfied by @a-hilaly in #958
  • fix: Convert CEL type to Go type recursively by @cirias in #940
  • fix: Support []object and map[string]object types in RGD schema by @kunalvirwal in #939
  • fix: Prevent random.* from being classified as a resource in #919
  • fix(release): capture GIT_VERSION once to prevent -dirty suffix in LDFLAGS by @a-hilaly in #982
  • fix(cluster-mgmt): ensure access to workload cluster is granted before argocd secret create by @iamahgoub in #966
  • fix(graph): replace panic in CRD graph builder with proper error handling by @AnshulPatil2005 in #901

โšก Performance

๐Ÿ“– Documentation

  • docs: expand collections gotchas and cross-references by @a-hilaly in #971
  • docs(cel): explain multiline expressions and YAML chomping by @a-hilaly in #974
  • fix(website): version CRD with docs snapshots by @a-hilaly in #978
  • Docs: manifests download URL changed to match actual URL by @hatofmonkeys in #925
  • fix: Fixed Quickstart instance.yaml sample on document by @ricky9408 in #913
  • docs: correct apiVersion for Application example by @birapjr in #899
  • fix: url in kubectl commands for upgrade and delete by @Fsero in #938

๐Ÿงช Testing

๐ŸŒฑ Other

New Contributors

Full Changelog: https://github.com/kubernetes-sigs/kro/compare/v0.7.1...v0.8.0