From 2f6c9e176e945dadc6d268ea5bed83183c82eba9 Mon Sep 17 00:00:00 2001 From: Jonathan Dieu Date: Wed, 8 Jul 2026 19:09:35 -0700 Subject: [PATCH 1/3] ci: cache kubeconform schemas instead of re-fetching every run -schema-location default isn't bundled/offline - it's a remote URL pattern (raw.githubusercontent.com/yannh/kubernetes-json-schema), fetched fresh per resource kind on every single CI run, no caching. That's dozens of requests per run against a shared, heavily-used GitHub Actions IP range, and it's been hitting HTTP 429 rate limits often enough to fail both the helm and argocd-validate jobs outright. kubeconform has a -cache flag built in for exactly this. Paired with actions/cache to persist the directory across runs, schemas only need to be fetched from the network once (per kubernetes-version), not on every PR. --- .github/workflows/ci.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4192594..976673e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -28,6 +28,18 @@ jobs: tar xz -C /tmp -f /tmp/kubeconform.tar.gz sudo mv /tmp/kubeconform /usr/local/bin/ + # -schema-location default isn't actually bundled/offline - it's a + # remote URL pattern (raw.githubusercontent.com/yannh/kubernetes-json-schema), + # fetched fresh per resource kind on every run with no caching. That's + # dozens of requests per CI run against a shared, heavily-used GitHub + # Actions IP range, which gets rate-limited (HTTP 429) often enough to + # be disruptive. -cache persists what's already been fetched. + - name: Cache kubeconform schemas + uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + with: + path: /tmp/kubeconform-cache + key: kubeconform-schemas-v1.36.0 + - name: Lint and validate charts run: | set -eo pipefail @@ -55,6 +67,7 @@ jobs: -kubernetes-version 1.36.0 \ -schema-location default \ -schema-location 'https://raw.githubusercontent.com/datreeio/CRDs-catalog/main/{{.Group}}/{{.ResourceKind}}_{{.ResourceAPIVersion}}.json' \ + -cache /tmp/kubeconform-cache \ -skip CustomResourceDefinition \ -summary done @@ -77,6 +90,12 @@ jobs: tar xz -C /tmp -f /tmp/kubeconform.tar.gz sudo mv /tmp/kubeconform /usr/local/bin/ + - name: Cache kubeconform schemas + uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + with: + path: /tmp/kubeconform-cache + key: kubeconform-schemas-v1.36.0 + - name: Validate ArgoCD manifests run: | find argocd -name '*.yaml' -print0 \ @@ -84,6 +103,7 @@ jobs: -kubernetes-version 1.36.0 \ -schema-location default \ -schema-location 'https://raw.githubusercontent.com/datreeio/CRDs-catalog/main/{{.Group}}/{{.ResourceKind}}_{{.ResourceAPIVersion}}.json' \ + -cache /tmp/kubeconform-cache \ -skip CustomResourceDefinition \ -summary From 3316645bda2b4eb817c677eef639bea07152741a Mon Sep 17 00:00:00 2001 From: Jonathan Dieu Date: Wed, 8 Jul 2026 19:11:16 -0700 Subject: [PATCH 2/3] fix(ci): create the kubeconform cache dir before use, not just on cache hit actions/cache only creates the restored directory on a hit. On the first run for a given key it's a miss, so the dir never exists and -cache fails immediately with 'no such file or directory'. --- .github/workflows/ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 976673e..10137f7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -43,6 +43,7 @@ jobs: - name: Lint and validate charts run: | set -eo pipefail + mkdir -p /tmp/kubeconform-cache for chart in charts/*/*; do [ -f "$chart/Chart.yaml" ] || continue echo "--- $chart ---" @@ -98,6 +99,7 @@ jobs: - name: Validate ArgoCD manifests run: | + mkdir -p /tmp/kubeconform-cache find argocd -name '*.yaml' -print0 \ | xargs -0 -r kubeconform -strict \ -kubernetes-version 1.36.0 \ From dea1b02802e8aeefa48de534fbca4ad658bc0ad4 Mon Sep 17 00:00:00 2001 From: Jonathan Dieu Date: Wed, 8 Jul 2026 19:18:43 -0700 Subject: [PATCH 3/3] fix(ci): rotate the kubeconform cache key instead of fixing it actions/cache caches are immutable per key - the fixed key only ever captured whatever schemas the first run needed, so any resource kind added later would hit the network on every run forever without ever getting persisted, contradicting the whole point of caching them. A per-run key (github.run_id) plus a restore-keys prefix lets each run start from the most recent cache and save its own snapshot forward, so the cache can actually grow as new resource kinds show up. --- .github/workflows/ci.yml | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 10137f7..1225fc5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -38,7 +38,15 @@ jobs: uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: path: /tmp/kubeconform-cache - key: kubeconform-schemas-v1.36.0 + # actions/cache is immutable per key - a fixed key would only ever + # capture whatever schemas the first run happened to need, and any + # later-added resource kind would hit the network forever without + # ever getting persisted. A per-run key plus a restore-keys prefix + # lets each run start from the most recent cache and save its own + # (possibly larger) snapshot forward. + key: kubeconform-schemas-v1.36.0-${{ github.run_id }} + restore-keys: | + kubeconform-schemas-v1.36.0- - name: Lint and validate charts run: | @@ -95,7 +103,15 @@ jobs: uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: path: /tmp/kubeconform-cache - key: kubeconform-schemas-v1.36.0 + # actions/cache is immutable per key - a fixed key would only ever + # capture whatever schemas the first run happened to need, and any + # later-added resource kind would hit the network forever without + # ever getting persisted. A per-run key plus a restore-keys prefix + # lets each run start from the most recent cache and save its own + # (possibly larger) snapshot forward. + key: kubeconform-schemas-v1.36.0-${{ github.run_id }} + restore-keys: | + kubeconform-schemas-v1.36.0- - name: Validate ArgoCD manifests run: |