Hive Hive
Sign in

feat(linux-runner-image): pre-install kubectl and helm

GitHub issue · Closed

Metadata
Source
tuist/tuist #10908
Updated
Jun 24, 2026
Domains
Compute
Details

What

Bake kubectl and helm into the tuist-linux-runner OCI image at /usr/local/bin via two new Renovate-managed ARGs in infra/linux-runner-image/Dockerfile:

# renovate: datasource=github-releases depName=kubernetes/kubernetes
ARG KUBECTL_VERSION=1.36.1
# renovate: datasource=github-releases depName=helm/helm
ARG HELM_VERSION=4.2.0

The existing custom regex manager in renovate.json is generalized from RUNNER_VERSION to any ARG <UPPER_SNAKE>_VERSION=… in this one file, and the matching package rule is extended to cover kubernetes/kubernetes + helm/helm (same fix(linux-runner-image): commit prefix + automerge as actions/runner).

Why

GitHub-hosted Ubuntu runners pre-install both binaries via the upstream install-kubernetes-tools.sh build script. Namespace’s namespace-profile-default mirrors that. Our in-house tuist-production-linux image, introduced in #10886, omitted both.

That parity gap was the underlying cause of the mgmt-cluster-apply failure the day after the runner migration: mise install kubectl (no version pin) creates an unactivated shim that shadows the system binary, but on hosted runners the system fallback at /usr/local/bin/kubectl was masking the bug. Drop the fallback and the shim error surfaces.

Relationship to #10907

#10907 fixes the mise-action invocations themselves (install: false + mise use -g <tool> so the shim has a real version source). That PR is the load-bearing fix that unblocks mgmt-cluster-apply right now.

This PR is the defensive complement: even with the workflow fix in place, future deploy steps written against the runner image will continue to assume kubectl + helm exist on PATH (because that’s what GitHub-hosted does). Closing the parity gap means the next slim-image consumer doesn’t rediscover this footgun.

Order is independent — either PR can land first.

Validation

  • .github/workflows/linux-runner-image.yml (PR trigger) builds the image without pushing — green = Dockerfile + curl URLs resolve.
  • After merge: release-linux-runner-image job in release.yml runs on main, builds + pushes a new semver tag, and rewrites runnersFleetLinux.pools[*].runnerImage in managed-env values files where the pin is currently non-empty. Once the helm chart redeploys (next runners-controller reconcile), new runner Pods come up with the binaries baked in.
  • Renovate next sees the two new ARGs and starts opening fix(linux-runner-image): update <kubectl|helm> PRs on upstream releases (one-time validation: confirm a PR opens within the next renovation cycle).

Notes

  • Versions chosen to match current upstream stable: kubectl v1.36.1 (https://dl.k8s.io/release/stable.txt) and helm v4.2.0 (latest GitHub release).
  • helm is the v4 line. Our infra/mise.toml already pins helm = "4.1.3" for local development, so this is consistent.
  • dpkg --print-architecture is used to pick the right binary URL so the same Dockerfile will work when we add linux/arm64 to the buildx platforms: list (currently amd64-only per the workflow comment).
Comments

No GitHub comments yet.