-
v0.4.13 Stable
released this
2026-07-23 12:52:06 +00:00 | 0 commits to main since this releaseFixed
- Best-effort progress and failure status writes now use the shared conflict
retry path, so a routine Kubernetes409 Conflictno longer drops the
condition that explains why reconciliation failed. reconcile/testkit.Env.Stopis safe after envtest setup fails, preserving the
original startup error instead of masking it with a nil-pointer panic in suite
teardown.
Included changes (v0.4.12 -> v0.4.13)
8b112a021dedfix(reconcile): retry best-effort status conflicts
Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
- Best-effort progress and failure status writes now use the shared conflict
-
v0.4.12 Stable
released this
2026-07-17 09:42:17 +00:00 | 4 commits to main since this releaseAdded
- operator.mk — the canonical shared Makefile scaffolding. Tool pins + installers
(ENVTEST_VERSION derived from controller-runtime, ENVTEST_K8S_VERSION derived
MINOR-only from k8s.io/api — full-patch derivation failed live on 1.35.2) and the core
dev-loop targets. Operators vendor a copy +includeit; the lib-bump autoland
re-syncs the copy from each release tag, so toolchain scaffolding can never silently
drift again (kratos sat on release-0.19/golangci-v1 for months unnoticed).
Included changes (v0.4.11 -> v0.4.12)
d32a8df94166feat(operator.mk): canonical shared Makefile scaffolding for the operators
Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
- operator.mk — the canonical shared Makefile scaffolding. Tool pins + installers
-
v0.4.11 Stable
released this
2026-07-16 14:26:48 +00:00 | 8 commits to main since this releaseAdded
- The extraction wave — the shared surfaces every operator hand-rolled:
Config.IsRemoteGone: the harness folds "remote already gone" Delete errors into an
idempotent finalize (the status-lost-CR credential-leak class was fixed independently
in two repos within 24h; unmatched errors keep today's semantics, so deliberate holds
like kratos's ambiguous-miss grace still work).reconcile.Metrics(+Config.Metrics/MetricsController): reconcile passes,
durations, status-write outcomes, andInstrumentedCall/RecordCallfor API
clients — namespaced so adopting operators keep their metric names; domain gauges
stay operator-side. Replaces kratos's 173-line kit + openbao's ~300-line middleware,
and gives forgejo/pipelines-operator/minio coverage for free.SecretValue/HashValue/HashCanonical: the write-only-secret drift leaves,
supporting BOTH fingerprint conventions (hash for high-entropy material;
resourceVersion for low-entropy, per kratos's documented security choice).httpkit:ClusterCATransport(trust-bundle + shared pooling tuning),
CredentialCache[C](rotation-aware client cache — the VSO/ESO rotated-token
contract),BoundedRead/ErrorExcerpt(bounded to the condition-message limit).
Included changes (v0.4.10 -> v0.4.11)
adb1dcf72a52feat(extract): IsRemoteGone delete fold + Metrics kit + secret-drift helpers + httpkit
Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
- The extraction wave — the shared surfaces every operator hand-rolled:
-
v0.4.10 Stable
released this
2026-07-15 17:20:35 +00:00 | 12 commits to main since this releaseAdded
reconcile/testkit— the shared test surface consumer operators have been
copy-pasting:FakeCR/FakeCRRetainschemed test CRs,StubHandlerscripted
handler family,NewScheme/NewClient/GetObject/Conditionhelpers,
ConflictOnceClient,BaseConfig, andStartEnvtest(framework-agnostic envtest
bring-up with bin/k8s binary discovery — replaces the ~120-line suite_test.go
duplicated across every operator). The lib's own harness suite now runs on it.- Inverse-gap tests promoted from operator repos to the source:
StatusUpdateBestEffort(was only proven in openbao), LastTransitionTime
preservation through theRunflow (was openbao's 386-line e2e suite),
RemoveFinalizerno-op-when-missing, andMirrorStatusPhaseFailed/PhaseDeleting
hook coverage (was only proven via kratos's mirror tests).
Included changes (v0.4.9 -> v0.4.10)
66eebb3bf593feat(testkit): shared test surface + inverse-gap tests promoted from operators
Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
-
v0.4.9 Stable
released this
2026-07-15 14:48:19 +00:00 | 16 commits to main since this releaseFixed
reconcile: aReady=Falsecondition with an empty caller-supplied reason is no longer emitted —
ReadyFalsenow defaults an empty reason toNotReady. The Kubernetes API rejects a condition with
an emptyReason(422FieldValueRequired), so an outcome that reached the failure path with no
reason previously produced an unwritable condition (silent status-write failure). (ReadyTruewas
already safe — it always uses a constant reason.) (+TestReadyFalse_DefaultsEmptyReason)reconcile: the dry-run converge path now callsMirrorStatusbefore persisting, like every
other status-writing path. A dry-run CR isReady, but the legacy mirrored fields were left
reflecting the prior phase — permanently inconsistent withReady=Truefor operators that use a
MirrorStatushook. (No-op whenMirrorStatusis nil, so operators without one are unaffected.)
Included changes (v0.4.8 -> v0.4.9)
6d458960cddbfix(reconcile): default empty Ready=False reason (422 guard) + mirror on dry-run
Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
-
v0.4.8 Stable
released this
2026-07-14 20:17:47 +00:00 | 20 commits to main since this releaseFixed
reconcile: dry-run is now symmetric on delete — a dry-run CR no longer performs a
realResolve+Deleteagainst the remote on deletion (which destroyed state it promised
never to touch, or wedged undeletable underHoldUntilSuccess). The K8s-sideCleanup
and finalizer removal still run, so the CR deletes cleanly. (+TestRunDeleteDryRun)reconcile: theDegradedcondition message is now bounded bytruncateMessage(like
Ready=False/SetCondition), so a splatted remote-error body can't exceed the etcd
condition-message bound or over-disclose.reconcile: a Degraded/failed object no longer retains a staleProgressing=True
(self-contradictoryReady=False+Degraded=True+Progressing=True);
markDegradedStyleclears it — covering the convergefailPathand both delete-path
failure calls.reconcile: the converge dry-run gate now clears any staleDegraded/Progressingleft
by a prior non-dry-run reconcile, so a dry-run CR isn't reportedReadyandDegraded
at the same time.
Included changes (v0.4.7 -> v0.4.8)
530056d18615docs(changelog): promote Unreleased to [0.4.8] (mid-flight release recovery)df747dd747c9docs(changelog): add Unreleased section for the harness fixes (v0.4.8)2ec43c5f29d7fix(reconcile): 4 shared-harness bugs (dry-run delete, Degraded truncation, stale Progressing)ed2fa525f665fix(cicd): auto-resolve CHANGELOG land conflicts via .gitattributes merge=unionb040ae77b5d9fix(ci): pin golang:1.25 builder base by digestc3d82fe13b67docs(readme): Recorder events are size-bounded, not sanitized7d62c566920cchore(staging): open v0.4.8-dev dev cycle
Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
-
v0.4.7 Stable
released this
2026-07-01 14:36:09 +00:00 | 34 commits to main since this releaseAdded
reconcile: unit coverage forCadences.withDefaults— the previously-unexercised
defaulting branches.TestCadencesWithDefaultsasserts each zero-value field
resolves to its documented default (Ready5m,Transient30s) and that the
subtleProgressing → Transientfallback resolves to the already-defaulted
Transient: a zeroProgressingtracks the resolvedTransient(explicit45s
when set, else the30sdefault) rather than a stale zero, while explicit values
are preserved intact. Every other harness test sets all three cadences explicitly,
so these branches had no coverage.
Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
-
v0.4.6 Stable
released this
2026-07-01 10:18:41 +00:00 | 39 commits to main since this releaseAdded
reconcile: unit coverage for two previously-untested public-API contracts —
ReasonedError.Unwrap(errors.Is/errors.Unwrap transparency, so a
Failf(reason, "…: %w", cause)stays matchable byerrors.Is(err, cause)while
keeping its Degraded reason recoverable viaReasonOf) and the
RequeueTransientOfplain-error fallback (a non-reasoned error classifies as
non-transient).reason.gopreviously had only incidental coverage from
reconcile_test.go.
Changed
- CI: route Go module fetches through the in-cluster Athens proxy (
GOPROXY, with a
directfallback) and add buildkitgomod/go-buildcache mounts to
ci.Dockerfile— a cold build no longer re-downloads the whole module graph from
proxy.golang.org.
Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
-
v0.4.5 Stable
released this
2026-06-28 16:09:24 +00:00 | 47 commits to main since this releaseChanged
- First release shipped through the consolidated, ArgoCD-delivered pipeline —
the go-library-tag taxonomy now rides the same shared templates as zdns
(pipeline-build-buildkitvalidate +pipeline-test-noop+pipeline-promote-tag,
fromsean/pipelinesvia the registry ApplicationSet), no per-projectscripts/set.
Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
- First release shipped through the consolidated, ArgoCD-delivered pipeline —
-
v0.4.4 Stable
released this
2026-06-28 10:36:36 +00:00 | 48 commits to main since this releaseFixed
- The reconcile harness no longer stamps
ObservedGenerationon a Converge
error underObservedGenOnConvergedOnly. A failed generation is
not-yet-converged — exactly like a Progressing one — and must stay
"unobserved", or a consumer's ObservedGeneration-keyed convergence fast path
(kratos) short-circuits the failed generation on the next pass and masks the
error as Ready.ObservedGenOnAllSuccessis unchanged (it records the failing
generation so kstatus reads Failed, not InProgress). Adds
TestRunErrorObservedGenPolicy— the error-path mirror of the existing
Progressing/ObservedGeneration test.
Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
- The reconcile harness no longer stamps