Skip to content

fix: 28 ApplicationSets pinned main while app-of-apps tracked the revision - #201

Merged
stxkxs merged 1 commit into
mainfrom
feat/catalog-revision-is-load-bearing
Aug 9, 2026
Merged

fix: 28 ApplicationSets pinned main while app-of-apps tracked the revision#201
stxkxs merged 1 commit into
mainfrom
feat/catalog-revision-is-load-bearing

Conversation

@stxkxs

@stxkxs stxkxs commented Aug 9, 2026

Copy link
Copy Markdown
Member

cluster-bootstrap stamps two sibling annotations on every ArgoCD cluster Secret, gitops/repo-url and gitops/repo-branch, and the comment above them says appsets template their own source off these so no org is hardcoded in the manifests. That is true of repo-url — 33 files read it. repo-branch had exactly one reference in the whole org: the line that writes it.

Meanwhile 28 applied ApplicationSets carried targetRevision: main as a literal, directly beneath a repoURL templated off the annotation.

So a cluster bootstrapped against any other revision ran app-of-apps at that revision — the Application does honour var.gitops_repo_branch — and every child Application at main. Both report Synced and Healthy. ArgoCD is telling the truth about each Application individually, and the cluster is running two revisions of the catalog at once with nothing anywhere to say so.

Two things that makes impossible:

  • Testing a catalog change on a branch. The cluster syncs main's values while app-of-apps displays the branch name — which is exactly the evidence someone would check.
  • Pinning a release. A platform installed from a tag gets a tagged app-of-apps over an unpinned fleet, so "deploy the known-good version" deploys HEAD.

Closes #238 by taking its option 1: make the annotation load-bearing.

Scope

Every catalog source now reads the annotation. Chart sources are untouched and must be — their repoURL is a Helm or OCI registry and their targetRevision is a chart version, a different thing that happens to share a field name.

The render fixtures gain the annotation, and that is load-bearing rather than housekeeping: the appsets run with goTemplateOptions: missingkey=error, so a cluster Secret without it now fails the render instead of silently defaulting to something.

The gate

scripts/check-catalog-revision.py parses each applied ApplicationSet, finds the sources whose repoURL resolves from gitops/repo-url, and asserts their targetRevision resolves from gitops/repo-branch.

It also fails when it finds zero catalog sources. Every addon gets its values files through one, so none means the parse broke rather than the repo being clean — a gate that finds nothing to check has stopped checking.

ok: all 25 catalog source(s) read their revision from gitops/repo-branch

Paired with rackctl, which is gaining a versions: block: pinning the catalog locally is inert while the fleet syncs main regardless.

@github-actions

github-actions Bot commented Aug 9, 2026

Copy link
Copy Markdown

CI Results

Check Status
Zero-placeholder gate ✅ success
YAML Lint ✅ success
Dashboard gate (live grafana.com ids + AMG-saveable) ✅ success
Kyverno policy tests (+ verify-images contract) ✅ success
Fork-safety gate (no hardcoded org, blocking) ✅ success
Helm-render (every addon × every env) ✅ success
Policy-admission (Enforce-tier Kyverno vs the fleet) ✅ success
ApplicationSet schema + sync waves ✅ success
Appset render (Karpenter subnet selector) ✅ success
Secret scan (gitleaks) ✅ success
Render + assert + schema + misconfig (all environments) ✅ success

All checks passed.

…ision

`cluster-bootstrap` stamps two sibling annotations on every ArgoCD cluster
Secret, `gitops/repo-url` and `gitops/repo-branch`, and the comment above them
says appsets template their own source off these so no org is hardcoded in the
manifests. That was true of repo-url — 33 files read it. repo-branch had exactly
one reference in the whole org: the line that writes it.

Meanwhile 28 applied ApplicationSets carried `targetRevision: main` as a
literal, directly beneath a repoURL templated off the annotation.

So a cluster bootstrapped against any other revision ran app-of-apps at that
revision — the Application does honour var.gitops_repo_branch — and every child
Application at main. Both report Synced and Healthy: ArgoCD is telling the truth
about each Application individually, and the cluster is running two revisions of
the catalog at once with nothing anywhere to say so.

Two things that makes impossible. Testing a catalog change on a branch: the
cluster syncs main's values while app-of-apps displays the branch name, which is
exactly the evidence someone would check. And pinning a release: a platform
installed from a tag gets a tagged app-of-apps over an unpinned fleet, so
"deploy the known-good version" deploys HEAD.

Every catalog source now reads the annotation. Chart sources are untouched and
must be — their repoURL is a Helm or OCI registry and their targetRevision is a
chart version, a different thing sharing a field name.

The render fixtures gain the annotation, which is load-bearing rather than
housekeeping: the appsets run with goTemplateOptions missingkey=error, so a
cluster Secret without it now fails the render instead of silently defaulting.

`scripts/check-catalog-revision.py` holds it. It parses each applied
ApplicationSet, finds the sources whose repoURL resolves from gitops/repo-url,
and asserts their targetRevision resolves from gitops/repo-branch. It also fails
when it finds ZERO catalog sources — every addon gets its values files through
one, so none means the parse broke rather than the repo being clean.
@stxkxs
stxkxs force-pushed the feat/catalog-revision-is-load-bearing branch from f4a8375 to 122edf4 Compare August 9, 2026 18:06
@github-actions

github-actions Bot commented Aug 9, 2026

Copy link
Copy Markdown

CI Results

Check Status
Zero-placeholder gate ✅ success
YAML Lint ✅ success
Dashboard gate (live grafana.com ids + AMG-saveable) ✅ success
Kyverno policy tests (+ verify-images contract) ✅ success
Fork-safety gate (no hardcoded org, blocking) ✅ success
Helm-render (every addon × every env) ✅ success
Policy-admission (Enforce-tier Kyverno vs the fleet) ✅ success
ApplicationSet schema + sync waves ✅ success
Appset render (Karpenter subnet selector) ✅ success
Secret scan (gitleaks) ✅ success
Render + assert + schema + misconfig (all environments) ✅ success

All checks passed.

@stxkxs
stxkxs merged commit c1b8753 into main Aug 9, 2026
23 checks passed
@stxkxs
stxkxs deleted the feat/catalog-revision-is-load-bearing branch August 9, 2026 21:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant