From 0bcee1686cdb3a52e4b85fe396947928b0452054 Mon Sep 17 00:00:00 2001 From: MK Date: Fri, 3 Apr 2026 14:16:15 +0800 Subject: [PATCH 1/2] fix(cli): replace *> with 2>&1 in install.ps1 for PowerShell 7.6 The `*>` redirection operator on native commands can cause a .NET `InvalidOperationException` when `StandardOutputEncoding` is set but `RedirectStandardOutput` is not. This happens interactively (real console attached) but not in CI (no console). Capture output to a variable first, then write to log file via `Out-File` to avoid both the redirection issue and `$LASTEXITCODE` pipeline clobbering. Also adds a PowerShell 7.6 CI test job for regression coverage. Closes #1019 --- .github/workflows/test-standalone-install.yml | 80 +++++++++++++++++++ packages/cli/install.ps1 | 6 +- 2 files changed, 84 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test-standalone-install.yml b/.github/workflows/test-standalone-install.yml index 9e3d29c1cd..b4b371a4a1 100644 --- a/.github/workflows/test-standalone-install.yml +++ b/.github/workflows/test-standalone-install.yml @@ -474,6 +474,86 @@ jobs: vp upgrade --rollback vp --version + test-install-ps1-v76: + name: Test install.ps1 (Windows x64, PowerShell 7.6) + runs-on: windows-latest + permissions: + contents: read + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Install PowerShell 7.6 + shell: pwsh + run: | + dotnet tool install --global PowerShell --version 7.6.0 + $pwsh76 = "$env:USERPROFILE\.dotnet\tools\pwsh.exe" + echo "PWSH76=$pwsh76" >> $env:GITHUB_ENV + $ver = & $pwsh76 -NoProfile -Command '$PSVersionTable.PSVersion.ToString()' + Write-Host "PowerShell version: $ver" + if (-not $ver.StartsWith("7.6")) { + Write-Error "Expected PowerShell 7.6.x but got $ver" + exit 1 + } + + - name: Run install.ps1 via iex under PowerShell 7.6 + shell: pwsh + run: | + & $env:PWSH76 -NoProfile -Command "Get-Content ./packages/cli/install.ps1 -Raw | Invoke-Expression" + + - name: Set PATH + shell: bash + run: | + echo "$USERPROFILE\.vite-plus\bin" >> $GITHUB_PATH + + - name: Verify installation + shell: pwsh + working-directory: ${{ runner.temp }} + run: | + Write-Host "PATH: $env:Path" + vp --version + vp --help + vp create vite --no-interactive --no-agent -- hello --no-interactive -t vanilla + cd hello + vp run build + vp --version + + - name: Verify bin setup + shell: pwsh + run: | + $binPath = "$env:USERPROFILE\.vite-plus\bin" + Get-ChildItem -Force $binPath + if (-not (Test-Path $binPath)) { + Write-Error "Bin directory not found: $binPath" + exit 1 + } + + $expectedShims = @("node.exe", "npm.exe", "npx.exe") + foreach ($shim in $expectedShims) { + $shimFile = Join-Path $binPath $shim + if (-not (Test-Path $shimFile)) { + Write-Error "Shim not found: $shimFile" + exit 1 + } + Write-Host "Found shim: $shimFile" + } + where.exe node + where.exe npm + where.exe npx + where.exe vp + + $env:Path = "$env:USERPROFILE\.vite-plus\bin;$env:Path" + vp env doctor + vp env run --node 24 -- node -p "process.versions" + + - name: Verify upgrade + shell: pwsh + run: | + vp upgrade --check + vp upgrade 0.1.14-alpha.1 + vp --version + vp upgrade --rollback + vp --version + test-install-ps1: name: Test install.ps1 (Windows x64) runs-on: windows-latest diff --git a/packages/cli/install.ps1 b/packages/cli/install.ps1 index 9385a0f2d1..b4f39835aa 100644 --- a/packages/cli/install.ps1 +++ b/packages/cli/install.ps1 @@ -375,8 +375,10 @@ function Main { Push-Location $VersionDir try { $env:CI = "true" - & "$BinDir\vp.exe" install --silent *> $installLog - if ($LASTEXITCODE -ne 0) { + $output = & "$BinDir\vp.exe" install --silent 2>&1 + $installExitCode = $LASTEXITCODE + $output | Out-File $installLog + if ($installExitCode -ne 0) { Write-Host "error: Failed to install dependencies. See log for details: $installLog" -ForegroundColor Red exit 1 } From 60a834719f878f1e7c555941267bc73be62effcf Mon Sep 17 00:00:00 2001 From: MK Date: Fri, 3 Apr 2026 19:49:35 +0800 Subject: [PATCH 2/2] fix(cli): unblock downloaded binaries to prevent Access Denied error Windows SmartScreen / Defender blocks execution of downloaded .exe files that carry a Zone.Identifier (Mark of the Web) alternate data stream. This causes both "Access denied" on vp.exe itself and "Failed to download Node.js runtime: Access is denied. (os error 5)" when vp.exe tries to perform file operations while MOTW-restricted. Strip the marker with Unblock-File after copying binaries to BinDir. Closes #901 Closes #1019 Closes #1226 --- packages/cli/install.ps1 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/cli/install.ps1 b/packages/cli/install.ps1 index b4f39835aa..708d52e412 100644 --- a/packages/cli/install.ps1 +++ b/packages/cli/install.ps1 @@ -350,6 +350,10 @@ function Main { } } + # Remove Zone.Identifier (Mark of the Web) from downloaded binaries so + # Windows SmartScreen / Defender won't block execution. + Get-ChildItem -Path $BinDir -Filter "*.exe" | Unblock-File + # Generate wrapper package.json that declares vite-plus as a dependency. # pnpm will install vite-plus and all transitive deps via `vp install`. # The packageManager field pins pnpm to a known-good version.