Skip to content

fix(phase4): execute Windows WSL scripts without BOM - #82

Merged
gitcommit90 merged 1 commit into
mainfrom
fix/windows-wsl-script-transport
Aug 5, 2026
Merged

fix(phase4): execute Windows WSL scripts without BOM#82
gitcommit90 merged 1 commit into
mainfrom
fix/windows-wsl-script-transport

Conversation

@gitcommit90

@gitcommit90 gitcommit90 commented Aug 5, 2026

Copy link
Copy Markdown
Owner

What changed

The last real Windows run proved stdin preserved shell quoting, but its log exposed two PowerShell 5 boundary effects: stdin added a UTF-8 BOM (test), and non-login bash -s omitted the installed node path. The helper now writes each command to a unique runner-temp file as UTF-8 without BOM, mounts it into WSL, and executes it from a login shell.

Verification

  • exact no-BOM file transport passed under the actual limited helm-ph4 account on VM 115 with an isolated WSL distribution, nested command substitutions, login PATH, and cleanup;
  • updated script parsed in actual VM 115 Windows PowerShell;
  • focused Phase 4 suite: 8 passed, 0 failed;
  • full npm run ci: 177 tests, 175 passed, 2 skipped, 0 failed.

Only the Windows acceptance helper and its regression test changed. No version bump, tag, release, Stable promotion, website deploy, or production change.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Improved Windows command execution in WSL for better UTF-8 compatibility.
    • Preserved command text and supported Node.js paths more reliably.
    • Added exit-status checks to detect failed commands.
    • Ensured temporary scripts are cleaned up after execution.

PowerShell 5 adds a UTF-8 BOM when piping text to wsl.exe, so bash received
`test` as the first command. A non-login `bash -s` also omitted the installed
node path. Write each command to a unique runner-temp script as UTF-8 without
BOM, mount that file through /mnt, and execute it from a login shell.

The exact transport passed under the real limited helm-ph4 account on VM 115
with an isolated WSL distribution, including nested substitutions and cleanup.
Keep structural coverage for no-BOM file transport and login-shell execution.

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

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Invoke-Distro now writes commands to BOM-free UTF-8 temporary scripts and executes them through a WSL login Bash shell. It checks the exit status and removes the script. Windows acceptance tests validate the new behavior.

Changes

Windows WSL execution

Layer / File(s) Summary
Temporary script execution and validation
ops/platform-acceptance/windows.ps1, test/phase4-platform-acceptance.mjs
Invoke-Distro writes temporary UTF-8 scripts, runs them with /bin/bash -lc, checks failures, and cleans up. Acceptance tests require this path and reject stdin piping.

Estimated code review effort: 3 (Moderate) | ~15–30 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the main change: removing BOMs when executing Windows WSL scripts.
Description check ✅ Passed The description clearly explains the problem, implementation, scope, and verification results, although it omits several template sections.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/windows-wsl-script-transport

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai 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.

Actionable comments posted: 2

🤖 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 `@ops/platform-acceptance/windows.ps1`:
- Around line 36-45: Update the temporary script handling around $script so
creation, path conversion, and WSL execution all occur inside the try block.
Initialize $script before try, guard cleanup in finally so it only runs when a
path was assigned, and use Remove-Item -LiteralPath for deletion.
- Around line 38-43: Update the temporary script execution in the PowerShell
flow around WriteAllText and the WSL bash invocation so every command failure
propagates instead of only the final command status; use bash’s errexit behavior
or prepend set -e to the generated script. Add a regression case in
Assert-DistroVersion coverage with a failing first command followed by a
successful final command, and if changing the invocation to bash -e, update the
corresponding expectation in phase4-platform-acceptance.mjs.
🪄 Autofix

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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 02152b7a-9a7a-4b1b-97e3-a107f735c013

📥 Commits

Reviewing files that changed from the base of the PR and between 2606bef and 67cf61e.

📒 Files selected for processing (2)
  • ops/platform-acceptance/windows.ps1
  • test/phase4-platform-acceptance.mjs

Comment on lines +36 to +45
$script = Join-Path $tempRoot ("1helm-distro-{0}.sh" -f [guid]::NewGuid().ToString('N'))
$encoding = New-Object System.Text.UTF8Encoding($false)
[IO.File]::WriteAllText($script, $Command + "`n", $encoding)
$drive = $script.Substring(0, 1).ToLowerInvariant()
$scriptInDistro = "/mnt/$drive/" + ($script.Substring(3) -replace '\\', '/')
try {
& $Wsl -d $Distro -u root --exec /bin/bash -lc "bash '$scriptInDistro'" | Out-Host
if ($LASTEXITCODE -ne 0) { Refuse "in-distribution command failed: $Command" }
} finally {
Remove-Item $script -Force -ErrorAction SilentlyContinue

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Keep cleanup active during temporary-file creation.

Line 41 starts try after WriteAllText and path conversion. If either operation fails, finally does not run and a temporary script can remain in the runner temp directory.

Move creation, path conversion, and execution inside try. Initialize $script before try, guard the cleanup, and use Remove-Item -LiteralPath.

🤖 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 `@ops/platform-acceptance/windows.ps1` around lines 36 - 45, Update the
temporary script handling around $script so creation, path conversion, and WSL
execution all occur inside the try block. Initialize $script before try, guard
cleanup in finally so it only runs when a path was assigned, and use Remove-Item
-LiteralPath for deletion.

Comment on lines +38 to +43
[IO.File]::WriteAllText($script, $Command + "`n", $encoding)
$drive = $script.Substring(0, 1).ToLowerInvariant()
$scriptInDistro = "/mnt/$drive/" + ($script.Substring(3) -replace '\\', '/')
try {
& $Wsl -d $Distro -u root --exec /bin/bash -lc "bash '$scriptInDistro'" | Out-Host
if ($LASTEXITCODE -ne 0) { Refuse "in-distribution command failed: $Command" }

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Propagate failures from every command in the temporary script.

Line 42 runs bash without -e, and Line 38 does not prepend set -e. Bash returns the status of the final command. In Assert-DistroVersion, a failed service check followed by a successful version check returns 0, so Line 43 records false success.

Run the script with bash -e or write set -e as the first line. Add a regression case with a failed first command and a successful final command. If bash -e is used, update Line 217 in test/phase4-platform-acceptance.mjs.

🤖 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 `@ops/platform-acceptance/windows.ps1` around lines 38 - 43, Update the
temporary script execution in the PowerShell flow around WriteAllText and the
WSL bash invocation so every command failure propagates instead of only the
final command status; use bash’s errexit behavior or prepend set -e to the
generated script. Add a regression case in Assert-DistroVersion coverage with a
failing first command followed by a successful final command, and if changing
the invocation to bash -e, update the corresponding expectation in
phase4-platform-acceptance.mjs.

@gitcommit90
gitcommit90 merged commit f6f58a4 into main Aug 5, 2026
6 checks passed
@gitcommit90
gitcommit90 deleted the fix/windows-wsl-script-transport branch August 5, 2026 05:27
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.

1 participant