--- name: kubelb-dependency-updates description: Sweep and update every dependency surface in the kubelb repo (go.mod, Makefile tool versions, prow images, GitHub Actions, hack/ci pins, addon Helm charts, pinned container images) and split the work into PRs. Use when asked to update or bump dependencies, tooling, chart versions, addon versions, or image pins in kubelb/kubelb-ce/kubelb-ee. --- # KubeLB Dependency Updates ## The two things that go wrong 1. **A surface gets missed.** Dependabot covers less than it looks like. Work the inventory below, do not assume. 2. **A bump silently no-ops or silently gets lost.** Verify by reading the resulting tree, never by trusting a "merged" badge or a clean `make` run. ## Scan for CVEs first Vulnerabilities decide what to bump and in what order. Run the scanners **before** touching any version, and land security-driven bumps as their own PR ahead of routine ones — a CVE fix should be reviewable and backportable without a pile of cosmetic bumps around it. Discover what this repo already runs rather than assuming; see [REFERENCE.md](REFERENCE.md#discovering-a-repos-security-posture) for the discovery commands. Reuse its pinned scanner versions and thresholds so local results match CI. For kubelb today that is: ```bash go install golang.org/x/vuln/cmd/govulncheck@v1.7.0 govulncheck ./... && (cd cli && govulncheck ./...) make build build-cli docker build -t kubelb-manager:scan -f kubelb.goreleaser.dockerfile . trivy image --severity HIGH,CRITICAL --ignore-unfixed kubelb-manager:scan trivy rootfs --severity HIGH,CRITICAL --ignore-unfixed cli/bin/kubelb ``` Then triage: a finding that a bump fixes drives that bump. A finding with no fixed version, or in a package the binaries never import, gets suppressed **with a reason** rather than chased — see [REFERENCE.md](REFERENCE.md#suppressing-a-finding). ## Inventory Run every row. `auto` = dependabot proposes it weekly; still confirm it is current. | Surface | Where | Auto? | |---|---|---| | Go modules (root + cli) | `go.mod`, `cli/go.mod` | direct only | | Makefile tools | `CONTROLLER_TOOLS_VERSION`, `CHAINSAW_VERSION`, `KUSTOMIZE_VERSION`, `HELM_DOCS_VERSION`, `CRD_REF_DOCS_VERSION`, `SETUP_ENVTEST_VERSION`, `GO_VERSION`, `GATEWAY_API_VERSION` | no | | CI tool pins | `hack/ci/verify.sh` (helm, yq, shfmt, gimps, boilerplate, wwhrd) | no | | Prow images | `.prow/verify.yaml`, `.prow/postsubmits.yaml` | **no** | | Action SHAs | `.github/workflows/*.yml` `uses:` | yes | | Action version *inputs* | same files, `with: version:` | **no** | | Addon charts | `charts/kubelb-addons/Chart.yaml` + `Chart.lock` | yes, except agentgateway | | agentgateway / -crds | same | **no** (ignored, see `dependabot.yml`) | | Envoy dataplane pins | `internal/controllers/kubelb/loadbalancer_controller.go`, `charts/kubelb-addons/templates/gateway-class.yaml`, `hack/e2e/images*.yaml` | no | | Base images | `*.dockerfile` | yes | | Kind node | `hack/e2e/setup-kind.sh`, `.prow/verify.yaml` | no | Go deps: direct deps are usually already current. Use `go get -u ./...` in **both** modules to catch indirect ones. Drop the `k8c.io/kubelb` bump it makes in `cli/go.mod` — inert (`replace` points at `../`) and pure noise. ## PR grouping Split on **user-facing vs internal**, not one-PR-per-bump. - **Security fixes → first, on their own.** Anything closing a CVE goes ahead of routine bumps so it can be reviewed and backported cleanly. - **User-facing → its own PR, one per concern.** Addon charts (they deploy into tenant clusters), the managed envoy dataplane image, anything with a real `release-note`, CRD/API changes. Each needs its own e2e signal and its own revert story. - **Internal → bundle freely into one PR.** Makefile tools, prow images, action SHAs, `hack/ci` pins, go.mod. Nobody downstream sees these. Keep addon-chart bumps that carry CRD changes (envoy-gateway, agentgateway, metallb minors) separate from each other so a red e2e run stays bisectable. **Avoid stacked PRs.** See [REFERENCE.md](REFERENCE.md#stacked-prs-lose-commits) — `kubermatic-bot` deletes branches on merge, which auto-closes dependent PRs and can silently drop a merged commit. Prefer one flat PR against `main`. ## Verification gate ```bash make lint && make test && make build make verify-helm-lock verify-addons-patches helm-lint # any chart change make lint-cli test-cli # any go.mod change ``` Chart changes: commit `Chart.lock` before running `verify-helm-lock` — it compares via `git diff` against HEAD, so an uncommitted lock always reports out-of-sync. Before bumping the prow `golangci-lint` image, run `make lint` **and** `make lint-cli` with that exact version locally. A newer linter surfaces new findings and turns the `pull-kubelb-lint-cli` job red. ## Pitfalls Read [REFERENCE.md](REFERENCE.md) before starting. The ones that have actually bitten: silent no-op tool installs, version skew between go.mod and the Makefile/chart pins, chart minors that delete what a `hack/patches/*.patch` targets, and stacked PRs losing commits.