Skip to content

refactor: extract check command into its own module #535

refactor: extract check command into its own module

refactor: extract check command into its own module #535

name: Test Standalone Install Scripts
permissions: {}
on:
workflow_dispatch:
pull_request:
paths:
- 'packages/cli/install.sh'
- 'packages/cli/install.ps1'
- 'crates/vite_installer/**'
- 'crates/vite_setup/**'
- '.github/workflows/test-standalone-install.yml'
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}
cancel-in-progress: true
defaults:
run:
shell: bash
env:
VP_VERSION: alpha
jobs:
test-install-sh:
name: Test install.sh (${{ matrix.name }})
runs-on: ${{ matrix.os }}
permissions:
contents: read
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
name: Linux x64 glibc
- os: macos-15-intel
name: macOS x64
- os: macos-latest
name: macOS ARM64
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Run install.sh
run: cat packages/cli/install.sh | bash
- name: Verify installation
working-directory: ${{ runner.temp }}
run: |
# Source shell config to get PATH updated
if [ -f ~/.zshenv ]; then
# non-interactive shells use zshenv
source ~/.zshenv
elif [ -f ~/.zshrc ]; then
# interactive shells use zshrc
source ~/.zshrc
elif [ -f ~/.bash_profile ]; then
# non-interactive shells use bash_profile
source ~/.bash_profile
elif [ -f ~/.bashrc ]; then
# interactive shells use bashrc
source ~/.bashrc
else
export PATH="$HOME/.vite-plus/bin:$PATH"
fi
echo "PATH: $PATH"
ls -al ~/
vp --version
vp --help
# test create command
vp create vite --no-interactive --no-agent -- hello --no-interactive -t vanilla
cd hello && vp run build && vp --version
- name: Set PATH
shell: bash
run: |
echo "$HOME/.vite-plus/bin" >> $GITHUB_PATH
- name: Verify bin setup
run: |
# Verify bin directory was created by vp env --setup
BIN_PATH="$HOME/.vite-plus/bin"
ls -al "$BIN_PATH"
if [ ! -d "$BIN_PATH" ]; then
echo "Error: Bin directory not found: $BIN_PATH"
exit 1
fi
# Verify shim executables exist
for shim in node npm npx; do
if [ ! -f "$BIN_PATH/$shim" ]; then
echo "Error: Shim not found: $BIN_PATH/$shim"
exit 1
fi
echo "Found shim: $BIN_PATH/$shim"
done
# Verify vp env doctor works
vp env doctor
vp env run --node 24 -- node -p "process.versions"
which node
which npm
which npx
which vp
- name: Verify upgrade
run: |
# --check queries npm registry and prints update status
vp upgrade --check
vp upgrade 0.1.14-alpha.1
vp --version
# rollback to the previous version (should succeed after a real update)
vp upgrade --rollback
vp --version
test-install-sh-readonly-config:
name: Test install.sh (readonly shell config)
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Make shell config files read-only
run: |
# Simulate Nix-managed or read-only shell configs
touch ~/.bashrc ~/.bash_profile ~/.profile
chmod 444 ~/.bashrc ~/.bash_profile ~/.profile
- name: Run install.sh
run: |
output=$(cat packages/cli/install.sh | bash 2>&1) || {
echo "$output"
echo "Install script exited with non-zero status"
exit 1
}
echo "$output"
# Verify installation succeeds (not a fatal error)
echo "$output" | grep -q "successfully installed"
# Verify fallback message shows binary location
echo "$output" | grep -q "vp was installed to:"
# Verify fallback message shows manual instructions
echo "$output" | grep -q "Or run vp directly:"
# Verify the permission warning was shown
echo "$output" | grep -qi "permission denied"
- name: Verify vp works via direct path
run: |
~/.vite-plus/bin/vp --version
test-install-sh-arm64:
name: Test install.sh (Linux ARM64 glibc via QEMU)
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Set up QEMU
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
with:
platforms: arm64
- name: Run install.sh in ARM64 container
run: |
docker run --rm --platform linux/arm64 \
-v "${{ github.workspace }}:/workspace" \
-e VP_VERSION=alpha \
ubuntu:20.04 bash -c "
ls -al ~/
apt-get update && apt-get install -y curl ca-certificates
cat /workspace/packages/cli/install.sh | bash
if [ -f ~/.profile ]; then
source ~/.profile
elif [ -f ~/.bashrc ]; then
source ~/.bashrc
else
export PATH="$HOME/.vite-plus/bin:$PATH"
fi
vp --version
vp --help
vp dlx print-current-version
# Verify bin setup
BIN_PATH=\"\$HOME/.vite-plus/bin\"
if [ ! -d \"\$BIN_PATH\" ]; then
echo \"Error: Bin directory not found: \$BIN_PATH\"
exit 1
fi
for shim in node npm npx; do
if [ ! -f \"\$BIN_PATH/\$shim\" ]; then
echo \"Error: Shim not found: \$BIN_PATH/\$shim\"
exit 1
fi
echo \"Found shim: \$BIN_PATH/\$shim\"
done
vp env doctor
export VITE_LOG=trace
vp env run --node 24 -- node -p \"process.versions\"
# Verify upgrade
vp upgrade --check
vp upgrade 0.1.14-alpha.1
vp --version
vp upgrade --rollback
vp --version
# FIXME: qemu: uncaught target signal 11 (Segmentation fault) - core dumped
# vp create vite --no-interactive --no-agent -- hello --no-interactive -t vanilla
# cd hello && vp run build
"
test-install-sh-musl-x64:
name: Test install.sh (Linux x64 musl)
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Run install.sh in Alpine container
run: |
docker run --rm \
-v "${{ github.workspace }}:/workspace" \
-e VP_VERSION=alpha \
-e CI=true \
alpine:3.21 sh -c "
# libstdc++: required by unofficial-builds Node.js musl binary
apk add --no-cache bash curl ca-certificates libstdc++
cat /workspace/packages/cli/install.sh | bash
export PATH=\"\$HOME/.vite-plus/bin:\$PATH\"
vp --version
vp --help
vp dlx print-current-version
# Verify bin setup
BIN_PATH=\"\$HOME/.vite-plus/bin\"
if [ ! -d \"\$BIN_PATH\" ]; then
echo \"Error: Bin directory not found: \$BIN_PATH\"
exit 1
fi
for shim in node npm npx; do
if [ ! -f \"\$BIN_PATH/\$shim\" ]; then
echo \"Error: Shim not found: \$BIN_PATH/\$shim\"
exit 1
fi
echo \"Found shim: \$BIN_PATH/\$shim\"
done
vp env doctor
vp env run --node 24 -- node -p \"process.versions\"
# Test create command
vp create vite --no-interactive --no-agent -- hello --no-interactive -t vanilla
cd hello && vp run build && vp --version
cd ..
# Verify upgrade
vp upgrade --check
vp upgrade 0.1.14-alpha.1
vp --version
vp upgrade --rollback
vp --version
"
test-install-sh-musl-arm64:
name: Test install.sh (Linux ARM64 musl via QEMU)
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Set up QEMU
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
with:
platforms: arm64
- name: Run install.sh in ARM64 Alpine container
run: |
docker run --rm --platform linux/arm64 \
-v "${{ github.workspace }}:/workspace" \
-e VP_VERSION=alpha \
-e CI=true \
alpine:3.21 sh -c "
# libstdc++ is needed by unofficial-builds Node.js musl binary
apk add --no-cache bash curl ca-certificates libstdc++
cat /workspace/packages/cli/install.sh | bash
export PATH=\"\$HOME/.vite-plus/bin:\$PATH\"
vp --version
vp --help
vp dlx print-current-version
# Verify bin setup
BIN_PATH=\"\$HOME/.vite-plus/bin\"
if [ ! -d \"\$BIN_PATH\" ]; then
echo \"Error: Bin directory not found: \$BIN_PATH\"
exit 1
fi
for shim in node npm npx; do
if [ ! -f \"\$BIN_PATH/\$shim\" ]; then
echo \"Error: Shim not found: \$BIN_PATH/\$shim\"
exit 1
fi
echo \"Found shim: \$BIN_PATH/\$shim\"
done
vp env doctor
export VITE_LOG=trace
vp env run --node 24 -- node -p \"process.versions\"
# FIXME: QEMU doesn't support all syscalls needed by rolldown/tsdown
# vp create vite --no-interactive --no-agent -- hello --no-interactive -t vanilla
# cd hello && vp run build && vp --version
# Verify upgrade
vp upgrade --check
vp upgrade 0.1.14-alpha.1
vp --version
vp upgrade --rollback
vp --version
"
test-install-ps1-v5:
name: Test install.ps1 (Windows x64, PowerShell 5.1)
runs-on: windows-latest
permissions:
contents: read
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Assert PowerShell 5.x
shell: powershell
run: |
Write-Host "PowerShell version: $($PSVersionTable.PSVersion)"
if ($PSVersionTable.PSVersion.Major -ne 5) {
Write-Error "Expected PowerShell 5.x but got $($PSVersionTable.PSVersion)"
exit 1
}
- name: Run install.ps1
shell: powershell
run: |
& ./packages/cli/install.ps1
- name: Run install.ps1 via irm simulation (catches BOM issues)
shell: powershell
run: |
$ErrorActionPreference = "Stop"
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: powershell
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: powershell
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: powershell
run: |
vp upgrade --check
vp upgrade 0.1.14-alpha.1
vp --version
vp upgrade --rollback
vp --version
test-install-ps1-arm64:
name: Test install.ps1 (Windows ARM64)
runs-on: windows-11-arm
permissions:
contents: read
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Run install.ps1
shell: pwsh
run: |
& ./packages/cli/install.ps1
- 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-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-release-age:
name: Test install.ps1 (minimum-release-age)
runs-on: windows-latest
permissions:
contents: read
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Verify minimumReleaseAge blocks non-interactive install
shell: powershell
run: |
$ErrorActionPreference = "Stop"
$env:CI = "true"
$env:VP_NODE_MANAGER = "no"
$env:VP_HOME = Join-Path $env:RUNNER_TEMP "vite-plus-release-age"
$npmrc = Join-Path $env:USERPROFILE ".npmrc"
$backup = Join-Path $env:RUNNER_TEMP ".npmrc.backup"
if (Test-Path $npmrc) {
Move-Item -Path $npmrc -Destination $backup -Force
}
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"
Write-Host $text
if ($exitCode -eq 0) {
Write-Error "Expected install.ps1 to fail when pnpm minimum-release-age blocks vite-plus"
exit 1
}
if ($text -notmatch "Install blocked by your minimumReleaseAge setting") {
Write-Error "Expected release-age block message in installer output"
exit 1
}
if ($text -notmatch "ERR_PNPM_NO_MATURE_MATCHING_VERSION|minimumReleaseAge") {
Write-Error "Expected pnpm release-age details in installer output"
exit 1
}
$installLog = Get-ChildItem -Path $env:VP_HOME -Recurse -Filter install.log | Select-Object -First 1
if (-not $installLog) {
Write-Error "Expected install.log to be written under VP_HOME"
exit 1
}
$logText = Get-Content -Path $installLog.FullName -Raw
if ($logText -notmatch "ERR_PNPM_NO_MATURE_MATCHING_VERSION|minimumReleaseAge") {
Write-Error "Expected pnpm release-age details in install.log"
exit 1
}
$overrideFiles = Get-ChildItem -Path $env:VP_HOME -Recurse -Force -Filter .npmrc |
Where-Object { $_.FullName -notmatch "\\js_runtime\\" }
if ($overrideFiles) {
Write-Host "Unexpected override files:"
$overrideFiles | ForEach-Object { Write-Host $_.FullName }
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) {
Move-Item -Path $backup -Destination $npmrc -Force
}
}
test-install-ps1:
name: Test install.ps1 (Windows x64)
runs-on: windows-latest
permissions:
contents: read
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Run install.ps1
shell: pwsh
run: |
& ./packages/cli/install.ps1
- name: Set PATH
shell: bash
run: |
echo "$USERPROFILE\.vite-plus\bin" >> $GITHUB_PATH
- name: Verify upgrade
shell: pwsh
run: |
# --check queries npm registry and prints update status
vp upgrade --check
vp upgrade 0.1.14-alpha.1
vp --version
# rollback to the previous version (should succeed after a real update)
vp upgrade --rollback
vp --version
- name: Verify installation on powershell
shell: pwsh
working-directory: ${{ runner.temp }}
run: |
# Print PATH from environment
echo "PATH: $env:Path"
vp --version
vp --help
# $env:VITE_LOG = "trace"
# test create command
vp create vite --no-interactive --no-agent -- hello --no-interactive -t vanilla
cd hello && vp run build && vp --version
- name: Verify bin setup on powershell
shell: pwsh
run: |
# Verify bin directory was created by vp env --setup
$binPath = "$env:USERPROFILE\.vite-plus\bin"
Get-ChildItem -Force $binPath
if (-not (Test-Path $binPath)) {
Write-Error "Bin directory not found: $binPath"
exit 1
}
# Verify shim executables exist (trampoline .exe files on Windows)
$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
# Verify vp env doctor works
$env:Path = "$env:USERPROFILE\.vite-plus\bin;$env:Path"
vp env doctor
vp env run --node 24 -- node -p "process.versions"
- name: Verify installation on cmd
shell: cmd
working-directory: ${{ runner.temp }}
run: |
echo PATH: %PATH%
dir "%USERPROFILE%\.vite-plus"
dir "%USERPROFILE%\.vite-plus\bin"
REM test create command
vp create vite --no-interactive --no-agent -- hello-cmd --no-interactive -t vanilla
cd hello-cmd && vp run build && vp --version
- name: Verify bin setup on cmd
shell: cmd
run: |
REM Verify bin directory was created by vp env --setup
set "BIN_PATH=%USERPROFILE%\.vite-plus\bin"
dir "%BIN_PATH%"
REM Verify shim executables exist (Windows uses trampoline .exe files)
for %%s in (node.exe npm.exe npx.exe vp.exe) do (
if not exist "%BIN_PATH%\%%s" (
echo Error: Shim not found: %BIN_PATH%\%%s
exit /b 1
)
echo Found shim: %BIN_PATH%\%%s
)
where node
where npm
where npx
where vp
REM Verify vp env doctor works
vp env doctor
vp env run --node 24 -- node -p "process.versions"
- name: Verify installation on bash
shell: bash
working-directory: ${{ runner.temp }}
run: |
echo "PATH: $PATH"
ls -al ~/.vite-plus
ls -al ~/.vite-plus/bin
vp --version
vp --help
# test create command
vp create vite --no-interactive --no-agent -- hello-bash --no-interactive -t vanilla
cd hello-bash && vp run build && vp --version
- name: Verify bin setup on bash
shell: bash
run: |
# Verify bin directory was created by vp env --setup
BIN_PATH="$HOME/.vite-plus/bin"
ls -al "$BIN_PATH"
if [ ! -d "$BIN_PATH" ]; then
echo "Error: Bin directory not found: $BIN_PATH"
exit 1
fi
# Verify trampoline .exe files exist
for shim in node.exe npm.exe npx.exe vp.exe; do
if [ ! -f "$BIN_PATH/$shim" ]; then
echo "Error: Trampoline shim not found: $BIN_PATH/$shim"
exit 1
fi
echo "Found trampoline shim: $BIN_PATH/$shim"
done
# Verify vp env doctor works
vp env doctor
vp env run --node 24 -- node -p "process.versions"
which node
which npm
which npx
which vp
test-vp-setup-exe:
name: Test vp-setup.exe (pwsh)
runs-on: windows-latest
permissions:
contents: read
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: ./.github/actions/clone
- name: Setup Dev Drive
uses: samypr100/setup-dev-drive@30f0f98ae5636b2b6501e181dfb3631b9974818d # v4.0.0
with:
drive-size: 12GB
drive-format: ReFS
env-mapping: |
CARGO_HOME,{{ DEV_DRIVE }}/.cargo
RUSTUP_HOME,{{ DEV_DRIVE }}/.rustup
- uses: oxc-project/setup-rust@23f38cfb0c04af97a055f76acee94d5be71c7c82 # v1.0.16
with:
target-dir: ${{ format('{0}/target', env.DEV_DRIVE) }}
- name: Build vp-setup.exe
shell: bash
run: cargo build --release -p vite_installer
- name: Install via vp-setup.exe (silent)
shell: pwsh
run: ${{ format('{0}/target/release/vp-setup.exe', env.DEV_DRIVE) }}
env:
VP_VERSION: alpha
- name: Set PATH
shell: bash
run: echo "$USERPROFILE/.vite-plus/bin" >> $GITHUB_PATH
- name: Verify installation
shell: pwsh
run: |
vp --version
vp --help
- name: Verify installation (cmd)
shell: cmd
run: |
vp --version
vp --help
- name: Verify installation (bash)
shell: bash
run: |
vp --version
vp --help