#!/usr/bin/env bash set -euo pipefail # Normalise staged manifests to their kubectl kustomize output, so what is # committed is exactly what Argo CD renders. Requires kubectl and yq. identity='[.apiVersion, .kind, .metadata.name // ""] | join("|")' git diff --cached --name-only --diff-filter=ACM -- '*.yaml' | while IFS= read -r file; do dir=$(dirname "$file") name=$(basename "$file") [ "$name" = kustomization.yaml ] && continue # only normalise files the sibling kustomization lists as a resource, so # patches and components are never replaced with build output yq -r '.resources[]? // ""' "$dir/kustomization.yaml" 2>/dev/null | grep -Fxq "$name" || continue rendered=$(mktemp) kubectl kustomize "$dir" | yq eval-all "select(($identity) == \"$(yq eval-all "$identity" "$file" | head -1)\")" - >"$rendered" if [ -s "$rendered" ] && ! diff -q "$file" "$rendered" >/dev/null; then cat "$rendered" >"$file" git add "$file" echo "normalised $file" fi rm -f "$rendered" # normalising may have reverted the change entirely if git diff --cached --quiet -- "$file"; then git reset -q HEAD -- "$file" fi done # nothing left staged — prevent an empty commit if git diff --cached --quiet; then echo "pre-commit: no meaningful changes, aborting commit" exit 1 fi