Skip to content

fix(installer): pin k3d + helm versions — drop api.github.com latest lookups - #438

Merged
LukasWodka merged 3 commits into
fix/409-unc-job-cwdfrom
fix/410-pin-k3d-helm
Jul 27, 2026
Merged

fix(installer): pin k3d + helm versions — drop api.github.com latest lookups#438
LukasWodka merged 3 commits into
fix/409-unc-job-cwdfrom
fix/410-pin-k3d-helm

Conversation

@LukasWodka

@LukasWodka LukasWodka commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Summary

Ports #382's determinism to Windows: install-k8s.ps1 no longer resolves k3d/helm via the unauthenticated api.github.com releases/latest endpoint (60 req/hour per IP — a single shared corporate NAT exhausts it; observed failing live on a customer install, 2026-07-27, right after an all-green preflight).

Change

  • $K3dVersion (default v5.9.0) and $HelmVersion (default v4.2.3) — env-overridable, lockstep with scripts/lib/common.sh until the shared facts spec (feat(installer): single-source installer facts (versions, hosts, timeouts, floors) + CI behavior-parity gate (RFC-CLIENT-0003 D3/D4) #435) single-sources them.
  • Test-ReleaseTagShape — release-shape + path-traversal gate before any tag reaches a download URL (mirrors the bootstrap ref gate / cli validate_version_tag).
  • latest remains supported but API-free: /releases/latest redirect Location header for k3d (the cli install.ps1 trick), get.helm.sh/helm-latest-version for helm — exact lib/setup-linux.sh parity.
  • Pester: pin defaults, shape gate, resolver behavior (pinned = no network, latest = resolver, fail-closed on unresolvable/bad shape), plus a regression gate that fails if any https://api.github.com fetch reappears.
  • manifest.sha256 regenerated.

Not in scope: the winget branch still installs whatever version winget carries (tracked under #419/#435); checksum verification is unchanged (k3d already fail-closed).

Stacked on #437 — merge that first; this branch contains it.

Type

Bug fix

Test plan

Full Pester suite locally on pwsh 7.5 (CI invocation): 165 passed, 0 failed, 8 skipped (10 new). gen-manifest.sh --check clean.

🤖 Generated with Claude Code


Note

Low Risk
Installer-only change to version resolution for optional direct binary downloads; winget path unchanged. Well-covered by new tests; main risk is stale pins until env override or latest.

Overview
Windows installer no longer resolves k3d or Helm via api.github.com releases/latest on the direct-download path. Default installs use pinned K3D_VERSION / HELM_VERSION (v5.9.0 / v4.2.3, env-overridable, aligned with scripts/lib/common.sh).

New helpers Test-ReleaseTagShape, Get-LatestGitHubTag (GitHub /releases/latest redirect), and Resolve-ToolVersion validate tags before building URLs, support literal latest via API-free lookups (k3d redirect, get.helm.sh/helm-latest-version), and retry transient failures like the bash installer. Install-K3dAndHelm wires these in place of the old JSON API calls.

Pester covers pins, tag validation, resolver behavior, timeouts, and a regression that blocks https://api.github.com from reappearing. manifest.sha256 is updated for install-k8s.ps1.

Reviewed by Cursor Bugbot for commit c3acf9e. Bugbot is set up for automated code reviews on this repo. Configure here.

…lookups (#410)

Ports the bash pins (#382) to the Windows installer: K3D_VERSION defaults
to v5.9.0 and HELM_VERSION to v4.2.3 (lockstep with scripts/lib/common.sh
until #435 single-sources them), env-overridable, validated against a
release-tag shape before any URL is built (path-traversal gate mirroring
the bootstrap and cli install.ps1).

The unauthenticated releases/latest API allows 60 req/hour per IP — one
shared corporate NAT exhausts it and fails installs (observed live on a
customer install 2026-07-27). The literal value 'latest' still works but
resolves API-free: the /releases/latest redirect Location for k3d, and
get.helm.sh/helm-latest-version for helm — exactly like lib/setup-linux.sh.

A Pester gate now fails the suite if any https://api.github.com fetch
reappears in the installer.

Closes #410

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@LukasWodka
LukasWodka requested a review from saadqbal as a code owner July 27, 2026 13:50
@LukasWodka LukasWodka self-assigned this Jul 27, 2026
@LukasWodka

Copy link
Copy Markdown
Contributor Author

bugbot run

Comment thread scripts/install-k8s.ps1 Outdated
…s (Bugbot #438)

The new API-free 'latest' resolvers ran a single request — the old
lookups and lib/setup-linux.sh retry 3x5s. Resolve-ToolVersion now
drives the resolver through Invoke-WithRetry (resolvers throw on
failure), so a one-off network blip on flaky corporate egress retries
instead of aborting the install; a persistent failure still fails
closed with the pin-a-tag remedy.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Comment thread scripts/install-k8s.ps1
@LukasWodka

Copy link
Copy Markdown
Contributor Author

bugbot run

…ugbot #438)

A host that accepts the TCP connect but never responds would hang the
version resolvers indefinitely; the bash peers bound this with
--connect-timeout 15 --max-time 30. Both resolver requests now carry
-TimeoutSec 30; a timeout throws, so the retry ladder + fail-closed
remedy from the previous commit take over. AST-based Pester gate keeps
the timeouts in place.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@LukasWodka

Copy link
Copy Markdown
Contributor Author

bugbot run

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit c3acf9e. Configure here.

@shujaatTracebloc shujaatTracebloc left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the diff, the helpers it depends on (Invoke-WithRetry, Err, Get-WindowsArch), and the two prior Bugbot findings.

Correctness — verified

  • Pins v5.9.0 (k3d) / v4.2.3 (helm) match scripts/lib/common.sh exactly — the stated lockstep invariant holds.
  • The manifest.sha256 entry matches install-k8s.ps1 byte-for-byte.
  • Default path is pinned → no api.github.com and no network for version resolution; a test asserts the API URL never reappears in the file.
  • Test-ReleaseTagShape fails closed on empty / / / .. / non-vX.Y.Z, so a tag is validated before it is ever interpolated into a download URL (traversal lever closed).
  • Both latest resolvers now carry Invoke-WithRetry (retry 3×5 parity) and -TimeoutSec 30; network-down / timeout / empty-response all throw → retry → fail-closed via Err. Both earlier Bugbot findings (dropped retries, missing timeouts) are addressed in code and each has a dedicated test (incl. the AST test enforcing -TimeoutSec on every Invoke-WebRequest in Get-LatestGitHubTag).

Bugbot: both inline threads resolved; latest review reports no new issues; check green.

Caveats (not blockers):

  1. Stacked on #437 — base is fix/409-unc-job-cwd, so #437 must merge first.
  2. installer-tests.yaml (the Pester suite) is gated to base main/develop/openshift, so it does not run on this PR. The 10 new tests are validated only by the author's local run + this code read; they will run in CI once #437 merges and this retargets/rebases onto develop.

LGTM.

@LukasWodka
LukasWodka merged commit aaa15e7 into fix/409-unc-job-cwd Jul 27, 2026
4 checks passed
shujaatTracebloc added a commit that referenced this pull request Jul 27, 2026
…lookups (re-land #410 onto develop) (#446)

* fix(installer): pin k3d + helm versions — drop api.github.com latest lookups (#410)

Ports the bash pins (#382) to the Windows installer: K3D_VERSION defaults
to v5.9.0 and HELM_VERSION to v4.2.3 (lockstep with scripts/lib/common.sh
until #435 single-sources them), env-overridable, validated against a
release-tag shape before any URL is built (path-traversal gate mirroring
the bootstrap and cli install.ps1).

The unauthenticated releases/latest API allows 60 req/hour per IP — one
shared corporate NAT exhausts it and fails installs (observed live on a
customer install 2026-07-27). The literal value 'latest' still works but
resolves API-free: the /releases/latest redirect Location for k3d, and
get.helm.sh/helm-latest-version for helm — exactly like lib/setup-linux.sh.

A Pester gate now fails the suite if any https://api.github.com fetch
reappears in the installer.

Closes #410

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(installer): restore retry parity on the 'latest' version resolvers (Bugbot #438)

The new API-free 'latest' resolvers ran a single request — the old
lookups and lib/setup-linux.sh retry 3x5s. Resolve-ToolVersion now
drives the resolver through Invoke-WithRetry (resolvers throw on
failure), so a one-off network blip on flaky corporate egress retries
instead of aborting the install; a persistent failure still fails
closed with the pin-a-tag remedy.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(installer): bound the 'latest' lookup requests (-TimeoutSec 30, Bugbot #438)

A host that accepts the TCP connect but never responds would hang the
version resolvers indefinitely; the bash peers bound this with
--connect-timeout 15 --max-time 30. Both resolver requests now carry
-TimeoutSec 30; a timeout throws, so the retry ladder + fail-closed
remedy from the previous commit take over. AST-based Pester gate keeps
the timeouts in place.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Lukas Wuttke <lukas@tracebloc.io>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants