Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
46cec6a
feat(installer): add standalone Windows .exe installer (vp-setup.exe)
fengmk2 Apr 4, 2026
b5b5a0f
refactor(installer): simplify code after review
fengmk2 Apr 4, 2026
dcb6275
style: apply formatting fixes from vp check --fix
fengmk2 Apr 4, 2026
bb8465b
feat(installer): implement remaining RFC gaps
fengmk2 Apr 4, 2026
6e91be7
fix(build): remove unused junction dependency from vite_global_cli
fengmk2 Apr 4, 2026
281ceb8
docs(rfc): restructure Installation Flow with visual diagram
fengmk2 Apr 4, 2026
7c7208e
fix(rfc): remove garbled Unicode characters in ASCII diagram
fengmk2 Apr 4, 2026
51d6081
docs(rfc): sync RFC with implementation
fengmk2 Apr 4, 2026
c685d37
refactor(installer): replace raw FFI with winreg crate for registry a…
fengmk2 Apr 4, 2026
322c17b
refactor(installer): minor cleanup from code review
fengmk2 Apr 4, 2026
cdfb8b9
fix(installer): address Codex review findings
fengmk2 Apr 4, 2026
ee94e3c
refactor(installer): address simplify review findings
fengmk2 Apr 4, 2026
79b3c48
refactor(installer): pre-compute Node.js manager decision before menu
fengmk2 Apr 4, 2026
59e8e04
fix(installer): match install.ps1 Node.js manager default for interac…
fengmk2 Apr 4, 2026
aa6de53
fix(ci): fix test-vp-setup-exe workflow syntax error
fengmk2 Apr 4, 2026
6883c8d
docs(rfc): sync RFC with latest implementation changes
fengmk2 Apr 4, 2026
e6f7130
refactor(setup): move create_env_files from vite_installer to vite_setup
fengmk2 Apr 4, 2026
1ee3110
fix(build): remove unused tracing dependency from vite_installer
fengmk2 Apr 4, 2026
09941c9
fix(ci): add clone step to test-vp-setup-exe for workspace resolution
fengmk2 Apr 4, 2026
4ea51f8
fix(build): fix rustfmt blank line in upgrade_check.rs imports
fengmk2 Apr 4, 2026
197db64
perf(ci): add Dev Drive setup to test-vp-setup-exe for faster Windows…
fengmk2 Apr 4, 2026
80806a7
fix(installer): update documentation URL to viteplus.dev/guide/
fengmk2 Apr 4, 2026
c3bc418
fix(installer): update outdated comment to reference auto_detect_node…
fengmk2 Apr 4, 2026
176cb67
chore: remove unnecessary comment in cli.rs
fengmk2 Apr 4, 2026
eace8ae
feat(installer): auto-detect CI environment to skip interactive prompts
fengmk2 Apr 4, 2026
14c78f0
chore: remove unnecessary -y flag from CI (auto-detected)
fengmk2 Apr 4, 2026
54cc2c5
fix(ci): add flate to typos allowlist (flate2 crate name)
fengmk2 Apr 4, 2026
14adf23
docs(rfc): clarify minimum Windows version with release date
fengmk2 Apr 4, 2026
82e7763
docs(rfc): add link to Rust platform support page for Windows target …
fengmk2 Apr 4, 2026
9ae7431
docs: add vp-setup.exe as Windows installation option
fengmk2 Apr 4, 2026
ad137d6
docs: improve vp-setup.exe installation wording
fengmk2 Apr 4, 2026
2b61b34
docs: tweak vp-setup.exe wording
fengmk2 Apr 4, 2026
144cb81
docs: simplify vp-setup.exe installation line
fengmk2 Apr 4, 2026
80c041e
docs: move link from vp-setup.exe to 'latest release'
fengmk2 Apr 4, 2026
ad834cb
refactor: extract VP_BINARY_NAME const and fix review findings
fengmk2 Apr 4, 2026
d6a682c
fix(installer): pause before closing in interactive mode
fengmk2 Apr 5, 2026
f6c15ee
fix(installer): remove misleading quotes from version input prompt
fengmk2 Apr 5, 2026
a81f93c
docs: add SmartScreen warning guide for vp-setup.exe download
fengmk2 Apr 5, 2026
aa5dfc2
docs: use vp-setup.exe in SmartScreen warning text
fengmk2 Apr 5, 2026
b619994
fix(installer): propagate VP_HOME to child vp processes
fengmk2 Apr 7, 2026
998d51d
fix(installer): reinstall when current version directory is incomplete
fengmk2 Apr 7, 2026
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
7 changes: 7 additions & 0 deletions .github/actions/build-upstream/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
${{ steps.rust-target.outputs.dir }}/${{ inputs.target }}/release/vp
${{ steps.rust-target.outputs.dir }}/${{ inputs.target }}/release/vp.exe
${{ steps.rust-target.outputs.dir }}/${{ inputs.target }}/release/vp-shim.exe
${{ steps.rust-target.outputs.dir }}/${{ inputs.target }}/release/vp-setup.exe
key: ${{ steps.cache-key.outputs.key }}

# Apply Vite+ branding patches to vite source (CI checks out
Expand Down Expand Up @@ -143,6 +144,11 @@
shell: bash
run: cargo build --release --target ${{ inputs.target }} -p vite_trampoline

- name: Build installer binary (Windows only)
if: steps.cache-restore.outputs.cache-hit != 'true' && contains(inputs.target, 'windows')
shell: bash
run: cargo build --release --target ${{ inputs.target }} -p vite_installer

Check failure

Code scanning / zizmor

code injection via template expansion Error

code injection via template expansion

- name: Save NAPI binding cache
if: steps.cache-restore.outputs.cache-hit != 'true'
uses: actions/cache/save@94b89442628ad1d101e352b7ee38f30e1bef108e # v5
Expand All @@ -156,6 +162,7 @@
${{ steps.rust-target.outputs.dir }}/${{ inputs.target }}/release/vp
${{ steps.rust-target.outputs.dir }}/${{ inputs.target }}/release/vp.exe
${{ steps.rust-target.outputs.dir }}/${{ inputs.target }}/release/vp-shim.exe
${{ steps.rust-target.outputs.dir }}/${{ inputs.target }}/release/vp-setup.exe
key: ${{ steps.cache-key.outputs.key }}

# Build vite-plus TypeScript after native bindings are ready
Expand Down
31 changes: 31 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,14 @@ jobs:
./target/${{ matrix.settings.target }}/release/vp-shim.exe
if-no-files-found: error

- name: Upload installer binary artifact (Windows only)
if: contains(matrix.settings.target, 'windows')
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: vp-setup-${{ matrix.settings.target }}
path: ./target/${{ matrix.settings.target }}/release/vp-setup.exe
if-no-files-found: error

- name: Remove .node files before upload dist
if: ${{ matrix.settings.target == 'x86_64-unknown-linux-gnu' }}
run: |
Expand Down Expand Up @@ -241,6 +249,12 @@ jobs:
path: rust-cli-artifacts
pattern: vite-global-cli-*

- name: Download installer binaries (Windows)
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
path: installer-artifacts
pattern: vp-setup-*

- name: Move Rust CLI binaries to target directories
run: |
# Move each artifact's binary to the correct target directory
Expand All @@ -265,6 +279,19 @@ jobs:
echo "Found binaries:"
echo "$vp_files"

- name: Prepare installer binaries for release
run: |
mkdir -p installer-release
for artifact_dir in installer-artifacts/vp-setup-*/; do
if [ -d "$artifact_dir" ]; then
dir_name=$(basename "$artifact_dir")
target_name=${dir_name#vp-setup-}
cp "$artifact_dir/vp-setup.exe" "installer-release/vp-setup-${target_name}.exe"
fi
done
echo "Installer binaries:"
ls -la installer-release/ || echo "No installer binaries found"

- name: Set npm packages version
run: |
sed -i 's/"version": "0.0.0"/"version": "${{ env.VERSION }}"/' packages/core/package.json
Expand Down Expand Up @@ -318,6 +345,8 @@ jobs:
${INSTALL_PS1}
\`\`\`

Or download and run \`vp-setup.exe\` from the assets below.

View the full commit: https://github.com/${{ github.repository }}/commit/${{ github.sha }}
EOF

Expand All @@ -332,6 +361,8 @@ jobs:
name: vite-plus v${{ env.VERSION }}
tag_name: v${{ env.VERSION }}
target_commitish: ${{ github.sha }}
files: |
installer-release/vp-setup-*.exe

- name: Send Discord notification
if: ${{ inputs.npm_tag == 'latest' }}
Expand Down
56 changes: 56 additions & 0 deletions .github/workflows/test-standalone-install.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
paths:
- 'packages/cli/install.sh'
- 'packages/cli/install.ps1'
- 'crates/vite_installer/**'
- 'crates/vite_setup/**'
- '.github/workflows/test-standalone-install.yml'

concurrency:
Expand Down Expand Up @@ -706,3 +708,57 @@
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

Check notice

Code scanning / zizmor

credential persistence through GitHub Actions artifacts Note test

credential persistence through GitHub Actions artifacts
- 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

Check notice

Code scanning / zizmor

usage of GitHub Actions misfeatures Note test

usage of GitHub Actions misfeatures
run: |
vp --version
vp --help

- name: Verify installation (bash)
shell: bash
run: |
vp --version
vp --help
1 change: 1 addition & 0 deletions .typos.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
ratatui = "ratatui"
PUNICODE = "PUNICODE"
Jod = "Jod" # Node.js v22 LTS codename
flate = "flate" # flate2 crate name (gzip/deflate compression)

[files]
extend-exclude = [
Expand Down
53 changes: 48 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ vite_js_runtime = { path = "crates/vite_js_runtime" }
vite_glob = { git = "https://github.com/voidzero-dev/vite-task.git", rev = "076cef486127e6cd1fefc58945f00dac316888ca" }
vite_install = { path = "crates/vite_install" }
vite_migration = { path = "crates/vite_migration" }
vite_setup = { path = "crates/vite_setup" }
vite_shared = { path = "crates/vite_shared" }
vite_static_config = { path = "crates/vite_static_config" }
vite_path = { git = "https://github.com/voidzero-dev/vite-task.git", rev = "076cef486127e6cd1fefc58945f00dac316888ca" }
Expand All @@ -206,6 +207,7 @@ vite_workspace = { git = "https://github.com/voidzero-dev/vite-task.git", rev =
walkdir = "2.5.0"
wax = "0.6.0"
which = "8.0.0"
winreg = "0.56.0"
xxhash-rust = "0.8.15"
zip = "7.2"

Expand Down Expand Up @@ -334,3 +336,7 @@ panic = "abort" # Let it crash and force ourselves to write safe Rust.
# size instead of speed. This reduces it from ~200KB to ~100KB on Windows.
[profile.release.package.vite_trampoline]
opt-level = "z"

# The installer binary is downloaded by users, so optimize for size.
[profile.release.package.vite_installer]
opt-level = "z"
8 changes: 1 addition & 7 deletions crates/vite_global_cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,13 @@ name = "vp"
path = "src/main.rs"

[dependencies]
base64-simd = { workspace = true }
chrono = { workspace = true }
clap = { workspace = true, features = ["derive"] }
clap_complete = { workspace = true, features = ["unstable-dynamic"] }
directories = { workspace = true }
flate2 = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
node-semver = { workspace = true }
sha2 = { workspace = true }
tar = { workspace = true }
thiserror = { workspace = true }
tokio = { workspace = true, features = ["full"] }
tracing = { workspace = true }
Expand All @@ -34,13 +30,11 @@ vite_install = { workspace = true }
vite_js_runtime = { workspace = true }
vite_path = { workspace = true }
vite_command = { workspace = true }
vite_setup = { workspace = true }
vite_shared = { workspace = true }
vite_str = { workspace = true }
vite_workspace = { workspace = true }

[target.'cfg(windows)'.dependencies]
junction = { workspace = true }

[dev-dependencies]
serial_test = { workspace = true }
tempfile = { workspace = true }
Expand Down
14 changes: 4 additions & 10 deletions crates/vite_global_cli/src/commands/upgrade/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,12 @@
//! Downloads and installs a new version of the CLI from the npm registry
//! with SHA-512 integrity verification.

mod install;
mod integrity;
mod platform;
pub(crate) mod registry;

use std::process::ExitStatus;

use owo_colors::OwoColorize;
use vite_install::request::HttpClient;
use vite_path::AbsolutePathBuf;
use vite_setup::{install, integrity, platform, registry};
use vite_shared::output;

use crate::{commands::env::config::get_vp_home, error::Error};
Expand All @@ -35,9 +31,6 @@ pub struct UpgradeOptions {
pub registry: Option<String>,
}

/// Maximum number of old versions to keep.
const MAX_VERSIONS_KEEP: usize = 5;

/// Execute the upgrade command.
#[allow(clippy::print_stdout, clippy::print_stderr)]
pub async fn execute(options: UpgradeOptions) -> Result<ExitStatus, Error> {
Expand Down Expand Up @@ -154,7 +147,7 @@ async fn install_platform_and_main(
install::extract_platform_package(platform_data, version_dir).await?;

// Verify binary was extracted
let binary_name = if cfg!(windows) { "vp.exe" } else { "vp" };
let binary_name = vite_setup::VP_BINARY_NAME;
let binary_path = version_dir.join("bin").join(binary_name);
if !tokio::fs::try_exists(&binary_path).await.unwrap_or(false) {
return Err(Error::Upgrade(
Expand Down Expand Up @@ -189,7 +182,8 @@ async fn install_platform_and_main(
if let Some(ref prev) = previous_version {
protected.push(prev.as_str());
}
if let Err(e) = install::cleanup_old_versions(install_dir, MAX_VERSIONS_KEEP, &protected).await
if let Err(e) =
install::cleanup_old_versions(install_dir, vite_setup::MAX_VERSIONS_KEEP, &protected).await
{
output::warn(&format!("Old version cleanup failed (non-fatal): {e}"));
}
Expand Down
7 changes: 2 additions & 5 deletions crates/vite_global_cli/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,6 @@ pub enum Error {
#[error("Upgrade error: {0}")]
Upgrade(Str),

#[error("Integrity mismatch: expected {expected}, got {actual}")]
IntegrityMismatch { expected: Str, actual: Str },

#[error("Unsupported integrity format: {0} (only sha512 is supported)")]
UnsupportedIntegrity(Str),
#[error("{0}")]
Setup(#[from] vite_setup::error::Error),
}
3 changes: 1 addition & 2 deletions crates/vite_global_cli/src/upgrade_check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ use std::{

use owo_colors::OwoColorize;
use serde::{Deserialize, Serialize};

use crate::commands::upgrade::registry;
use vite_setup::registry;

const CHECK_INTERVAL_SECS: u64 = 24 * 60 * 60;
const PROMPT_INTERVAL_SECS: u64 = 24 * 60 * 60;
Expand Down
Loading
Loading