• v0.6.17 e08e27ffd0

    v0.6.17 Stable

    pipeline-bot released this 2026-07-15 01:56:27 +00:00 | 47 commits to main 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 | 51 commits to main 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 | 55 commits to main 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 | 59 commits to main 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 | 63 commits to main 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 | 68 commits to main 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 | 75 commits to main 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 | 84 commits to main 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
  • v0.6.9 640e2505e2

    v0.6.9 Stable

    gitea_admin released this 2026-07-06 22:28:00 +00:00 | 91 commits to main since this release

    Added

    • ForgejoTagProtection CRD + controller: declaratively manage a repo's
      tag-protection rules (glob namePattern + whitelistUsernames/whitelistTeams)
      through the gitea SDK's tag_protections API. Because the API has no get-by-name
      and keys rules by int64 ID, Converge lists (paginated), matches on the natural
      namePattern key, create-or-edits, and stores status.tagProtectionID for
      edit/delete — mirroring ForgejoLabel. Lets tag creation (e.g. release v* tags)
      be restricted to the in-cluster pipeline identity.
    • ForgejoCollaborator CRD + controller: declaratively grant a user direct
      collaborator access (read/write/admin) on a single repository via
      AddCollaborator (idempotent PUT), removing it on delete. This is the only way to
      grant write on a user-owned repo (sean/*) — ForgejoTeam only covers
      org-owned repos — so a dedicated non-admin pipeline-bot can be given write on
      each pipeline repo without the site-admin token.
    • ForgejoBranchProtection: merge-whitelist fields (enableMergeWhitelist,
      mergeWhitelistUsernames, mergeWhitelistTeams). With push disabled, protected
      branches advance only via PR merges; enabling this + listing pipeline-bot forces
      every change to a protected branch through the pipeline (no human or bot outside
      the whitelist can merge).

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

    • 4b1c1ef9e473 feat(crd): ForgejoTagProtection + ForgejoCollaborator + merge-whitelist
    • c0152458da61 fix(cicd): auto-resolve CHANGELOG land conflicts via .gitattributes merge=union
    • 16b1f5d488f5 fix(ci): pin golang:1.26 builder base by digest
    • a6ab3a1ab9ca chore: retrigger CI (transient buildkit lease error)
    • 8c50685f4aa8 docs(forgejorepository): correct stale cloneAddrFor comment (no server derivation)
    Downloads
  • v0.6.8 8e5e9ce118

    v0.6.8 Stable

    gitea_admin released this 2026-07-03 22:53:36 +00:00 | 103 commits to main since this release

    Added

    • Unit tests for the import-source helpers cloneAddrFor / serviceTypeFor:
      cover the TypeCloneAddr and TypeGitServiceType mappings,
      including the gitea-default and plain-git fallback paths.
    Downloads