Skip to content

validate: manifest-driven mode to validate a whole environment#126

Merged
orian merged 1 commit into
mainfrom
feat/validate-manifest-driven
Jul 8, 2026
Merged

validate: manifest-driven mode to validate a whole environment#126
orian merged 1 commit into
mainfrom
feat/validate-manifest-driven

Conversation

@orian

@orian orian commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator

Follow-up to #125. validate -manifest validated one node (passed via -layer/-config), using the manifest only as cross-cluster context — checking a whole environment meant a shell loop over nodes. This makes "validate the whole manifest" a first-class command.

Behavior

hclexp validate -manifest roles.hcl -env prod-us -layer-root .
# validation error: [role data] posthog.broken: view source table references "posthog.nonexistent", ...

With -manifest/-env and no -layer/-config, validate:

  • loads and resolves every role's composition for -env,
  • builds the cluster set from the whole manifest (member-role unions + aliases, -cluster flags last),
  • runs the full validation (dependencies, MV/view sources, Distributed proxy columns) on each role against that cluster set,
  • prefixes errors with the role ([role data] …) and exits non-zero if any role fails.

Mode is selected only when neither -layer nor an explicit -config is given (detected via flag.FlagSet.Visit). With -layer/-config, the existing single-node behavior (manifest as context) is unchanged — verified by regression.

Implementation

Shared helpers so both modes load role schemas once:

  • loadManifestRoleSchemas — role → resolved *Schema
  • clusterSetFromRoles — union member-role databases per cluster + aliases (reused by the single-node buildManifestClusters, which loads only cluster-referenced roles)
  • validateManifest(...) []roleValidation — returns per-role errors, unit-tested without os.Exit
  • runValidateManifest — printing + exit code; flagWasSet — explicit--config detection

Tests

  • validateManifest: every role validated; a clean role passes while a role with a broken reference reports it and its cross-cluster proxy still resolves; all-clean manifest → zero errors.
  • Binary end-to-end: one command flags [role data] for a broken view, then passes for the whole env once fixed.
  • Single-node mode regression: validate -layer … unchanged.

Full suite green; go vet + gofmt clean. Notes in docs/plans/2026-07-08-validate-manifest-driven.md.

`validate -manifest` validated one node (passed via -layer/-config) using the
manifest as cross-cluster context; checking a whole env meant looping validate
per node in a shell.

Add a manifest-driven mode: with -manifest/-env and no -layer/-config, validate
loads every role's composition for the env, builds the cluster set from the
whole manifest (member-role unions + aliases + any -cluster flags), and runs the
full validation on each role against it. Per-role errors are prefixed
"[role X]"; it exits non-zero if any role fails. Mode is selected when neither
-layer nor an explicit -config is given (detected via flag.Visit); the
single-node path is unchanged.

Factor shared helpers (loadManifestRoleSchemas, clusterSetFromRoles) so both
modes load role schemas once; validateManifest returns per-role results and is
unit-tested without os.Exit.
@orian orian enabled auto-merge (squash) July 8, 2026 12:39
@orian orian merged commit 4b49a65 into main Jul 8, 2026
17 checks passed
@orian orian deleted the feat/validate-manifest-driven branch July 8, 2026 12:41
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