diff --git a/.gitea/workflows/kubeconform.yml b/.gitea/workflows/kubeconform.yml new file mode 100644 index 0000000..2225880 --- /dev/null +++ b/.gitea/workflows/kubeconform.yml @@ -0,0 +1,80 @@ +name: Validate Kubernetes Manifests + +on: + pull_request: + branches: [main] + +jobs: + kubeconform: + runs-on: ubuntu-latest + container: + image: docker.io/archlinux/archlinux:latest + steps: + - name: Setup environment + run: | + pacman -Syu --noconfirm kubeconform git yq nodejs npm + + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Create kubeconform configuration + run: | + cat > /tmp/kubeconform-config.yaml << 'EOF' + schema_location: + - default + - "https://raw.githubusercontent.com/datreeio/CRDs-catalog/refs/heads/main/{{ .ResourceKind }}_{{ .ResourceAPIVersion }}.json" + EOF + + - name: Validate Manifests + run: | + # Create a cache directory for schemas + mkdir -p /tmp/kubeconform-cache + + # Validate manifests with proper schema resolution + find . -type f \( -name "*.yml" \) \ + -not -path "./.gitea/*" \ + -not -path "./clusters/default/system-upgrade/*" \ + -exec sh -c ' + for file do + echo "=== Validating: $file ===" + if yq -e "select(.kind == \"HelmRelease\")" "$file" >/dev/null 2>&1; then + echo "Found HelmRelease - using fluxcd schema" + kubeconform \ + -schema-location "https://raw.githubusercontent.com/datreeio/CRDs-catalog/refs/heads/main/helm.toolkit.fluxcd.io/helmrelease_v2.json" \ + -output json \ + "$file" + elif yq -e "select(.kind == \"HelmRepository\")" "$file" >/dev/null 2>&1; then + echo "Found HelmRepository - using fluxcd schema" + kubeconform \ + -schema-location "https://raw.githubusercontent.com/datreeio/CRDs-catalog/refs/heads/main/source.toolkit.fluxcd.io/helmrepository_v1.json" \ + -output json \ + "$file" + elif yq -e "select(.kind == \"L2Advertisement\")" "$file" >/dev/null 2>&1; then + echo "Found L2Advertisement - using metallb schema" + kubeconform \ + -schema-location "https://raw.githubusercontent.com/datreeio/CRDs-catalog/refs/heads/main/metallb.io/l2advertisement_v1beta1.json" \ + -output json \ + "$file" + elif yq -e "select(.kind == \"IPAddressPool\")" "$file" >/dev/null 2>&1; then + echo "Found IPAddressPool - using metallb schema" + kubeconform \ + -schema-location "https://raw.githubusercontent.com/datreeio/CRDs-catalog/refs/heads/main/metallb.io/ipaddresspool_v1beta1.json" \ + -output json \ + "$file" + elif yq -e "select(.kind == \"SealedSecret\")" "$file" >/dev/null 2>&1; then + echo "Found SealedSecret - using bitnami schema" + kubeconform \ + -schema-location "https://raw.githubusercontent.com/datreeio/CRDs-catalog/refs/heads/main/bitnami.com/sealedsecret_v1alpha1.json" \ + -output json \ + "$file" + else + echo "Validating with default schemas" + kubeconform \ + -schema-location default \ + -output json \ + "$file" + fi + done + ' sh {} +