Releases: sourcehawk/operator-component-framework
v0.7.1
This release replaces the repetitive per-primitive examples with focused, high-value examples that demonstrate real operator patterns. It also adds mutation ordering guidance, backward compatibility naming conventions, and exclusion-based container selectors.
Changed
- Examples replaced with pattern-focused examples: Removed 22 per-primitive boilerplate examples and replaced them with 5 examples that each demonstrate a specific operator pattern: mutations and gating, data extraction and guards, component prerequisites, custom resources, and grace inconsistency handling. Each example includes golden file tests.
- Backward compat mutation naming convention: Legacy mutations are now named
BackwardCompat<version><what>(e.g.,BackwardCompatV1Container) so the pattern is immediately recognizable when scanning a builder chain.
Added
ContainerNotNamedandContainersNotNamedselectors: New container selectors that match all containers except those with the given name(s). Useful when a mutation should apply to everything except a known sidecar or infrastructure container.EnableDebugLoggingfield onExampleAppSpec: Shared example owner spec now includes a debug logging toggle, used by the mutations-and-gating example to demonstrate mutation ordering with container name dependencies.DebugLoggingMutationexample: A new boolean-gated mutation that targets a specific container by name, demonstrating how registration order interacts with backward compat renames.test-examplesMakefile target: Example tests (golden files, mutation unit tests) now run as part ofmake allvia a dedicatedtest-examplestarget.
Documentation
- Mutation ordering and container name dependencies: New guidelines section covering how to handle mutations that depend on container names that vary across versions, with rules for broad selectors vs. registration ordering.
- Revert mutations vs. forward mutations: Expanded reasoning in the "Represent Desired State" guideline explaining why baseline-as-latest with revert mutations is easier to maintain than baseline-as-original with forward mutations.
- Backward compat naming and multi-version ordering: Guidance on the
BackwardCompatnaming convention, chained revert ordering (newest first), and the alternative non-overlapping gate approach with its tradeoffs. - Tracing sidecar GoDoc fix: Corrected comment that incorrectly said JAEGER_AGENT_HOST is set on "the application container" when it applies to all containers.
v0.7.0
This release fixes grace status handling across all primitives, adds per-resource configuration for grace inconsistency warnings, and improves documentation.
Fixed
- Grace status handlers now return Healthy when appropriate: Deployment, StatefulSet, ReplicaSet, and DaemonSet grace handlers previously never returned
GraceStatusHealthy, always reporting Degraded or Down even when all replicas were ready. They now compare ready replicas against the desired count and return Healthy when they match. - CronJob operational handler no longer reports false Pending: The default handler now always returns Operational, since a CronJob is a passive scheduler that is functioning correctly once it exists. Previously it reported Pending until the first execution, which could conflict with the grace handler.
- Grace/convergence consistency enforced: Grace handlers use
==(not>=) when comparing replica counts against desired, preventing grace from returning Healthy for states where convergence reports non-healthy (e.g., during scale-down).
Added
SuppressGraceInconsistencyWarningresource option: A new field onResourceOptions(and correspondingResourceOptionsBuildermethod) allows suppressing the per-resource warning log emitted when a grace handler returns Healthy while the convergence handler returns non-healthy. Use this when the inconsistency is intentional due to a custom handler override.- Per-resource grace inconsistency logging: The component now logs each inconsistent resource individually with its identity and convergence reason, rather than a single aggregate warning.
- Grace/convergence consistency documentation: The custom resource implementation guide (
docs/custom-resource.md) now documents the consistency invariant between convergence and grace handlers, with illustrative tables showing correct and incorrect behavior. - Guidelines: stable guard values: New guidance in
docs/guidelines.mdon preferring stable extracted values for guard conditions to avoid unintentional re-blocking after resource creation.
Documentation
- Added blog post link to README and guidelines: The Missing Layers in Your Kubernetes Operator.
- Updated AI instructions with missing documentation and package references, E2E testing guidance, and a self-maintenance callout.
v0.6.0
This release adds component-level prerequisites (initialization barriers) and a golden file testing utility for snapshot-testing primitive output.
Added
- Component prerequisites: A new
Prerequisiteinterface andWithPrerequisitebuilder method allow components to declare initialization barriers that must be satisfied before any resources are reconciled. IncludesDependsOnfor expressing inter-component ordering via status conditions. PrerequisiteStatusandPrerequisiteResult: Status types (Met,NotMet) and result struct for prerequisite check outcomes.PrerequisiteNotMetcondition reason: Components blocked by an unsatisfied prerequisite report this condition reason with the prerequisite's explanation.golden.AssertYAMLandgolden.CompareYAML: Generic snapshot testing helpers that serialize a primitive'sPreviewObjectoutput to YAML and compare against a golden file. Supports-updateflag integration and optionalWithSchemefor resolvingTypeMeta.PreviewObjecton all primitives: Every built-in primitive (21 typed + 4 unstructured) now exposesPreviewObject()for rendering post-mutation state without a live cluster.- Guidelines documentation (
docs/guidelines.md): Covers testing strategies, version-aware mutation patterns, and golden file workflow.
Changed
- Existing e2e primitive tests refactored to use shared assertion helpers from
e2e/framework.
v0.5.1
This release adds WrapGuard and WrapExtractor generic helpers that eliminate repetitive pointer-to-value callback wrapping across all primitive builders.
Added
generic.WrapGuard: Converts a value-receiver guard callback into a pointer-receiver callback for the generic builder layer. Handles nil passthrough.generic.WrapExtractor: Converts a value-receiver data extractor callback into a pointer-receiver callback for the generic builder layer. Handles nil passthrough.
Changed
- All 25 primitive builders (21 typed + 4 unstructured) now use
WrapGuardandWrapExtractorinstead of inline nil-check and closure wrapping in theirWithGuardandWithDataExtractormethods.
Docs
- Added
Guardableto the custom resource and unstructured primitive documentation. - Rewrote the custom resource mutator example to properly demonstrate
NextFeatureand per-feature plan scoping. - Updated the custom resource builder example to use value-type callbacks with
WrapGuardandWrapExtractor.
v0.5.0
This release renames the WithTruth method on ResourceOptionsBuilder to When, aligning its API with VersionGate.When() for consistency across the framework.
Changed
- ResourceOptionsBuilder: Renamed
WithTruth(bool)toWhen(bool). The semantics are unchanged: all conditions must be true for the resource to be created, evaluated with AND logic alongside any configured feature gate. - Internal field
truthsrenamed torequiredTruthsto matchVersionGateinternals.
Dependencies
- Updated
k8s.io/utilsdigest to 28399d8.
v0.4.0
This release introduces guards, a precondition system for controlling resource reconciliation order within a component.
Added
- Guards for gating resource application on preconditions. Each resource primitive can declare a guard via
WithGuard()on its builder. When a guard evaluates toBlocked, the resource is skipped and all resources registered after it in the component are also skipped. The blocked reason is surfaced in the component's status condition. Guards are not evaluated during suspension, so a component can always be fully deactivated regardless of guard state.- New
Guardableinterface andGuardStatustype inpkg/component/concepts/ WithGuard()builder method available on all primitive categories (static, workload, task, integration)- Guard-blocked resources always participate in status aggregation regardless of participation mode
- New
- Ordered resource reconciliation. Resources are now reconciled sequentially in registration order, which is required for guards to work correctly and provides deterministic reconciliation behavior.
Changed
- CI: Updated
actions/checkoutto v6.
v0.3.0
This release builds on the v0.2.0 initial release with naming improvements to the feature system and a new builder for gating resource lifecycle at the component level.
Breaking changes
The feature package has been renamed for clarity and consistency with Go naming conventions:
| Before | After |
|---|---|
feature.MutationFeature |
feature.Gate |
feature.ResourceFeature |
feature.VersionGate |
feature.NewResourceFeature(...) |
feature.NewVersionGate(...) |
Migration: These are direct renames with no behavioral changes. A find-and-replace is sufficient.
Added
ResourceOptionsBuilderfor declaratively gating resource lifecycle based on feature state. When a gate is disabled, the resource is deleted from the cluster; when enabled, it is created normally. Supports composing gates with boolean conditions viaWithTruth(), marking resources asAuxiliary()orReadOnly(), and aResourceOptionsFor()convenience function for the common single-gate case.- Compatibility tests and documentation (
docs/compatibility.md) covering controller-runtime v0.22+ support.
v0.2.0
Initial release of the Operator Component Framework, a Go library for building Kubernetes operators using a behavioral component model.
What's included
- Component system with builder API, phased reconciliation, condition aggregation, grace periods, and suspension handling
- 23 resource primitives covering core Kubernetes workload types (Deployment, StatefulSet, DaemonSet, Job, CronJob, Service, Ingress, ConfigMap, Secret, PV/PVC, RBAC resources, and more) plus an unstructured primitive for arbitrary resources
- Feature mutation system with version gating, composable mutation layers, and typed editors per resource kind
- Lifecycle interfaces (Alive, Graceful, Suspendable, Completable, Operational, DataExtractable) for expressing workload semantics
- Metrics and event recording integrations
- E2E test coverage across all primitive types
Dependencies
This release is built against:
k8s.io/apiv0.35.2k8s.io/apimachineryv0.35.2sigs.k8s.io/controller-runtimev0.23.3- Go 1.25.6+
Compatible with controller-runtime v0.22+ (Kubernetes 1.34+). Older versions are incompatible due to transitive dependency module path migrations in the Kubernetes ecosystem. See Compatibility for details on pinning to v0.22 using replace directives.
Note
This is a v0.x release. The API surface is functional and tested but may change in future minor versions based on real-world usage.