Files
gitops/.githooks/pre-commit
T

42 lines
1.3 KiB
Bash
Executable File

#!/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