Skip to content

fix: switch tenant apps to native OCIRepository semver selection#1588

Merged
botantler[bot] merged 2 commits into
mainfrom
claude/tenant-image-automation-jnY6v
May 27, 2026
Merged

fix: switch tenant apps to native OCIRepository semver selection#1588
botantler[bot] merged 2 commits into
mainfrom
claude/tenant-image-automation-jnY6v

Conversation

@devantler
Copy link
Copy Markdown
Contributor

Why

Tenant image automation (wedding-app, ascoachingogvaner) was effectively broken.

The prod cluster reconciles everything from the platform's own OCI artifact (ghcr.io/devantler-tech/platform/manifests:latest) — never from Git directly (every Flux Kustomization in k8s/bases/cluster/ sources OCIRepository/flux-system). The old design used ImageUpdateAutomation to commit tenant OCIRepository.ref.tag bumps into Git main. But for such a commit to reach the cluster it had to trigger a full platform release: semantic-release tag → cd.yaml → republish the platform OCI :latest → cluster pulls → re-applies sync.yaml. Every tenant app update was therefore coupled to a full platform redeploy — fragile and, in practice, not landing.

What

Switch each tenant OCIRepository to native semver selection — the "deploy stable on production" pattern from the Flux OCI cheatsheet:

ref:
  semver: ">=1.0.0"   # was: tag: <pinned> # {"$imagepolicy": ...}

The cluster's per-app OCIRepository now polls the tenant registry directly and pulls the newest matching tag every interval (1m) — no Git commit, no image controllers, no platform release loop. Tenant apps update independently of the platform release cycle. Cosign verification (verify.matchOIDCIdentity) is unchanged.

Removed the now-unused machinery:

  • per-app ImageRepository + ImagePolicy (k8s/bases/apps/*/image-policy.yaml)
  • the image-automation/ overlay dir (GitRepository + ImageUpdateAutomation + ExternalSecret)
  • image-reflector-controller + image-automation-controller from the FluxInstance
  • the vault-seed GitHub App git key + PushSecret that fed git auth (incl. the now-orphaned git-key-secret.enc.yaml)

⚠️ This deletes one SOPS-encrypted file (vault-seed/git-key-secret.enc.yaml) — the obsolete GitHub App private key used only by the removed git automation. It is recoverable from history. Flagging since *.enc.yaml is a protected path.

The tenant app repos (wedding-app, ascoachingogvaner) need no changes — they already publish semver-tagged OCI manifest artifacts via the reusable publish-app.yaml workflow.

Validation

kustomize build succeeds for both overlays and all affected paths:

  • k8s/clusters/local/, k8s/clusters/prod/
  • k8s/providers/hetzner/apps, .../infrastructure, .../infrastructure/controllers
  • k8s/bases/apps/wedding-app, k8s/bases/apps/ascoachingogvaner

Rendered output confirms: no ImageRepository/ImagePolicy/ImageUpdateAutomation/automation GitRepository remain; both tenant OCIRepository resources use semver: ">=1.0.0"; the FluxInstance lists only the four core controllers.

Test plan

  • CI Talos + Docker system test passes (note: tenant apps are prod-only and excluded from the Docker overlay, so this exercises the cluster wiring/controllers, not the tenants themselves)
  • After merge + platform release, confirm in prod that OCIRepository/wedding-app and OCIRepository/ascoachingogvaner reconcile to the latest published tag and roll their apps

Generated by Claude Code

Tenant image automation never reached the cluster: the cluster reconciles
solely from the platform OCI artifact, so ImageUpdateAutomation tag bumps
committed to Git only landed after a full platform release republished the
artifact — coupling every tenant release to a platform redeploy.

Select the newest manifest tag directly in each tenant OCIRepository via
ref.semver (the cheatsheet's "deploy stable on production" pattern). The
cluster now pulls new tenant versions on its own interval, independent of
the platform release cycle. Cosign verification is unchanged.

Remove the now-unused machinery: per-app ImageRepository/ImagePolicy, the
image-automation GitRepository/ImageUpdateAutomation/ExternalSecret, the
image-reflector/image-automation controllers from the FluxInstance, and the
vault-seed GitHub App git key + PushSecret that fed git auth.
Copilot AI review requested due to automatic review settings May 26, 2026 22:41
@devantler devantler marked this pull request as ready for review May 26, 2026 22:42
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR decouples tenant app updates from the platform release cycle by switching tenant OCIRepository resources to Flux’s native semver-based tag selection, and removes the now-unneeded Git-based image automation stack (controllers, manifests, and Vault seeding materials).

Changes:

  • Switch wedding-app and ascoachingogvaner OCIRepository.spec.ref from pinned tag (set via $imagepolicy) to semver: ">=1.0.0".
  • Remove Git-based image automation resources (ImagePolicy/Repository, ImageUpdateAutomation, automation GitRepository + ExternalSecret) and stop installing Flux image automation controllers.
  • Remove the obsolete SOPS-encrypted GitHub App private key and its Vault seeding PushSecret from the Hetzner vault-seed overlay.

Reviewed changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated no comments.

Show a summary per file
File Description
k8s/providers/hetzner/infrastructure/vault-seed/seed-image-automation-git.yaml Removes PushSecret that seeded the image-automation GitHub App key into OpenBao.
k8s/providers/hetzner/infrastructure/vault-seed/kustomization.yaml Drops the deleted git key secret + PushSecret from vault-seed resources.
k8s/providers/hetzner/infrastructure/vault-seed/git-key-secret.enc.yaml Deletes the SOPS-encrypted GitHub App private key Secret that was only used for removed git automation.
k8s/providers/hetzner/infrastructure/controllers/flux-instance/flux-instance.yaml Removes image-reflector/image-automation controllers from the prod FluxInstance components list.
k8s/providers/hetzner/apps/kustomization.yaml Stops including the removed image-automation/ overlay.
k8s/providers/hetzner/apps/image-automation/kustomization.yaml Deletes the image-automation overlay kustomization.
k8s/providers/hetzner/apps/image-automation/image-update-automation.yaml Deletes ImageUpdateAutomation that previously committed tag bumps back to Git.
k8s/providers/hetzner/apps/image-automation/git-repository.yaml Deletes the GitRepository used solely by ImageUpdateAutomation.
k8s/providers/hetzner/apps/image-automation/external-secret.yaml Deletes ExternalSecret that generated the GitHub App auth Secret for git automation.
k8s/bases/apps/wedding-app/sync.yaml Switches OCIRepository.ref to semver selection for native updates.
k8s/bases/apps/wedding-app/kustomization.yaml Removes the app’s ImagePolicy/ImageRepository resource from the base.
k8s/bases/apps/wedding-app/image-policy.yaml Deletes the app’s ImageRepository + ImagePolicy resources.
k8s/bases/apps/ascoachingogvaner/sync.yaml Switches OCIRepository.ref to semver selection for native updates.
k8s/bases/apps/ascoachingogvaner/kustomization.yaml Removes the app’s ImagePolicy/ImageRepository resource from the base.
k8s/bases/apps/ascoachingogvaner/image-policy.yaml Deletes the app’s ImageRepository + ImagePolicy resources.

Resolve ascoachingogvaner OCIRepository conflict in favor of native semver
selection (this branch's approach) over the #1584 pinned tag bump to 1.1.0.
The #1584 CNPG-cleanup changes (networkpolicy + kustomization-patch) merge
cleanly and are kept.
@botantler botantler Bot enabled auto-merge May 26, 2026 23:41
@botantler botantler Bot added this pull request to the merge queue May 27, 2026
Merged via the queue into main with commit a51a6bb May 27, 2026
9 checks passed
@botantler botantler Bot deleted the claude/tenant-image-automation-jnY6v branch May 27, 2026 00:12
@github-project-automation github-project-automation Bot moved this from 🫴 Ready to ✅ Done in 🌊 Project Board May 27, 2026
@botantler
Copy link
Copy Markdown
Contributor

botantler Bot commented May 27, 2026

🎉 This PR is included in version 1.2.1 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

@botantler botantler Bot added the released label May 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

Status: ✅ Done

Development

Successfully merging this pull request may close these issues.

3 participants