name: Validate manifests on: push: pull_request: jobs: validate: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Install tools run: | curl -sL https://github.com/yannh/kubeconform/releases/latest/download/kubeconform-linux-amd64.tar.gz \ | tar xz -C /usr/local/bin curl -fsSL https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash curl -fsSL https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 \ -o /usr/local/bin/yq chmod +x /usr/local/bin/yq # Traefik IngressRoute is a CRD, so kubeconform needs an extra schema source. mkdir -p .ci-schemas/traefik.io curl -fsSL https://raw.githubusercontent.com/datreeio/CRDs-catalog/main/traefik.io/ingressroute_v1alpha1.json \ -o .ci-schemas/traefik.io/ingressroute_v1alpha1.json cp .ci-schemas/traefik.io/ingressroute_v1alpha1.json .ci-schemas/traefik.io/IngressRoute_v1alpha1.json cp .ci-schemas/traefik.io/ingressroute_v1alpha1.json .ci-schemas/traefik.io/IngressRoute.json cp .ci-schemas/traefik.io/ingressroute_v1alpha1.json .ci-schemas/traefik.io/ingressroute.json # ArgoCD ApplicationSet is also a CRD. It stays dormant until bootstrap # is enabled, but once enabled we validate it with an explicit schema. mkdir -p .ci-schemas/argoproj.io curl -fsSL https://raw.githubusercontent.com/datreeio/CRDs-catalog/main/argoproj.io/applicationset_v1alpha1.json \ -o .ci-schemas/argoproj.io/applicationset_v1alpha1.json cp .ci-schemas/argoproj.io/applicationset_v1alpha1.json .ci-schemas/argoproj.io/ApplicationSet_v1alpha1.json cp .ci-schemas/argoproj.io/applicationset_v1alpha1.json .ci-schemas/argoproj.io/ApplicationSet.json cp .ci-schemas/argoproj.io/applicationset_v1alpha1.json .ci-schemas/argoproj.io/applicationset.json - name: Helm lint run: | found=0 for parent in helm custom-charts; do [ -d "$parent" ] || continue for chart in "$parent"/*; do [ -d "$chart" ] || continue found=1 echo "Linting $chart" helm lint "$chart" done done if [ "$found" -eq 0 ]; then echo "No Helm charts found" fi - name: kubeconform - raw YAML run: | bootstrap_enabled=false if [ -f bootstrap/config.yaml ] && grep -Eq '^[[:space:]]*enabled:[[:space:]]*true[[:space:]]*$' bootstrap/config.yaml; then bootstrap_enabled=true fi mapfile -t manifests < <( find . -type f -name '*.yaml' \ ! -path './.gitea/*' \ ! -name '*.enc.yaml' \ ! -name '*.secret.yaml' \ ! -name '*kustomization.yaml' \ ! -path './bootstrap/config.yaml' \ ! -path './bootstrap/repo.yaml' \ | sort ) if [ "$bootstrap_enabled" != "true" ]; then filtered=() for manifest in "${manifests[@]}"; do [ "$manifest" = "./bootstrap/applicationset.yaml" ] && continue filtered+=("$manifest") done manifests=("${filtered[@]}") fi if [ "${#manifests[@]}" -eq 0 ]; then echo "No manifests found" exit 0 fi printf '%s\n' "${manifests[@]}" \ | xargs kubeconform \ -strict \ -kubernetes-version 1.35.0 \ -ignore-missing-schemas \ -schema-location default \ -schema-location '.ci-schemas/{{.Group}}/{{.ResourceKind}}{{.KindSuffix}}.json' \ -schema-location '.ci-schemas/{{.Group}}/{{.ResourceKind}}_{{.ResourceAPIVersion}}.json' \ -summary - name: Apply bootstrap ApplicationSet env: KUBECONFIG_B64: ${{ secrets.KUBECONFIG_B64 }} run: | if [ "${GITHUB_EVENT_NAME:-}" != "push" ] || [ "${GITHUB_REF:-}" != "refs/heads/main" ]; then echo "Skipping bootstrap apply: only push events on main may apply" exit 0 fi if [ ! -f bootstrap/config.yaml ] || ! grep -Eq '^[[:space:]]*enabled:[[:space:]]*true[[:space:]]*$' bootstrap/config.yaml; then echo "Skipping bootstrap apply: bootstrap/config.yaml is not enabled" exit 0 fi if [ -z "${KUBECONFIG_B64:-}" ]; then echo "KUBECONFIG_B64 secret is required to apply bootstrap/applicationset.yaml" exit 1 fi curl -fsSL https://dl.k8s.io/release/$(curl -fsSL https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl \ -o /usr/local/bin/kubectl chmod +x /usr/local/bin/kubectl mkdir -p "${HOME}/.kube" printf '%s' "$KUBECONFIG_B64" | base64 -d > "${HOME}/.kube/config" if [ "${GITHUB_EVENT_NAME:-}" == "push" ] || [ "${GITHUB_REF:-}" == "refs/heads/main" ]; then for _ov in manifest/overlays/*; do kubectl kustomize $_ov >/dev/null || exit 1 done fi kubectl apply -f bootstrap/applicationset.yaml