chore(installer): honest step labels + per-tool progress in the Windows installer (#422) - #477
Merged
Merged
Conversation
…PS installer Step 1/5 "Checking system requirements" actually installed ~700 MB of tools, nearly all console-silent (downloads with the progress overlay off since #471, plus silent winget/Add-AppxPackage/installer invocations), which reads as a hang. The k3d start path also streamed raw INFO[...] lines past the style system. - Split Step 1 into "Checking system requirements" (preflight/GPU/virtualisation) and a dedicated "Installing system tools" step; renumber to /6. - Invoke-WithHeartbeat: run a blocking op in a background job with a live spinner (built on the existing Wait-JobWithProgress) so no op sits silent >10s. Wired into every tool download (kubectl/k3d/helm/winget/Docker Desktop), the winget installs, Add-AppxPackage, and the Docker Desktop installer. - Get-ToolSummaryLine: one honest line per tool (name, version, size, elapsed), printed as each tool becomes ready. - Route `k3d cluster start` through Invoke-WithHeartbeat: capture its raw output to the log + show a styled heartbeat instead of streaming INFO[...] lines (and fail loudly if start fails, instead of always reporting "started"). - Tests: Pester for Get-ToolSummaryLine, Invoke-WithHeartbeat, and source guards for the 6-step split + no-raw-k3d-output. The copy catalog is bash-driven and the bash installer already splits check (step a) from install (step b) with real progress, so its golden is unaffected. Closes #422 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Contributor
|
👋 Heads-up — Code review queue is at 34 / 30 Above the WIP limit. The team convention is to review existing PRs before opening new work. Open PRs currently in Code review (oldest first):
Pull from review before opening new work. (This is a nudge from the kanban WIP check, not a block.) |
shujaatTracebloc
marked this pull request as ready for review
July 29, 2026 14:52
…p-progress # Conflicts: # scripts/manifest.sha256 # scripts/tests/install-k8s.Tests.ps1
…gbot) Two High-severity findings from moving work into Start-Job via Invoke-WithHeartbeat: - TLS 1.2 doesn't carry into job runspaces (PS 5.1 defaults to TLS 1.0/1.1), so in-job HTTPS downloads (kubectl/k3d/helm/winget/Docker Desktop) could fail SSL/TLS on hosts that need the explicit floor. Re-apply Tls12 in $script:JobInit (OR-in, don't clobber), which every job runs before its scriptblock. - A native `k3d cluster start` non-zero exit leaves the job state 'Completed', so Invoke-WithHeartbeat never threw and the installer reported "Compute environment started." on a stopped cluster. The start scriptblock now checks $LASTEXITCODE and throws its captured output, so the existing catch surfaces a real Err. Adds a functional in-job-TLS test and a source guard for the exit-code throw. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…nstall (Bugbot) Two follow-on findings from the Start-Job/heartbeat design: - Invoke-WithHeartbeat threw a generic 'Failed while: ...' and swallowed the job's real error (Receive-Job -ErrorAction SilentlyContinue), so the k3d-start detail never reached the log/Err. Now capture output+error (2>&1) and the job's terminating reason, and include it in the throw; the k3d-start catch passes it as Err detail too. - The Docker Desktop installer Start-Process had no -ErrorAction Stop and no exit check, so a spawn/install failure completed the job as success and Step 2 continued. Now -ErrorAction Stop + PassThru + exit-code throw, wrapped so it Errs cleanly with the real detail. Adds a heartbeat failure-detail test + a Docker-installer source guard. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
k3d and helm printed their green Get-ToolSummaryLine 'ready' line inside the download branch, before Assert-ToolRuns — so a corrupt/wrong-arch binary showed as ready and then failed the gate (kubectl already gates first). Compute the summary at download time (correct elapsed) but defer the Ok until after the execute-gate passes. Adds a source guard. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The winget Docker path soft-logged failures, never checked $LASTEXITCODE, and had no direct-download fallback when winget was present — so a failed winget install let Step 2 continue and only surfaced as the 10-minute Docker-wait timeout later. Now: the winget scriptblock throws on a non-zero exit; if winget is absent OR didn't land the exe, fall through to the direct download (parity with k3d/helm); and a final Test-Path guard Errs immediately if neither path installed Docker. Adds a source guard. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…s (Bugbot) Start-Process -Wait / winget install inside Invoke-WithHeartbeat (a background job) leaks the child process on timeout: Stop-Job ends the job runspace but the installer keeps running, and the winget path could time out then fall through to a second concurrent install. Switch the Docker Desktop installer + all winget installs (Docker, k3d, helm) to Start-Process -PassThru + Wait-ProcessWithDeadline, which shows the spinner AND kills the actual process on timeout, then checks the exit code. Downloads (Invoke-WebRequest) stay on Invoke-WithHeartbeat — no child process to orphan. Updates the Docker source guards accordingly. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit e6be743. Configure here.
Same orphan hazard as the installers: k3d cluster start ran inside Invoke-WithHeartbeat (a job), so Stop-Job on timeout left the native k3d child running. Switch it to Start-Process -PassThru + Wait-ProcessWithDeadline (kills on timeout), redirecting its raw INFO[...] to temp files for the log; check both the deadline and the exit code so a failed/stuck start Errs with the real reason instead of a false 'started'. Now every process-spawning op is killable; only in-runspace downloads + Add-AppxPackage remain on the job-based heartbeat. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
saadqbal
approved these changes
Jul 30, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

What & why
Step 1/5 "Checking system requirements"in the PowerShell installer actually installed ~700 MB of tooling (Docker Desktop, kubectl, k3d, helm) — nearly all console-silent (the download progress overlay is off for speed since #471, and the winget /Add-AppxPackage/ installer invocations print nothing). Users read the dead air as a hang. Thek3d cluster startre-run path also streamed rawINFO[0000] …lines past the style system.Changes (
scripts/install-k8s.ps1)/6.Invoke-WithHeartbeat: runs a blocking op in a background job with a live spinner (built on the existingWait-JobWithProgress), so nothing in Steps 1–2 sits silent >10s. Wired into every tool download (kubectl / k3d / helm / winget / Docker Desktop), the winget installs,Add-AppxPackage, and the Docker Desktop installer.Get-ToolSummaryLine: one honest line per tool as it becomes ready — name, version, size, elapsed (e.g.kubectl v1.31.0 (~60 MB, 12s)).Invoke-WithHeartbeat— captured to the log with a styled heartbeat instead of rawINFO[…], and now fails loudly if start fails (was always reporting "started").Acceptance (from #422)
Copy catalog
The copy catalog is bash-driven (reads
step_headerfrominstall-k8s.sh), and the bash installer already splits check (a) from install (b) with real progress (spin_cmd/download_with_progress). This change is PowerShell-only, so the catalog golden is unaffected —copy-catalog.batsstays green.Tests
Get-ToolSummaryLine(formatting),Invoke-WithHeartbeat(returns output / throws on failure / passes ArgumentList), and source guards for the 6-step split + no-raw-k3d-output.Local verification
Pester 241/0/8 · bats 559 ok (only the 3 known macOS-local flakes) · copy-catalog green · check-style pass · drift clean · manifest regenerated · PS parse OK.
Closes #422
Note
Low Risk
Installer UX and progress/error-handling only on Windows PowerShell; no auth, cluster logic, or bash installer changes beyond the manifest hash.
Overview
The Windows
install-k8s.ps1flow is renumbered to six steps: preflight/GPU/virtualization stay in step 1, and ~700 MB of tooling (winget, Docker Desktop, kubectl, k3d, helm) moves to a dedicated “Installing system tools” step so labels match what actually runs.Invoke-WithHeartbeatwraps long silent work (HTTPS downloads,Add-AppxPackage) with the existing spinner via background jobs;Get-ToolSummaryLineprints one green line per tool (version, size, elapsed) afterAssert-ToolRuns. Job init now re-applies TLS 1.2 in job runspaces so corporate proxies don’t break in-job downloads.winget, the Docker Desktop installer, and
k3d cluster startuseStart-Process+Wait-ProcessWithDeadline(kill on timeout) instead of jobs that could orphan children. Docker install adds winget→direct-download fallback and explicit failure if the exe never appears. Pester covers the new helpers and source guards;manifest.sha256is updated forinstall-k8s.ps1.Reviewed by Cursor Bugbot for commit ef4b7c5. Bugbot is set up for automated code reviews on this repo. Configure here.