Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions .github/scripts/test-install-bootstrap.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ if ($args.Count -eq 0) {
exit 0
}
if ($env:VP_SELF_SETUP_SUPPORT_CHECK -ne '1') { exit 99 }
if ($scenario -in @('legacy', 'legacy-failure', 'pr')) { Write-Output 'Usage: vp [COMMAND]' }
if ($scenario -in @('legacy', 'legacy-remote', 'legacy-failure', 'pr')) { Write-Output 'Usage: vp [COMMAND]' }
else { Write-Output 'vite-plus-self-setup-v1' }
exit 0
'@ | Set-Content -LiteralPath "$testRoot/package/binary.ps1"
Expand Down Expand Up @@ -60,6 +60,10 @@ function Invoke-WebRequest {
if ($Method -eq 'Head') {
return @{ Headers = @{ 'x-commit-key' = "voidzero-dev:vite-plus:$fixtureSha" } }
}
if (-not $OutFile) {
$content = Get-Content -LiteralPath "$testRoot/scripts/install-legacy.ps1" -Raw
return @{ Content = [Text.Encoding]::UTF8.GetBytes($content) }
}
Copy-Item -LiteralPath "$testRoot/payload.tgz" -Destination $OutFile
}

Expand All @@ -76,7 +80,7 @@ function Invoke-InstallHandoff {
}

try {
foreach ($scenario in @('supported', 'legacy', 'legacy-failure', 'failure', 'pr', 'supported-pr')) {
foreach ($scenario in @('supported', 'legacy', 'legacy-remote', 'legacy-failure', 'failure', 'pr', 'supported-pr')) {
$env:Path = $originalPath
$env:NPM_CONFIG_REGISTRY = 'https://custom.example'
$script:Requests = New-Object 'System.Collections.Generic.List[string]'
Expand All @@ -89,7 +93,7 @@ try {
$ViteVersion = 'latest'
$LocalTgz = $LocalBinary = $PrVersion = $PrCommitVersion = $null
$NpmRegistry = 'https://custom.example'
$InstallerDirectory = "$testRoot/scripts"
$InstallerDirectory = if ($scenario -eq 'legacy-remote') { $null } else { "$testRoot/scripts" }
if ($scenario -in @('pr', 'supported-pr')) { $PrVersion = '2406' }
Main
Assert ($env:NPM_CONFIG_REGISTRY -eq 'https://custom.example') 'Setup changed the caller registry'
Expand Down
60 changes: 60 additions & 0 deletions .github/scripts/test-install-legacy-remote.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Reproduce setup-vp's remote install of 0.2.6 in cloudflare/vinext#3251.
# Serve this checkout's scripts so the test does not depend on the deployed installer.
$ErrorActionPreference = 'Stop'
$root = Join-Path $env:RUNNER_TEMP 'vp-remote-legacy'
New-Item -ItemType Directory -Force -Path $root | Out-Null
Copy-Item (Join-Path $PSScriptRoot '../../packages/cli/install.ps1') "$root/install.txt"
Copy-Item (Join-Path $PSScriptRoot '../../packages/cli/install-legacy.ps1') "$root/install-legacy.bin"
$stdout = Join-Path $root 'server.stdout.txt'
$stderr = Join-Path $root 'server.stderr.txt'

# Python serves .txt as text/plain and .bin as application/octet-stream.
# Port 0 selects an available port. Unbuffered output exposes it before any request.
$server = Start-Process -FilePath (Get-Command python).Source `
-ArgumentList @('-u', '-m', 'http.server', '0', '--bind', '127.0.0.1', '--directory', "`"$root`"") `
-RedirectStandardOutput $stdout -RedirectStandardError $stderr -PassThru
try {
$url = $null
$deadline = (Get-Date).AddSeconds(30)
while ((Get-Date) -lt $deadline) {
if ($server.HasExited) {
throw "Installer HTTP server exited: $(Get-Content -LiteralPath $stderr -Raw)"
}
$serverOutput = Get-Content -LiteralPath $stdout -Raw
if ($serverOutput -match 'Serving HTTP on 127\.0\.0\.1 port (\d+)') {
$url = "http://127.0.0.1:$($Matches[1])"
break
}
Start-Sleep -Milliseconds 100
}
if (-not $url) { throw 'Installer HTTP server did not start' }

$env:VP_HOME = Join-Path $root 'install'
$env:VP_TEST_INSTALLER_URL = "$url/install.txt"
$env:VP_LEGACY_INSTALLER_URL = "$url/install-legacy.bin"
$response = Invoke-WebRequest -Uri $env:VP_LEGACY_INSTALLER_URL -UseBasicParsing
if ($response.Content -isnot [byte[]]) {
throw "Expected a byte-array legacy response, got $($response.Content.GetType().FullName)"
}

# setup-vp evaluates downloaded text in a script block, with no sibling legacy file.
# A child process also keeps installer exit calls from bypassing server cleanup.
$powershell = (Get-Process -Id $PID).Path
& $powershell -NoProfile -Command '& ([scriptblock]::Create((irm -TimeoutSec 15 $env:VP_TEST_INSTALLER_URL)))'
if ($LASTEXITCODE -ne 0) { throw "Remote install failed with exit code $LASTEXITCODE" }

# One request above checks the response type; another must come from the installer.
$requests = @(Select-String -LiteralPath $stderr -Pattern 'GET /install-legacy.bin ' -SimpleMatch)
if ($requests.Count -ne 2) { throw 'The installer did not fetch the remote legacy script exactly once' }

$vp = Join-Path $env:VP_HOME 'bin/vp.exe'
$version = & $vp --version
if ($LASTEXITCODE -ne 0 -or $version -notcontains "vp v$env:VP_VERSION") {
throw "Expected the installed vp to report version $env:VP_VERSION, got: $version"
}
Write-Host ($version -join [Environment]::NewLine)
& $vp env run --node 24 -- node --version
if ($LASTEXITCODE -ne 0) { throw 'The installed vp could not run Node.js 24' }
} finally {
Stop-Process -Id $server.Id -ErrorAction SilentlyContinue
}
65 changes: 52 additions & 13 deletions .github/workflows/test-standalone-install.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ on:
- 'packages/cli/install.ps1'
- 'packages/cli/install-legacy.sh'
- 'packages/cli/install-legacy.ps1'
- '.github/scripts/test-install-legacy-remote.ps1'
- 'packages/tools/src/install-global-cli.ts'
- 'packages/tools/src/local-npm-registry.ts'
- 'crates/vp_installer/**'
Expand Down Expand Up @@ -283,7 +284,7 @@ jobs:
exit 1
fi
cat "$OUTPUT"
grep -F "Set VP_BIN_DIR, VP_DATA_DIR, and VP_CACHE_DIR together" "$OUTPUT"
grep -F "Set all three variables together: VP_BIN_DIR, VP_DATA_DIR, and VP_CACHE_DIR." "$OUTPUT"

- name: Existing GitHub setup-vp uses legacy layout
run: |
Expand Down Expand Up @@ -555,11 +556,41 @@ jobs:
npm --version
vp env doctor

test-install-ps1-remote-legacy:
name: Test remote legacy install.ps1 (${{ matrix.shell }})
runs-on: windows-latest
permissions:
contents: read
strategy:
fail-fast: false
matrix:
shell: [powershell, pwsh]
env:
# Reproduce the setup-vp install that failed in cloudflare/vinext#3251.
VP_VERSION: '0.2.6'
VP_NODE_MANAGER: 'yes'
GITHUB_ACTION_REPOSITORY: voidzero-dev/setup-vp
steps:
- uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2

- name: Install an old release through an HTTP byte-array response (PowerShell 5.1)
if: matrix.shell == 'powershell'
shell: powershell
run: ./.github/scripts/test-install-legacy-remote.ps1

- name: Install an old release through an HTTP byte-array response (PowerShell 7)
if: matrix.shell == 'pwsh'
shell: pwsh
run: ./.github/scripts/test-install-legacy-remote.ps1

test-install-sh-readonly-config:
name: Test install.sh (readonly shell config)
name: Test legacy install.sh (readonly shell config)
runs-on: ubuntu-latest
permissions:
contents: read
env:
# These output assertions cover install-legacy.sh. Newer binaries run self-setup.
VP_VERSION: '0.2.9'
steps:
- uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2

Expand Down Expand Up @@ -1037,10 +1068,13 @@ jobs:
vp --version

test-install-ps1-release-age:
name: Test install.ps1 (minimum-release-age)
name: Test legacy install.ps1 (minimum-release-age)
runs-on: namespace-profile-windows-4c-8g
permissions:
contents: read
env:
# The legacy script enforces release age; native self-setup uses a local override.
VP_VERSION: '0.2.9'
steps:
- uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2

Expand All @@ -1062,12 +1096,22 @@ jobs:
try {
Set-Content -Path $npmrc -Value "minimum-release-age=10000000"

$output = & powershell -NoProfile -ExecutionPolicy Bypass -File .\packages\cli\install.ps1 2>&1
$exitCode = $LASTEXITCODE
$text = $output -join "`n"
# PowerShell 5.1 treats redirected native stderr as an error under Stop.
# Capture each stream in a file so the assertions can inspect the failure.
$stdout = Join-Path $env:RUNNER_TEMP "vp-release-age.stdout.txt"
$stderr = Join-Path $env:RUNNER_TEMP "vp-release-age.stderr.txt"
$installer = (Resolve-Path ./packages/cli/install.ps1).Path
$process = Start-Process -FilePath (Get-Command powershell).Source `
-ArgumentList @("-NoProfile", "-ExecutionPolicy", "Bypass", "-File", "`"$installer`"") `
-RedirectStandardOutput $stdout -RedirectStandardError $stderr `
-Wait -PassThru
$text = @(
Get-Content -LiteralPath $stdout -Raw
Get-Content -LiteralPath $stderr -Raw
) -join [Environment]::NewLine
Write-Host $text

if ($exitCode -eq 0) {
if ($process.ExitCode -eq 0) {
Write-Error "Expected install.ps1 to fail when pnpm minimum-release-age blocks vite-plus"
exit 1
}
Expand Down Expand Up @@ -1102,11 +1146,6 @@ jobs:
Write-Error "Non-interactive install must not write minimum-release-age overrides"
exit 1
}

# The child install.ps1 is expected to fail in this test. Reset the
# native command exit code so the GitHub Actions PowerShell wrapper
# does not fail the step after our assertions pass.
$global:LASTEXITCODE = 0
} finally {
Remove-Item -Path $npmrc -Force -ErrorAction SilentlyContinue
if (Test-Path $backup) {
Expand Down Expand Up @@ -1463,7 +1502,7 @@ jobs:
if ($process.ExitCode -ne 1) {
throw "install.ps1 exited with $($process.ExitCode), expected 1"
}
if (-not $text.Contains("Set VP_BIN_DIR, VP_DATA_DIR, and VP_CACHE_DIR together")) {
if (-not $text.Contains("Set all three variables together: VP_BIN_DIR, VP_DATA_DIR, and VP_CACHE_DIR.")) {
throw "install.ps1 did not report the incomplete override group"
}

Expand Down
3 changes: 2 additions & 1 deletion packages/cli/install.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,8 @@ function Invoke-LegacyInstaller {
. $legacyScript -BinarySource $BinarySource -ResolvedVersion $ViteVersion -PreviewRef $PrVersion
} else {
$response = Invoke-WebRequest -Uri $LegacyInstallerUrl -UseBasicParsing
. ([scriptblock]::Create($response.Content)) -BinarySource $BinarySource -ResolvedVersion $ViteVersion -PreviewRef $PrVersion
$content = if ($response.Content -is [byte[]]) { [Text.Encoding]::UTF8.GetString($response.Content) } else { $response.Content }
. ([scriptblock]::Create($content)) -BinarySource $BinarySource -ResolvedVersion $ViteVersion -PreviewRef $PrVersion
}
# A child script's exit only returns to this bootstrap, so forward its failure.
if ($LASTEXITCODE -ne 0) {
Expand Down
Loading