• v0.6.19 3b95b04bf9

    v0.6.19 Stable

    pipeline-bot released this 2026-07-15 15:55:00 +00:00 | 64 commits to trunk since this release

    Changed

    • Bump libseanfarm-operator v0.4.7 -> v0.4.9: picks up the six shared-harness fixes from
      the R5 bug-hunt (dry-run delete no longer touches the remote, Degraded message truncation,
      Progressing cleared on failure, dry-run clears stale Degraded/Progressing, empty
      Ready=False reason defaults to NotReady instead of a silently-swallowed 422,
      dry-run converge now runs MirrorStatus).

    Included changes (v0.6.18 -> v0.6.19)

    • 3499dcec9424 fix(deps): bump libseanfarm-operator v0.4.7 -> v0.4.9
    Downloads
  • v0.6.18 ad3999db2e

    v0.6.18 Stable

    pipeline-bot released this 2026-07-15 12:47:38 +00:00 | 68 commits to trunk since this release

    Fixed

    • ForgejoWebhook.Delete no longer leaks the remote hook (which carries a delivery secret) when
      the status id was never persisted — it recovers the id via ListRepoHooks match-by-URL, mirroring
      the other ID-keyed Delete handlers, tolerating 404 on both the list (parent repo gone) and the delete.
    • ForgejoUser admin-grant failure is no longer swallowed on the create path — a failed
      AdminEditUser now yields Degraded+requeue instead of a premature Ready reporting an account that
      was created but is not an admin (matching the exists-path).
    • ForgejoOAuthApp self-heals a lost one-time client secret. The client secret is returned only by
      create, so a swallowed secret-write (app recorded, output Secret never written) left the CR Ready
      with no usable secret and no recovery. Converge now regenerates via UpdateOauth2 when the output
      Secret is absent/empty.
    • ForgejoOAuthApp.spec.name is now immutable (self == oldSelf). The reconciler adopts the app by
      name, so an in-place rename orphaned the original app and leaked its still-valid client secret.
    • ForgejoToken re-mints on a spec.scopes change. The active token kept its create-time scopes
      forever (a tightened scope set left an over-privileged token live, reported Ready). Steady-state now
      compares spec.scopes against a new status.appliedScopes recorded at mint — a spec-vs-applied
      compare, deliberately not against Forgejo's normalized scope form, so it can't thrash-loop.
    • ForgejoOrganization visibility drift is now repaired — editing spec.visibility after create
      applies. The edit sends the full desired org state, because gitea's EditOrgOption text fields are
      value-typed and the server replaces them — so a single-field edit no longer silently wipes the
      org's FullName/Description/Website/Location (this also fixes the same latent clobber that
      already existed on the text-field edit path).

    Included changes (v0.6.17 -> v0.6.18)

    • 0f205f8076e8 fix(forgejo): r5 leak/swallow/immutability/drift cluster (6 fixes)
    Downloads
  • v0.6.17 e08e27ffd0

    v0.6.17 Stable

    pipeline-bot released this 2026-07-15 01:56:27 +00:00 | 72 commits to trunk since this release

    Fixed

    • ForgejoRepository.spec.owner is now immutable, matching its sibling spec.name and every
      other identity field across the API. A repository's identity is (owner, name) — the reconciler
      keys GetRepo/CreateOrgRepo/DeleteRepo on both — so editing owner in place would create a
      new repo under the new owner and orphan the original in Forgejo (the finalizer only deletes the
      new owner/name). The lifecycle-contract doc already declared owner part of the immutable identity;
      this adds the self == oldSelf CEL validation that was missing on that one field. The migration
      importSource.owner stays mutable (it is a one-shot seed source, not the repo's identity).

    Included changes (v0.6.16 -> v0.6.17)

    • 1e24fc9588e5 fix(repository): make spec.owner immutable (matches spec.name + closes an orphan foot-gun)
    Downloads
  • v0.6.16 5cd10d9dde

    v0.6.16 Stable

    pipeline-bot released this 2026-07-14 21:07:41 +00:00 | 76 commits to trunk since this release

    Fixed

    • Delete no longer leaks a remote resource (or its live credential) when the status ID was
      never persisted.
      Six ID-keyed finalizer Delete handlers — ForgejoOAuthApp, ForgejoSSHKey,
      ForgejoLabel, ForgejoRelease, ForgejoTagProtection, ForgejoTeam — no-op'd when their
      Status.<X>ID == 0, so a CR deleted after the remote create landed but before its status write
      persisted orphaned the resource in Forgejo forever. For an OAuth app that means a live client
      secret, and for an SSH key a live public key, outliving the deprovisioned CR. Each Delete now
      recovers the target ID via the same natural-key lookup its Converge already uses to adopt an
      existing resource
      (OAuth app by name, SSH key by username+title, label/tag-protection by
      name/pattern, release by tag, team by org+name) before deleting. The OAuth-app fallback deletes
      every same-name app it owns, matching Converge's duplicate-pruning model.
    • Finalizer Delete is now idempotent on a 404. All six handlers (plus the shared is404 helper)
      treat an already-absent remote resource as a completed delete, so a benign race — deleted out of
      band, or a retried finalizer after the first delete landed — no longer surfaces a spurious error.
      The four parent-scoped fallback lookups (label/tag-protection by repo, SSH key by user, team by
      org) also tolerate a 404 on the list itself: when the parent repo/user/org was deleted (tenant
      teardown cascade), the child is already gone, so Delete cleanly no-ops instead of erroring. A
      non-404 list failure (transient 5xx) still surfaces. (forgejodelete_leak_test.go:
      recovers-ID-when-status-empty, idempotent-404, parent-gone, and non-404-propagates coverage.)

    Included changes (v0.6.15 -> v0.6.16)

    • ec47ea8d9b31 fix(delete): recover remote id via natural key so a status-lost CR can't leak
    Downloads
  • v0.6.15 c447350ffe

    v0.6.15 Stable

    pipeline-bot released this 2026-07-14 17:22:43 +00:00 | 80 commits to trunk since this release

    Changed

    • Incremental release.

    Included changes (v0.6.14 -> v0.6.15)

    • 829cbc165461 fix(forgejo): 3 credential/reconcile bugs (password loss, team pagination, webhook secret rotation)
    Downloads
  • v0.6.14 08ed61f5b1

    v0.6.14 Stable

    pipeline-bot released this 2026-07-13 18:51:57 +00:00 | 84 commits to trunk since this release

    Fixed

    • Bump libseanfarm-operator v0.4.1 → v0.4.7. Picks up six releases of shared reconcile-
      harness fixes + test coverage the operator was missing, notably the v0.4.4 fix that stops the
      harness stamping ObservedGeneration on a Converge error under ObservedGenOnConvergedOnly.
      Build + full envtest controller suite green on v0.4.7.

    Included changes (v0.6.13 -> v0.6.14)

    • 8652fd08c969 fix(deps): bump libseanfarm-operator v0.4.1 -> v0.4.7 (blocker: ObservedGen-stamp-on-error)
    Downloads
  • v0.6.13 350264ebfd

    v0.6.13 Stable

    pipeline-bot released this 2026-07-09 06:44:18 +00:00 | 88 commits to trunk since this release

    Changed

    • Incremental release.

    Included changes (v0.6.12 -> v0.6.13)

    • 51cad7e65ad4 test: green the controller suite so CI can gate on it
    Downloads
  • v0.6.12 3183ded6bf

    v0.6.12 Stable

    pipeline-bot released this 2026-07-09 00:56:38 +00:00 | 93 commits to trunk since this release

    Changed

    • Incremental release.

    Included changes (v0.6.11 -> v0.6.12)

    • d53e90cb8477 docs(crd): lifecycle contracts across the forgejo CRDs (kubectl explain)
    • ce2a4da47cc1 docs(collaborator): surface the lifecycle contract in the CRD (kubectl explain)
    Downloads
  • v0.6.11 8d7b572d6e

    v0.6.11 Stable

    pipeline-bot released this 2026-07-07 19:36:41 +00:00 | 100 commits to trunk since this release

    Changed

    • ForgejoTagProtection + ForgejoCollaborator: skip the write when already in
      sync, so steady-state reconciles no longer edit/re-grant every requeue. Tag
      protection compares the live whitelist (order-insensitive) before
      EditTagProtection; the collaborator grant is skipped when the user is already
      a direct collaborator (IsCollaborator) at the desired permission
      (CollaboratorPermission, with owner→admin coercion) — gated on direct
      membership so an effective-permission match (repo owner, org admin, or
      public-repo reader) never skips a genuinely-needed grant. This completes the
      drift-skip audit: the other 10 controllers already diff-gate their writes.
    • Cut steady-state Forgejo API load. The gitea client — and its construction-time
      GET /api/v1/version probe — is now cached per endpoint instead of rebuilt on
      every reconcile of every resource, so the version is probed once per credential
      rather than once per reconcile (~halving API calls); all clients share one
      connection-pooled http.Transport with a larger per-host idle pool. The default
      drift-resync interval is raised from 5m to 15m — Forgejo has no watch/event API
      for the settings these controllers manage, so periodic resync is the only drift
      signal, and since the operator is the writer, drift is rare.
    • Reconcile + client timings are now configurable (defaults unchanged in spirit)
      via flags that govern all controllers uniformly through the shared harness:
      --resync-interval, --progressing-interval, --transient-interval,
      --forgejo-client-timeout, --max-concurrent-reconciles, --retry-base-delay,
      --retry-max-delay. Previously these were hardcoded.

    Included changes (v0.6.10 -> v0.6.11)

    Downloads
  • v0.6.10 703b79253c

    v0.6.10 Stable

    pipeline-bot released this 2026-07-07 18:55:05 +00:00 | 109 commits to trunk since this release

    Fixed

    • ForgejoBranchProtection: address the rule by its rule name, not the branch
      name, on the check/edit path. Forgejo keys branch_protections/{name} on
      rule_name (which only defaults to the branch name at create time), so a CR
      whose spec.ruleName differed from spec.branchName re-checked by branch name,
      404'd, re-created, and Forgejo 409'd — the resource never converged and hammered
      Forgejo every requeue. Resolve the rule name once (status → spec.ruleName
      branch) and key GET/EDIT/DELETE on it consistently.
    • ForgejoBranchProtection: Delete now derives the rule name from spec when
      status.ruleName is unset (a created-but-status-lost rule is cleaned up instead
      of orphaned), and treats a delete 404 as success (idempotent finalizer).
    • ForgejoBranchProtection: skip the edit PATCH when the live rule already
      matches every managed field, cutting steady-state write load to Forgejo.

    Added

    • First handler-level unit tests against a fake Forgejo (httptest) — create,
      edit, rule-name idempotency, in-sync skip, error propagation, and delete
      (by-rule-name, idempotent 404, derive-from-spec, no-op) for
      ForgejoBranchProtection.
    • ForgejoToken CRD + controller: declaratively mint and rotate a Forgejo
      personal access token into a Secret. The controller authenticates as
      spec.username via HTTP Basic auth using the password in spec.authSecretRef
      (Forgejo's POST /users/{user}/tokens accepts BasicAuth only — a token cannot
      mint a token), mints a uniquely-named scoped PAT, writes it to spec.output,
      and revokes the previous one (mint-before-revoke → no credential gap). Rotation
      is controller-enforced on spec.rotateEvery (default 168h) because Forgejo 14
      PATs carry no server-side expiry; it also re-mints whenever the active token
      is missing server-side
      (e.g. after a Forgejo migration wipes tokens), so the
      credential self-heals instead of silently going stale — replacing the one-shot,
      never-rotating *-token-issuer Jobs. Owns tokens by name prefix (<base> /
      <base>-<n>), prunes stragglers, and revokes on delete. Purpose-built to retire
      the fragile forgejo-admin-token / forgejo-pipeline-bot-token issuers.

    Included changes (v0.6.9 -> v0.6.10)

    • 729bd6adede9 feat(forgejotoken): CRD + controller to mint & rotate Forgejo PATs
    • f16707ea1701 fix(branchprotection): key rule ops by rule name, not branch name
    Downloads