name: Validate Kubernetes Manifests on: pull_request: branches: [main] push: branches: [main] jobs: kubeconform: runs-on: ubuntu-latest container: image: ghcr.io/yannh/kubeconform:v0.7.0-alpine steps: - name: Install dependencies run: | apk add --no-cache \ yq \ findutils \ curl \ jq \ npm \ nodejs \ bash \ git - name: Checkout code uses: actions/checkout@v6 with: fetch-depth: 0 - name: Get changed files id: changed-files uses: tj-actions/changed-files@v47 with: files: | **.yml !.gitea/workflows/** - name: Validate Manifests if: steps.changed-files.outputs.any_changed == 'true' env: ALL_CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }} shell: bash run: | set -o pipefail declare -A SCHEMA_MAP=( ["HelmRelease"]="helm.toolkit.fluxcd.io/helmrelease_v2.json" ["HelmRepository"]="source.toolkit.fluxcd.io/helmrepository_v1.json" ["L2Advertisement"]="metallb.io/l2advertisement_v1beta1.json" ["IPAddressPool"]="metallb.io/ipaddresspool_v1beta1.json" ["SealedSecret"]="bitnami.com/sealedsecret_v1alpha1.json" ["ClusterPolicy"]="nvidia.com/clusterpolicy_v1.json" ["Plan"]="upgrade.cattle.io/plan_v1.json" ) EXIT_CODE=0 export KUBECONFORM_CACHE_DIR="/tmp/kubeconform-cache" mkdir -p "$KUBECONFORM_CACHE_DIR" while IFS= read -r file; do [ -z "$file" ] && continue echo "=== Validating: $file ===" KIND=$(yq -r '.kind // ""' "$file" 2>/dev/null || echo "") if [[ -n "$KIND" && -n "${SCHEMA_MAP[$KIND]}" ]]; then echo "Found $KIND - using custom schema" SCHEMA_URL="https://raw.githubusercontent.com/datreeio/CRDs-catalog/refs/heads/main/${SCHEMA_MAP[$KIND]}" if ! /kubeconform \ -schema-location "$SCHEMA_URL" \ -cache "$KUBECONFORM_CACHE_DIR" \ -output json \ "$file"; then EXIT_CODE=1 fi else echo "Validating with default schemas" if ! /kubeconform \ -schema-location default \ -cache "$KUBECONFORM_CACHE_DIR" \ -output json \ "$file"; then EXIT_CODE=1 fi fi echo "" done <<< "${ALL_CHANGED_FILES[@]}" exit $EXIT_CODE