fix(ci): install kind directly on Windows to avoid docker-desktop dep#261
Conversation
Chocolatey's `kind` package pulls `docker-desktop` as a dependency, which hangs on Windows CI runners. Since we use podman as the kind provider, docker-desktop is not needed. Download the kind binary directly from GitHub releases instead.
📝 WalkthroughWalkthroughThis PR updates the Windows CI workflow: Podman is installed from a pinned MSI with SHA256 verification, WSL2 is set and a rootful Podman machine initialized; the Windows kind step now downloads a pinned ChangesWindows Kubernetes Setup via Podman and kind
Sequence Diagram(s)sequenceDiagram
participant GHA as GitHub Actions
participant MSI as Podman MSI
participant FS as FileSystem
participant WSL as WSL2
participant KindBin as kind.exe
participant Podman as Podman
participant Cluster as Kind Cluster
GHA->>MSI: Download pinned Podman MSI
GHA->>MSI: Verify MSI SHA256
MSI->>FS: msiexec install (silent, log)
GHA->>FS: Verify podman.exe exists (or dump log/search)
GHA->>WSL: Set default version to 2
GHA->>Podman: podman machine init --rootful && podman machine start
GHA->>KindBin: Download pinned kind.exe and checksum
GHA->>KindBin: Verify kind SHA256
GHA->>GHA: Generate cluster UUID
GHA->>KindBin: kind create cluster --name UUID --image pinned-digest
KindBin->>Podman: Request node containers
Podman->>Cluster: Start node containers
Cluster->>GHA: Cluster ready
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
✅ Deploy Preview for devsydev canceled.
|
Replace `choco install podman-cli` with a direct download of the podman MSI installer from GitHub releases. This eliminates all Chocolatey dependencies from the Windows CI steps, matching the direct-download approach already used for kind.
… URL The kind download was failing because: 1. curl tried to write directly to C:\Program Files\RedHat\Podman\kind.exe before the MSI had created that directory 2. The kind.sigs.k8s.io redirect URL returned a 99-byte HTML page instead of following through to the binary Fix by downloading to RUNNER_TEMP first (always exists) then moving, and using the direct GitHub releases URL which doesn't have redirect issues.
…ndows The podman MSI may not create the install directory synchronously before the next shell command runs, causing `mv kind.exe` to fail with "No such file or directory". Place kind.exe in RUNNER_TEMP instead and add it to PATH independently. Also generate the cluster UUID inline since the uuid step is skipped on Windows runners.
…or WSL test The podman MSI install via bash was silently failing because Start-Process didn't properly wait. Split the approach: - provider test: use pre-installed Docker (no podman needed) - up-docker-wsl test: install podman via PowerShell with proper wait/error handling, then start podman machine in a separate step - Only set DOCKER_HOST to podman pipe for the up-docker-wsl test
Windows Docker is in Windows-container mode and cannot pull Linux images like kindest/node. All Windows kind tests need podman for its Linux VM (via WSL2). Replace the failing manual MSI install with the redhat-actions/podman-install action which handles this reliably.
The redhat-actions/podman-install action has no v1 tag. Revert to MSI approach with explicit INSTALLDIR parameter, verbose MSI logging for diagnostics, and full path to podman.exe to avoid PATH race conditions.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/pr-ci.yml:
- Around line 401-403: The workflow downloads Podman (variables $msiUrl and
$msiPath) and kind without verifying integrity; update the steps that use
Invoke-WebRequest to also fetch the corresponding official SHA256 checksum files
for Podman and kind, compute the downloaded file's SHA256 (e.g., using
Get-FileHash) and compare against the published checksum before running msiexec
or executing the kind binary; if the hash verification fails, fail the job and
emit a clear error via Write-Error, otherwise proceed to installation. Include
the same verification for the other download steps referenced (the kind download
around lines 431-432) and ensure the checksum source uses the official release
asset URL.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 96c5e87b-0283-4985-b760-4d0f46686cc8
📒 Files selected for processing (1)
.github/workflows/pr-ci.yml
Verify integrity of downloaded binaries before execution to harden against supply-chain attacks on Windows CI runners.
The Invoke-WebRequest of the shasums file returned binary content on Windows PowerShell, causing the hash extraction regex to produce an empty string. Pin the known hash directly instead.
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
.github/workflows/pr-ci.yml (1)
437-452: ⚡ Quick winMake the bash setup fail-fast and detect HTTP errors.
Two robustness gaps in this step:
- No
set -euo pipefail: intermediate failures (curl, sha256sum, awk, python) won't abort the step, leading to confusing downstream errors (e.g.,kind create clusterrunning with an emptyCLUSTER_NAME).curl -Lodoes not check HTTP status. If the release URL ever 404s or is redirected to an error page, an HTML/error body is silently written tokind.exe(the SHA check would catch this, but--fail/-fproduces a cleaner failure mode and ensures$RUNNER_TEMP/kind.sha256sumparsing isn't done on garbage).♻️ Proposed change
run: | + set -euo pipefail - curl -Lo "$RUNNER_TEMP/kind.exe" "https://github.com/kubernetes-sigs/kind/releases/download/v0.24.0/kind-windows-amd64" - curl -Lo "$RUNNER_TEMP/kind.sha256sum" "https://github.com/kubernetes-sigs/kind/releases/download/v0.24.0/kind-windows-amd64.sha256sum" + curl -fLo "$RUNNER_TEMP/kind.exe" "https://github.com/kubernetes-sigs/kind/releases/download/v0.24.0/kind-windows-amd64" + curl -fLo "$RUNNER_TEMP/kind.sha256sum" "https://github.com/kubernetes-sigs/kind/releases/download/v0.24.0/kind-windows-amd64.sha256sum" expected=$(awk '{print $1}' "$RUNNER_TEMP/kind.sha256sum") actual=$(sha256sum "$RUNNER_TEMP/kind.exe" | awk '{print $1}')🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/pr-ci.yml around lines 437 - 452, Add fail-fast and HTTP-error detection to the bash run block: enable strict mode by adding set -euo pipefail at the start of the script, change the curl invocations that download "$RUNNER_TEMP/kind.exe" and "$RUNNER_TEMP/kind.sha256sum" to use the --fail (or -f) flag so HTTP errors cause curl to exit non‑zero, and keep the existing sha256sum verification and CLUSTER_NAME generation (python ... uuid) before invoking kind create cluster --name "$CLUSTER_NAME"; reference the RUNNER_TEMP, curl, sha256sum, CLUSTER_NAME and kind create cluster symbols when making these edits.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/pr-ci.yml:
- Around line 414-430: The PowerShell step currently prints $proc.ExitCode and
relies on Test-Path to catch an MSI failure and does not abort on failures from
native commands (msiexec, wsl, podman), so change the step to check and fail on
non-zero exit codes: after the msiexec Start-Process block inspect
$proc.ExitCode and throw/exit if non-zero (instead of only logging), and after
each native invocation (wsl --set-default-version, & "$installDir\podman.exe"
machine init, set --rootful, start) check $LASTEXITCODE and fail immediately
with a clear message; optionally factor this into a small helper function (e.g.,
Assert-LastExitCode or Invoke-And-EnsureSuccess) to run the command and abort on
failure to keep the script DRY.
- Around line 429-430: The CI workflow sets DOCKER_HOST to the old
podman-machine named pipe; update the DOCKER_HOST variable in the workflow (the
DOCKER_HOST assignment) to point to Podman 5.x rootful Windows pipe
"npipe:////./pipe/docker_engine" instead of
"npipe:////./pipe/podman-machine-default" so Windows e2e tests connect to the
Podman daemon without Docker Desktop.
---
Nitpick comments:
In @.github/workflows/pr-ci.yml:
- Around line 437-452: Add fail-fast and HTTP-error detection to the bash run
block: enable strict mode by adding set -euo pipefail at the start of the
script, change the curl invocations that download "$RUNNER_TEMP/kind.exe" and
"$RUNNER_TEMP/kind.sha256sum" to use the --fail (or -f) flag so HTTP errors
cause curl to exit non‑zero, and keep the existing sha256sum verification and
CLUSTER_NAME generation (python ... uuid) before invoking kind create cluster
--name "$CLUSTER_NAME"; reference the RUNNER_TEMP, curl, sha256sum, CLUSTER_NAME
and kind create cluster symbols when making these edits.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: cb0b0f82-bab9-49eb-bdab-e6d5b8a5ffe0
📒 Files selected for processing (1)
.github/workflows/pr-ci.yml
| $proc = Start-Process msiexec.exe -Wait -PassThru -ArgumentList "/i `"$msiPath`" /qn /norestart /l*v `"$logFile`" INSTALLDIR=`"$installDir`"" | ||
| Write-Host "MSI exit code: $($proc.ExitCode)" | ||
|
|
||
| if (!(Test-Path "$installDir\podman.exe")) { | ||
| Write-Host "--- MSI install log (last 50 lines) ---" | ||
| Get-Content $logFile -Tail 50 | ||
| Write-Host "--- Searching for podman.exe ---" | ||
| Get-ChildItem "C:\" -Filter "podman.exe" -Recurse -Depth 4 -ErrorAction SilentlyContinue | ForEach-Object { Write-Host $_.FullName } | ||
| throw "podman.exe not found at $installDir" | ||
| } | ||
|
|
||
| echo "$installDir" | Out-File -Append -FilePath $env:GITHUB_PATH -Encoding utf8 | ||
|
|
||
| wsl --set-default-version 2 | ||
| & "$installDir\podman.exe" machine init | ||
| & "$installDir\podman.exe" machine set --rootful | ||
| & "$installDir\podman.exe" machine start |
There was a problem hiding this comment.
Native command failures don't fail this step in PowerShell.
By default, PowerShell does not propagate non-zero exit codes from native executables (msiexec, wsl, podman) into terminating errors, and $ErrorActionPreference = 'Stop' does not cover them either. As a result:
- Line 414:
$proc.ExitCodeis only printed; an MSI failure (e.g., 1603/1618) is recovered only becauseTest-Pathhappens to catch missingpodman.exe. - Lines 427–430:
wsl --set-default-version 2,podman machine init,podman machine set --rootful, andpodman machine startcan all fail silently, leaving subsequent CI steps to fail with confusing downstream errors.
Check $LASTEXITCODE after each native invocation (or wrap in a small helper) so failures abort the job with a clear cause.
🛠️ Suggested hardening
$proc = Start-Process msiexec.exe -Wait -PassThru -ArgumentList "/i `"$msiPath`" /qn /norestart /l*v `"$logFile`" INSTALLDIR=`"$installDir`""
Write-Host "MSI exit code: $($proc.ExitCode)"
+ if ($proc.ExitCode -ne 0) {
+ Get-Content $logFile -Tail 100
+ throw "Podman MSI install failed with exit code $($proc.ExitCode)"
+ }
if (!(Test-Path "$installDir\podman.exe")) {
...
}
echo "$installDir" | Out-File -Append -FilePath $env:GITHUB_PATH -Encoding utf8
- wsl --set-default-version 2
- & "$installDir\podman.exe" machine init
- & "$installDir\podman.exe" machine set --rootful
- & "$installDir\podman.exe" machine start
+ function Invoke-Native {
+ param([string]$Description, [scriptblock]$Cmd)
+ & $Cmd
+ if ($LASTEXITCODE -ne 0) { throw "$Description failed with exit code $LASTEXITCODE" }
+ }
+ Invoke-Native "wsl --set-default-version 2" { wsl --set-default-version 2 }
+ Invoke-Native "podman machine init" { & "$installDir\podman.exe" machine init }
+ Invoke-Native "podman machine set --rootful" { & "$installDir\podman.exe" machine set --rootful }
+ Invoke-Native "podman machine start" { & "$installDir\podman.exe" machine start }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/pr-ci.yml around lines 414 - 430, The PowerShell step
currently prints $proc.ExitCode and relies on Test-Path to catch an MSI failure
and does not abort on failures from native commands (msiexec, wsl, podman), so
change the step to check and fail on non-zero exit codes: after the msiexec
Start-Process block inspect $proc.ExitCode and throw/exit if non-zero (instead
of only logging), and after each native invocation (wsl --set-default-version, &
"$installDir\podman.exe" machine init, set --rootful, start) check $LASTEXITCODE
and fail immediately with a clear message; optionally factor this into a small
helper function (e.g., Assert-LastExitCode or Invoke-And-EnsureSuccess) to run
the command and abort on failure to keep the script DRY.
Podman 5.x in rootful mode exposes the API on \\.\pipe\docker_engine, not \\.\pipe\podman-machine-default. Update DOCKER_HOST in both the kind setup step and the test runner step.
On Windows Git Bash, sha256sum outputs a leading backslash when the file path contains backslashes. Strip it with awk gsub. Also pin the kind hash directly and set DOCKER_HOST to the pipe podman actually uses.
The awk gsub approach didn't strip the backslash due to YAML escaping complexity. Use sed with a character class to strip any non-hex prefix.
There was a problem hiding this comment.
♻️ Duplicate comments (2)
.github/workflows/pr-ci.yml (2)
414-415:⚠️ Potential issue | 🟠 Major | ⚡ Quick winFail fast on native command errors in the Windows Podman setup step.
This block still allows
msiexec,wsl, andpodman machinefailures to continue without an immediate hard fail, which can mask the root cause.Suggested fix
$proc = Start-Process msiexec.exe -Wait -PassThru -ArgumentList "/i `"$msiPath`" /qn /norestart /l*v `"$logFile`" INSTALLDIR=`"$installDir`"" Write-Host "MSI exit code: $($proc.ExitCode)" + if ($proc.ExitCode -ne 0) { + Write-Host "--- MSI install log (last 50 lines) ---" + Get-Content $logFile -Tail 50 + throw "Podman MSI install failed with exit code $($proc.ExitCode)" + } + + function Assert-LastExitCode([string]$description) { + if ($LASTEXITCODE -ne 0) { + throw "$description failed with exit code $LASTEXITCODE" + } + } ... - wsl --set-default-version 2 - & "$installDir\podman.exe" machine init - & "$installDir\podman.exe" machine set --rootful - & "$installDir\podman.exe" machine start + wsl --set-default-version 2 + Assert-LastExitCode "wsl --set-default-version 2" + & "$installDir\podman.exe" machine init + Assert-LastExitCode "podman machine init" + & "$installDir\podman.exe" machine set --rootful + Assert-LastExitCode "podman machine set --rootful" + & "$installDir\podman.exe" machine start + Assert-LastExitCode "podman machine start"Also applies to: 427-430
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/pr-ci.yml around lines 414 - 415, The PowerShell block uses Start-Process msiexec.exe and then writes the exit code but doesn't fail the job on non-zero exits; modify the msiexec invocation (Start-Process msiexec.exe) to check $proc.ExitCode immediately after execution and if non-zero call throw or exit with that code so the workflow fails fast; apply the same pattern to the wsl and podman machine commands referenced in the nearby steps (check their process exit codes and raise/exit on failure) so errors cannot be silently ignored.
437-437:⚠️ Potential issue | 🟠 Major | ⚡ Quick winUse the Podman 5.x rootful pipe for
DOCKER_HOSTon Windows.
podman-machine-defaultis inconsistent with the rootful setup in this workflow; both WindowsDOCKER_HOSTassignments should point todocker_engine.Suggested fix
- DOCKER_HOST: npipe:////./pipe/podman-machine-default + DOCKER_HOST: npipe:////./pipe/docker_engine ... - DOCKER_HOST="npipe:////./pipe/podman-machine-default" \ + DOCKER_HOST="npipe:////./pipe/docker_engine" \Also applies to: 506-506
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/pr-ci.yml at line 437, Update the Windows DOCKER_HOST environment assignment to use the Podman 5.x rootful pipe name "docker_engine" instead of "podman-machine-default"; replace the value npipe:////./pipe/podman-machine-default with npipe:////./pipe/docker_engine for the DOCKER_HOST entries so both Windows assignments consistently point to docker_engine in the workflow YAML.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Duplicate comments:
In @.github/workflows/pr-ci.yml:
- Around line 414-415: The PowerShell block uses Start-Process msiexec.exe and
then writes the exit code but doesn't fail the job on non-zero exits; modify the
msiexec invocation (Start-Process msiexec.exe) to check $proc.ExitCode
immediately after execution and if non-zero call throw or exit with that code so
the workflow fails fast; apply the same pattern to the wsl and podman machine
commands referenced in the nearby steps (check their process exit codes and
raise/exit on failure) so errors cannot be silently ignored.
- Line 437: Update the Windows DOCKER_HOST environment assignment to use the
Podman 5.x rootful pipe name "docker_engine" instead of
"podman-machine-default"; replace the value
npipe:////./pipe/podman-machine-default with npipe:////./pipe/docker_engine for
the DOCKER_HOST entries so both Windows assignments consistently point to
docker_engine in the workflow YAML.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 51a4c6cd-d63e-4c79-b747-210f07f92a90
📒 Files selected for processing (1)
.github/workflows/pr-ci.yml
CI Fixed ✓All 44 jobs now passing. Three commits added on top of the checksum verification commit:
Also reverted the |
Summary
choco install kindwith a direct binary download fromkind.sigs.k8s.ioon Windows CI runnerskindpackage pullsdocker-desktopas a dependency, which hangs on Windows runners since we only need podman (KIND_EXPERIMENTAL_PROVIDER: podman)choco install podman-cli -yunchanged; only the kind installation method changesSummary by CodeRabbit