fix: the crds Application never actually synced #50

Merged
ivuorinen merged 1 commit from fix/crds-app-sync-shape into main 2026-09-26 12:53:45 +00:00
Owner

Fixes the crds Application added in #49, which never actually ran.

What was wrong

Every resource in gitops/apps/crds/ was an ArgoCD hook. ArgoCD excludes hook
resources from its desired-vs-live comparison, so the Application had nothing to
compare — it reported Synced/Healthy within two minutes of merging and never
ran a sync operation at all.

Observed after #49 merged:

Check Result
status.resources empty
operationState absent — no sync ever ran
crd-installer namespace not created, despite CreateNamespace=true
Jobs none

Nothing broke. The three scripts still exist and the CRDs were already
installed, so the app was simply inert — which is exactly what #49 was designed
to be on its first run.

Why adding any normal resource is not enough

The same exclusion has a second consequence: a version changed inside a hook
manifest
never puts the Application OutOfSync, so the installer would not
re-run after a Renovate bump. The first sync would work and every subsequent
bump would silently do nothing. The change-trigger has to live in a normal
resource.

The fix

  • crd-versions ConfigMap (normal resource) holds the three chart versions.
    It is both the single source of truth and the thing that puts the app
    OutOfSync when a version changes.
  • RBAC becomes ordinary resources rather than hooks.
  • The Jobs become PostSync hooks reading their version through
    configMapKeyRef. PostSync because the ConfigMap and ServiceAccount must
    exist first — a PreSync hook needing them would deadlock, since normal
    resources never apply while PreSync is failing.

Sync-wave -5 still gates the dependent charts: the sync operation is not
complete until the PostSync hooks succeed, and an Application's health is the
child's.

This also removes the duplicate chart version that each Job carried in its
args — the version now appears in the ConfigMap and in the matching
Application's targetRevision, and nowhere else.

Guard

tests/gitops-sync-shape.bats encodes both halves of the bug:

  • no gitops/apps/ directory may consist entirely of hooks
  • the crds version source must stay a normal resource

Both were checked against mutations, including a faithful reconstruction of the
broken shape, which is rejected with
gitops/apps/crds/: all 7 resource(s) are ArgoCD hooks.

tests/version-sync.bats and tests/renovate-annotations.bats now read the pin
from the ConfigMap, and Renovate's custom manager accepts both NAME="x" in
shell and NAME: "x" in YAML.

Verification

32 bats tests and all 24 pre-commit hooks pass. The in-cluster behaviour cannot
be verified until this merges, for the same reason #49 could not be — which is
why the scripts stay until it is confirmed working.

Fixes the `crds` Application added in #49, which never actually ran. ## What was wrong Every resource in `gitops/apps/crds/` was an ArgoCD hook. ArgoCD excludes hook resources from its desired-vs-live comparison, so the Application had nothing to compare — it reported `Synced`/`Healthy` within two minutes of merging and never ran a sync operation at all. Observed after #49 merged: | Check | Result | |---|---| | `status.resources` | empty | | `operationState` | absent — no sync ever ran | | `crd-installer` namespace | not created, despite `CreateNamespace=true` | | Jobs | none | Nothing broke. The three scripts still exist and the CRDs were already installed, so the app was simply inert — which is exactly what #49 was designed to be on its first run. ## Why adding any normal resource is not enough The same exclusion has a second consequence: a version changed **inside a hook manifest** never puts the Application OutOfSync, so the installer would not re-run after a Renovate bump. The first sync would work and every subsequent bump would silently do nothing. The change-trigger has to live in a normal resource. ## The fix - **`crd-versions` ConfigMap** (normal resource) holds the three chart versions. It is both the single source of truth and the thing that puts the app OutOfSync when a version changes. - **RBAC becomes ordinary resources** rather than hooks. - **The Jobs become PostSync hooks** reading their version through `configMapKeyRef`. PostSync because the ConfigMap and ServiceAccount must exist first — a PreSync hook needing them would deadlock, since normal resources never apply while PreSync is failing. Sync-wave `-5` still gates the dependent charts: the sync operation is not complete until the PostSync hooks succeed, and an Application's health is the child's. This also removes the duplicate chart version that each Job carried in its `args` — the version now appears in the ConfigMap and in the matching Application's `targetRevision`, and nowhere else. ## Guard `tests/gitops-sync-shape.bats` encodes both halves of the bug: - no `gitops/apps/` directory may consist entirely of hooks - the `crds` version source must stay a normal resource Both were checked against mutations, including a faithful reconstruction of the broken shape, which is rejected with `gitops/apps/crds/: all 7 resource(s) are ArgoCD hooks`. `tests/version-sync.bats` and `tests/renovate-annotations.bats` now read the pin from the ConfigMap, and Renovate's custom manager accepts both `NAME="x"` in shell and `NAME: "x"` in YAML. ## Verification 32 bats tests and all 24 pre-commit hooks pass. The in-cluster behaviour cannot be verified until this merges, for the same reason #49 could not be — which is why the scripts stay until it is confirmed working.
fix: the crds Application never actually synced
All checks were successful
validate / render (pull_request) Successful in 49s
validate / hooks (pull_request) Successful in 1m15s
7881c5b9fc
Every resource in gitops/apps/crds/ was an ArgoCD hook. ArgoCD excludes
hook resources from its desired-vs-live comparison, so the Application had
nothing to compare: it reported Synced and Healthy within two minutes of
merging and never ran a sync operation at all. status.resources was empty,
operationState absent, the crd-installer namespace was never created
despite CreateNamespace=true, and no Job ever ran.

The same exclusion has a second consequence that rules out simply adding
any normal resource: a version changed inside a hook manifest never makes
the Application OutOfSync, so the installer would not re-run after a
Renovate bump. The trigger has to be a normal resource.

So the chart versions move into a crd-versions ConfigMap, which is both
the single place they live and the thing that puts the app OutOfSync when
one changes. RBAC becomes ordinary resources, and the Jobs become PostSync
hooks reading their version through configMapKeyRef — PostSync because the
ConfigMap and ServiceAccount must exist first, and a PreSync hook needing
them would deadlock. Wave -5 still gates: the sync is not complete until
the PostSync hooks succeed.

This also removes the duplicate version that the merged shape carried in
each Job's args.

tests/gitops-sync-shape.bats encodes both halves, and was checked against a
faithful reconstruction of the broken shape.
ivuorinen deleted branch fix/crds-app-sync-shape 2026-09-26 12:53:45 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
ivuorinen/turingpi-cluster!50
No description provided.