-
v0.6.28 Stable
released this
2026-07-27 23:41:29 +00:00 | 20 commits to trunk since this releaseFixed
- Bound and redact
status.migrationFailureMessage. The field was assigned
the raw migrate error, and the shared harness's 512-byte truncation applies to
condition messages and Events, not to status fields a controller assigns
itself — so an arbitrarily large third-party error body landed verbatim on the
object. The gitea SDK renders the response body into that error, and Forgejo
is free to quote submitted fields back in its message, so the credentials the
migrate request carried are now redacted by exact value (we hold them at the
call site) before the message is truncated to 512 bytes. Ordinary errors pass
through unchanged; the field is a diagnostic first.
Fixed
- Never prune branches off a repository this resource did not import. The
branch-selection finalizer added in 0.6.26 ran whenever
status.importPhase != "Succeeded", which is also what a CR reads when it
ADOPTS a pre-existing populated repository (GetRepo200) or when its status
is lost to an etcd restore, a CR recreate, or a conflicted status write. In
those states it deleted every branch exceptspec.importSource.branchoff a
canonical repository. Because the GitMirror XRD defaultsbranchtomain,
every mirrored repository was affected: an adopting reconcile of
seanfarm-gitopswould have deleted the protectedtrunkintegration branch,
and one ofsean/linuxevery open feature branch. Branch selection is now
gated on a newstatus.importedByThisResource, set only where the operator
invokes Forgejo's migrate API, so adoption and status loss both settle as
Succeededwithout mutating the repository. The 0.6.26 steady-state test did
not catch this: it keptSucceededacross reconciles, so it never exercised
the two states that arm the pruner. - Never delete an empty repository this resource did not create. The
empty-repository retry deletes before re-migrating, and its 60-minute cooldown
cannot hold back a CR whose status was wiped — a zerolastMigrationAttempt
reads as "no attempt recorded", not "not ours", so the delete fired on the
first reconcile. It is now gated on the same ownership evidence; an empty
repository we did not import is reported not-ready and left alone.
Included changes (v0.6.27 -> v0.6.28)
6a06eb2e0aa3fix(repository): bound and redact status.migrationFailureMessage7046913985e3fix(repository): gate destructive import steps on ownership evidence
Downloads
-
Source code (ZIP)
2 downloads
-
Source code (TAR.GZ)
2 downloads
- Bound and redact