Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
761c018
feat(global-cli): add monorepo release workflow with publish safety c…
ubugeeei Mar 28, 2026
a349b94
refactor
ubugeeei Mar 28, 2026
d8eaa3e
test: more conventional commit perser tests
ubugeeei Mar 28, 2026
67ce477
refactor: first publishing guidance template
ubugeeei Mar 28, 2026
5dea9c1
more docs
ubugeeei Mar 28, 2026
893c13c
remove tokio
ubugeeei Mar 28, 2026
49059a2
refactor
ubugeeei Mar 28, 2026
9740861
refactor
ubugeeei Mar 28, 2026
3a19d97
refactor
ubugeeei Mar 28, 2026
c98638c
refactor
ubugeeei Mar 28, 2026
0012d63
feat(release): harden vp release flow
ubugeeei Mar 28, 2026
b1825fd
fix(release): keep repo manifests unchanged
ubugeeei Mar 28, 2026
9c8958b
fix(release): restore CI buildability
ubugeeei Mar 28, 2026
96b7a72
fix(release): resolve remaining compile errors
ubugeeei Mar 28, 2026
237f99d
fix(release): use standard success exit statuses
ubugeeei Mar 28, 2026
5f2ccbe
fix(release): drop unused runner helper
ubugeeei Mar 28, 2026
0b024e9
fix(release): handle invalid tags in tests
ubugeeei Mar 28, 2026
4f9d904
test(versioning): align invalid patch expectation
ubugeeei Mar 28, 2026
59eea23
fix(release): keep publish workflow template parseable
ubugeeei Mar 28, 2026
2842c5a
chore(global): drop checked-in binaries
ubugeeei Mar 28, 2026
f16ccf5
fix ci
ubugeeei Mar 29, 2026
3cdf87e
fix ci
ubugeeei Mar 29, 2026
4f2b6b3
fix ci
ubugeeei Apr 20, 2026
87d3f06
fix vp release tagging and verification
ubugeeei Mar 30, 2026
a9ac445
fix ci
ubugeeei Mar 30, 2026
3d3b8a7
fix: align rolldown workspace deps
ubugeeei Mar 31, 2026
b8736f4
fix: stabilize windows script test and fixture format
ubugeeei Mar 31, 2026
d8cd75e
test: isolate env exec runtime cache
ubugeeei Mar 31, 2026
6cd853c
docs(release): add release guide and RFC
ubugeeei Apr 3, 2026
bba52c0
chore(release): use checkout v6 in publish template
ubugeeei Apr 3, 2026
99222ff
chore(release): defer node version to project config
ubugeeei Apr 3, 2026
3a11fc5
docs(readme): shorten top-level command summaries
ubugeeei Apr 3, 2026
d351f72
docs(readme): limit README changes to vp release
ubugeeei Apr 3, 2026
0502af3
docs(readme): shorten release summary
ubugeeei Apr 3, 2026
17b908d
feat(release): confirm custom prerelease channels
ubugeeei Apr 3, 2026
9aba7af
fix(release): expose prerelease helpers to tests
ubugeeei Apr 4, 2026
9e01a55
docs(rfc): clarify release config source
ubugeeei Apr 9, 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
4 changes: 3 additions & 1 deletion Cargo.lock

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

2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Vite+ is the unified entry point for local web development. It combines [Vite](h
- **`vp build`:** Build applications for production with Vite + Rolldown
- **`vp run`:** Execute monorepo tasks with caching and dependency-aware scheduling
- **`vp pack`:** Build libraries for npm publishing or standalone app binaries
- **`vp release`:** Publish workspace releases
- **`vp create` / `vp migrate`:** Scaffold new projects and migrate existing ones

All of this is configured from your project root and works across Vite's framework ecosystem.
Expand Down Expand Up @@ -120,6 +121,7 @@ Use `vp migrate` to migrate to Vite+. It merges tool-specific config files such

- **build** - Build for production
- **pack** - Build libraries
- **release** - Publish workspace releases
- **preview** - Preview production build

#### Manage Dependencies
Expand Down
2 changes: 2 additions & 0 deletions crates/vite_global_cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ tracing = { workspace = true }
owo-colors = { workspace = true }
oxc_resolver = { workspace = true }
crossterm = { workspace = true }
glob = { workspace = true }
petgraph = { workspace = true }
vite_error = { workspace = true }
vite_install = { workspace = true }
vite_js_runtime = { workspace = true }
Expand Down
107 changes: 107 additions & 0 deletions crates/vite_global_cli/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -613,6 +613,74 @@ pub enum Commands {
args: Vec<String>,
},

/// Version workspace packages locally, then publish them from trusted-publishing CI with readiness checks and optional changelog generation
Release {
/// Preview the release plan without changing files or publishing
#[arg(long)]
dry_run: bool,

/// During dry-runs, omit publish simulation and show only versioning/changelog actions
#[arg(long)]
skip_publish: bool,

/// Treat this release as the first one and ignore existing release tags
#[arg(long)]
first_release: bool,

/// Generate root and per-package changelogs
#[arg(long, overrides_with = "no_changelog")]
changelog: bool,

/// Skip changelog generation
#[arg(long, overrides_with = "changelog")]
no_changelog: bool,

/// Override the computed release version. Useful when retrying a partial publish.
#[arg(long, value_name = "VERSION")]
version: Option<String>,

/// Publish a prerelease using the provided identifier (for example: alpha, beta, rc)
#[arg(long, value_name = "TAG")]
preid: Option<String>,

/// Legacy TOTP code for npm 2FA publish flows. Prefer trusted publishing or passkey/security-key auth when possible.
#[arg(long, value_name = "OTP")]
otp: Option<String>,

/// Release only matching workspace packages. When multiple values are provided,
/// their order is used as a tie-breaker between independent packages.
#[arg(long, value_name = "PATTERN", value_delimiter = ',')]
projects: Option<Vec<String>>,

/// Create git tags for released packages
#[arg(long, overrides_with = "no_git_tag")]
git_tag: bool,

/// Skip git tag creation in preview mode
#[arg(long, overrides_with = "git_tag")]
no_git_tag: bool,

/// Create a git commit for release changes
#[arg(long, overrides_with = "no_git_commit")]
git_commit: bool,

/// Skip the release commit
#[arg(long, overrides_with = "git_commit")]
no_git_commit: bool,

/// Run detected release checks before publishing. Real releases do this by default.
#[arg(long, overrides_with = "no_run_checks")]
run_checks: bool,

/// Skip release checks before publishing
#[arg(long, overrides_with = "run_checks")]
no_run_checks: bool,

/// Skip the final confirmation prompt
#[arg(long, short = 'y', alias = "force")]
yes: bool,
},

/// Run tasks
#[command(disable_help_flag = true)]
Run {
Expand Down Expand Up @@ -2032,6 +2100,45 @@ pub async fn run_command_with_options(
commands::delegate::execute(cwd, "pack", &args).await
}

Commands::Release {
dry_run,
skip_publish,
first_release,
changelog,
no_changelog,
version,
preid,
otp,
projects,
git_tag: _,
no_git_tag,
git_commit: _,
no_git_commit,
run_checks,
no_run_checks,
yes,
} => {
let run_checks = if dry_run { run_checks } else { !no_run_checks || run_checks };
commands::release::execute(
cwd,
commands::release::ReleaseOptions {
dry_run,
skip_publish,
first_release,
changelog: changelog && !no_changelog,
version,
preid,
otp,
projects,
git_tag: !no_git_tag,
git_commit: !no_git_commit,
run_checks,
yes,
},
)
.await
}

Commands::Run { args } => {
if help::maybe_print_unified_delegate_help("run", &args, render_options.show_header) {
return Ok(ExitStatus::default());
Expand Down
6 changes: 6 additions & 0 deletions crates/vite_global_cli/src/command_picker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,12 @@ const COMMANDS: &[CommandEntry] = &[
append_help: false,
},
CommandEntry { label: "pack", command: "pack", summary: "Build library.", append_help: false },
CommandEntry {
label: "release",
command: "release",
summary: "Version and publish workspace packages with readiness checks, confirmation, and optional changelog generation.",
append_help: false,
},
CommandEntry {
label: "preview",
command: "preview",
Expand Down
36 changes: 35 additions & 1 deletion crates/vite_global_cli/src/commands/env/exec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,10 +193,43 @@ fn exit_status(code: i32) -> ExitStatus {

#[cfg(test)]
mod tests {
use std::ffi::OsString;

use serial_test::serial;
use tempfile::TempDir;

use super::*;

struct VpHomeGuard {
original_vp_home: Option<OsString>,
_temp_dir: TempDir,
}

impl VpHomeGuard {
fn new() -> Self {
let temp_dir = TempDir::new().unwrap();
let original_vp_home = std::env::var_os(env_vars::VP_HOME);
// SAFETY: This test helper is only used from serial tests and restores the
// process-global environment before dropping.
unsafe {
std::env::set_var(env_vars::VP_HOME, temp_dir.path());
}
Self { original_vp_home, _temp_dir: temp_dir }
}
}

impl Drop for VpHomeGuard {
fn drop(&mut self) {
// SAFETY: We restore the original process-global environment captured in new().
unsafe {
match &self.original_vp_home {
Some(value) => std::env::set_var(env_vars::VP_HOME, value),
None => std::env::remove_var(env_vars::VP_HOME),
}
}
}
}

#[tokio::test]
async fn test_execute_missing_command() {
let result = execute(Some("20.18.0"), None, &[]).await;
Expand All @@ -208,10 +241,11 @@ mod tests {
#[tokio::test]
#[serial]
async fn test_execute_node_version() {
let _guard = VpHomeGuard::new();
// Run 'node --version' with a specific Node.js version
let command = vec!["node".to_string(), "--version".to_string()];
let result = execute(Some("20.18.0"), None, &command).await;
assert!(result.is_ok());
assert!(result.is_ok(), "{result:?}");
let status = result.unwrap();
assert!(status.success());
}
Expand Down
1 change: 1 addition & 0 deletions crates/vite_global_cli/src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ pub mod install;
pub mod link;
pub mod outdated;
pub mod pm;
pub mod release;
pub mod remove;
pub mod unlink;
pub mod update;
Expand Down
1 change: 1 addition & 0 deletions crates/vite_global_cli/src/commands/pm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ pub async fn execute_pm_subcommand(
tag: tag.as_deref(),
access: access.as_deref(),
otp: otp.as_deref(),
provenance: None,
no_git_checks,
publish_branch: publish_branch.as_deref(),
report_summary,
Expand Down
Loading
Loading