Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
c8a4af6
feat(installer): add standalone Windows .exe installer (vp-setup.exe)
fengmk2 Apr 4, 2026
6b4200d
refactor(installer): simplify code after review
fengmk2 Apr 4, 2026
c562ab0
style: apply formatting fixes from vp check --fix
fengmk2 Apr 4, 2026
e5f2fc3
feat(installer): implement remaining RFC gaps
fengmk2 Apr 4, 2026
d5bdac2
fix(build): remove unused junction dependency from vite_global_cli
fengmk2 Apr 4, 2026
974cf12
docs(rfc): restructure Installation Flow with visual diagram
fengmk2 Apr 4, 2026
ba29a0d
fix(rfc): remove garbled Unicode characters in ASCII diagram
fengmk2 Apr 4, 2026
ef1b30e
docs(rfc): sync RFC with implementation
fengmk2 Apr 4, 2026
1898d38
refactor(installer): replace raw FFI with winreg crate for registry a…
fengmk2 Apr 4, 2026
ead7a8a
refactor(installer): minor cleanup from code review
fengmk2 Apr 4, 2026
d27f56f
fix(installer): address Codex review findings
fengmk2 Apr 4, 2026
b0a864d
refactor(installer): address simplify review findings
fengmk2 Apr 4, 2026
617e63e
refactor(installer): pre-compute Node.js manager decision before menu
fengmk2 Apr 4, 2026
bdf01e2
fix(installer): match install.ps1 Node.js manager default for interac…
fengmk2 Apr 4, 2026
54e3701
fix(ci): fix test-vp-setup-exe workflow syntax error
fengmk2 Apr 4, 2026
530c474
docs(rfc): sync RFC with latest implementation changes
fengmk2 Apr 4, 2026
3000abd
refactor(setup): move create_env_files from vite_installer to vite_setup
fengmk2 Apr 4, 2026
b4ab395
fix(build): remove unused tracing dependency from vite_installer
fengmk2 Apr 4, 2026
332ca31
fix(ci): add clone step to test-vp-setup-exe for workspace resolution
fengmk2 Apr 4, 2026
a518d50
fix(build): fix rustfmt blank line in upgrade_check.rs imports
fengmk2 Apr 4, 2026
33a4578
perf(ci): add Dev Drive setup to test-vp-setup-exe for faster Windows…
fengmk2 Apr 4, 2026
26c3671
fix(installer): update documentation URL to viteplus.dev/guide/
fengmk2 Apr 4, 2026
ba39ecb
fix(installer): update outdated comment to reference auto_detect_node…
fengmk2 Apr 4, 2026
19c3e24
chore: remove unnecessary comment in cli.rs
fengmk2 Apr 4, 2026
e415d43
feat(installer): auto-detect CI environment to skip interactive prompts
fengmk2 Apr 4, 2026
61d53a0
chore: remove unnecessary -y flag from CI (auto-detected)
fengmk2 Apr 4, 2026
75433ab
fix(ci): add flate to typos allowlist (flate2 crate name)
fengmk2 Apr 4, 2026
aa5c306
docs(rfc): clarify minimum Windows version with release date
fengmk2 Apr 4, 2026
d080c55
docs(rfc): add link to Rust platform support page for Windows target …
fengmk2 Apr 4, 2026
356be0d
docs: add vp-setup.exe as Windows installation option
fengmk2 Apr 4, 2026
05d5b1c
docs: improve vp-setup.exe installation wording
fengmk2 Apr 4, 2026
f058f86
docs: tweak vp-setup.exe wording
fengmk2 Apr 4, 2026
8e5e87b
docs: simplify vp-setup.exe installation line
fengmk2 Apr 4, 2026
deef407
docs: move link from vp-setup.exe to 'latest release'
fengmk2 Apr 4, 2026
ec79df1
refactor: extract VP_BINARY_NAME const and fix review findings
fengmk2 Apr 4, 2026
5b52a25
fix(installer): pause before closing in interactive mode
fengmk2 Apr 5, 2026
1d3e4a1
fix(installer): remove misleading quotes from version input prompt
fengmk2 Apr 5, 2026
a87b42c
docs: add SmartScreen warning guide for vp-setup.exe download
fengmk2 Apr 5, 2026
a8c95ab
docs: use vp-setup.exe in SmartScreen warning text
fengmk2 Apr 5, 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 @@ -626,3 +628,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) }}

Check notice

Code scanning / zizmor

code injection via template expansion Note test

code injection via template expansion
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 = "eb746ad3f35bd994ddb39be001eaf58986f48388" }
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 = "eb746ad3f35bd994ddb39be001eaf58986f48388" }
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