Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
91 commits
Select commit Hold shift + click to select a range
92eb8e7
feat(global-cli): add monorepo release workflow with publish safety c…
ubugeeei Mar 28, 2026
650a278
refactor
ubugeeei Mar 28, 2026
013da0a
test: more conventional commit perser tests
ubugeeei Mar 28, 2026
e5e927a
refactor: first publishing guidance template
ubugeeei Mar 28, 2026
ba8f778
more docs
ubugeeei Mar 28, 2026
6af54bb
remove tokio
ubugeeei Mar 28, 2026
4ea6d8b
refactor
ubugeeei Mar 28, 2026
ab737c2
refactor
ubugeeei Mar 28, 2026
a7c8da2
refactor
ubugeeei Mar 28, 2026
ad2b473
refactor
ubugeeei Mar 28, 2026
0ec06d9
feat(release): harden vp release flow
ubugeeei Mar 28, 2026
eb0557b
fix(release): keep repo manifests unchanged
ubugeeei Mar 28, 2026
c61cbe0
fix(release): restore CI buildability
ubugeeei Mar 28, 2026
3e079f6
fix(release): resolve remaining compile errors
ubugeeei Mar 28, 2026
7fb661a
fix(release): use standard success exit statuses
ubugeeei Mar 28, 2026
100eae4
fix(release): drop unused runner helper
ubugeeei Mar 28, 2026
c40d266
fix(release): handle invalid tags in tests
ubugeeei Mar 28, 2026
5045471
test(versioning): align invalid patch expectation
ubugeeei Mar 28, 2026
a02c430
fix(release): keep publish workflow template parseable
ubugeeei Mar 28, 2026
28f157b
chore(global): drop checked-in binaries
ubugeeei Mar 28, 2026
155e4b6
fix ci
ubugeeei Mar 29, 2026
c43ffa0
Merge branch 'main' of github.com:voidzero-dev/vite-plus into feat/pu…
ubugeeei Mar 29, 2026
c3c9209
Merge branch 'main' into feat/publish-support
ubugeeei Mar 29, 2026
fe917e2
fix ci
ubugeeei Mar 29, 2026
982d328
Merge branch 'feat/publish-support' of github.com:voidzero-dev/vite-p…
ubugeeei Mar 29, 2026
3d305ba
fix ci
ubugeeei Mar 29, 2026
6c0dba0
Merge branch 'main' of github.com:voidzero-dev/vite-plus into feat/pu…
ubugeeei Mar 30, 2026
66122e2
fix vp release tagging and verification
ubugeeei Mar 30, 2026
1f1fdb1
fix ci
ubugeeei Mar 30, 2026
39f0ef9
Merge remote-tracking branch 'origin/main' into feat/publish-support
ubugeeei Mar 31, 2026
6bf799a
fix: align rolldown workspace deps
ubugeeei Mar 31, 2026
1c029a1
fix: stabilize windows script test and fixture format
ubugeeei Mar 31, 2026
4c07242
test: isolate env exec runtime cache
ubugeeei Mar 31, 2026
c983d41
Merge branch 'main' into feat/publish-support
ubugeeei Mar 31, 2026
ced4ce5
Merge branch 'main' into feat/publish-support
ubugeeei Mar 31, 2026
54e4fde
Merge branch 'main' into feat/publish-support
ubugeeei Apr 1, 2026
d0c32a7
Merge branch 'main' of github.com:voidzero-dev/vite-plus into feat/pu…
ubugeeei Apr 1, 2026
caff4c1
docs(release): add release guide and RFC
ubugeeei Apr 3, 2026
c922e74
chore(release): use checkout v6 in publish template
ubugeeei Apr 3, 2026
04af78b
chore(release): defer node version to project config
ubugeeei Apr 3, 2026
a571751
docs(readme): shorten top-level command summaries
ubugeeei Apr 3, 2026
2b9fc7b
docs(readme): limit README changes to vp release
ubugeeei Apr 3, 2026
741ae51
docs(readme): shorten release summary
ubugeeei Apr 3, 2026
d5708aa
feat(release): confirm custom prerelease channels
ubugeeei Apr 3, 2026
c8d15ca
fix(release): expose prerelease helpers to tests
ubugeeei Apr 4, 2026
ab37951
Merge branch 'main' into feat/publish-support
ubugeeei Apr 6, 2026
494a017
Merge remote-tracking branch 'origin/main' into feat/publish-support
ubugeeei Apr 6, 2026
3e88d53
feat(global-cli): add monorepo release workflow with publish safety c…
ubugeeei Mar 28, 2026
6d530a3
refactor
ubugeeei Mar 28, 2026
0a2b243
test: more conventional commit perser tests
ubugeeei Mar 28, 2026
e6e39ee
refactor: first publishing guidance template
ubugeeei Mar 28, 2026
869c9d2
more docs
ubugeeei Mar 28, 2026
40d4f68
remove tokio
ubugeeei Mar 28, 2026
8584976
refactor
ubugeeei Mar 28, 2026
e7de9f7
refactor
ubugeeei Mar 28, 2026
4308965
refactor
ubugeeei Mar 28, 2026
9f47629
refactor
ubugeeei Mar 28, 2026
114114f
feat(release): harden vp release flow
ubugeeei Mar 28, 2026
4b7bbc2
fix(release): keep repo manifests unchanged
ubugeeei Mar 28, 2026
6ab94cf
fix(release): restore CI buildability
ubugeeei Mar 28, 2026
6fe6770
fix(release): resolve remaining compile errors
ubugeeei Mar 28, 2026
8b9752a
fix(release): use standard success exit statuses
ubugeeei Mar 28, 2026
e5fb3dc
fix(release): drop unused runner helper
ubugeeei Mar 28, 2026
8ed517e
fix(release): handle invalid tags in tests
ubugeeei Mar 28, 2026
2aaa62b
test(versioning): align invalid patch expectation
ubugeeei Mar 28, 2026
f2a21e4
fix(release): keep publish workflow template parseable
ubugeeei Mar 28, 2026
ebdce82
chore(global): drop checked-in binaries
ubugeeei Mar 28, 2026
c2277ff
fix ci
ubugeeei Mar 29, 2026
70b72d4
fix ci
ubugeeei Mar 29, 2026
78feeb3
fix ci
ubugeeei Apr 20, 2026
85a48aa
fix vp release tagging and verification
ubugeeei Mar 30, 2026
646d49a
fix ci
ubugeeei Mar 30, 2026
17bf303
fix: align rolldown workspace deps
ubugeeei Mar 31, 2026
6f17f5d
fix: stabilize windows script test and fixture format
ubugeeei Mar 31, 2026
d14b79c
test: isolate env exec runtime cache
ubugeeei Mar 31, 2026
3d3fa3b
docs(release): add release guide and RFC
ubugeeei Apr 3, 2026
8200e05
chore(release): use checkout v6 in publish template
ubugeeei Apr 3, 2026
8c3f38e
chore(release): defer node version to project config
ubugeeei Apr 3, 2026
3921a9c
docs(readme): shorten top-level command summaries
ubugeeei Apr 3, 2026
f01c8f3
docs(readme): limit README changes to vp release
ubugeeei Apr 3, 2026
df81bd9
docs(readme): shorten release summary
ubugeeei Apr 3, 2026
d833e57
feat(release): confirm custom prerelease channels
ubugeeei Apr 3, 2026
15485bb
fix(release): expose prerelease helpers to tests
ubugeeei Apr 4, 2026
d13d71e
docs(rfc): clarify release config source
ubugeeei Apr 9, 2026
c2361ab
fix: resolve publish provenance rebase conflict
ubugeeei May 21, 2026
be29811
fix: restore CI after main rebase
ubugeeei May 21, 2026
75b3a7b
fix: satisfy cargo security analysis
ubugeeei May 21, 2026
b2525a6
chore: merge main into publish support
ubugeeei Aug 13, 2026
0a5661b
feat(release): add trusted publishing setup
ubugeeei Aug 13, 2026
8c0d115
fix(release): restore lint compliance after main sync
ubugeeei Aug 13, 2026
5db9cca
chore: reconcile publish support history
ubugeeei Aug 13, 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
2 changes: 2 additions & 0 deletions 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 @@ -23,6 +23,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`:** Run `package.json` scripts and 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 toolchain`:** Show the versions of Vite+, Vite, Rolldown, Oxc, and other tools
- **`vp create` / `vp migrate`:** Scaffold new projects and migrate existing ones

Expand Down Expand Up @@ -126,6 +127,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
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ Build:
build Build for production
pack Build library
preview Preview production build
release Version and publish workspace packages with readiness checks, confirmation, and optional changelog generation

Manage Dependencies:
add Add packages to dependencies
Expand Down
4 changes: 3 additions & 1 deletion crates/vp_global_cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,14 @@ serde_json = { workspace = true }
node-semver = { workspace = true }
thiserror = { workspace = true }
tar = { workspace = true }
tempfile = { workspace = true }
tokio = { workspace = true, features = ["full"] }
tracing = { workspace = true }
owo-colors = { workspace = true }
oxc_resolver = { workspace = true }
crossterm = { workspace = true }
glob = { workspace = true }
petgraph = { workspace = true }
indexmap = { workspace = true }
indicatif = { workspace = true }
vp_error = { workspace = true }
Expand All @@ -45,7 +48,6 @@ uuid = { workspace = true, features = ["v4"] }

[dev-dependencies]
serial_test = { workspace = true }
tempfile = { workspace = true }

[lints]
workspace = true
170 changes: 170 additions & 0 deletions crates/vp_global_cli/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,115 @@ 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>,

/// Configure npm Trusted Publishing for the selected workspace packages, then exit
#[arg(
long,
conflicts_with_all = [
"skip_publish",
"first_release",
"changelog",
"no_changelog",
"version",
"preid",
"otp",
"git_tag",
"no_git_tag",
"git_commit",
"no_git_commit",
"run_checks",
"no_run_checks"
]
)]
setup_trusted_publishing: bool,

/// GitHub repository in owner/repository form (auto-detected from origin by default)
#[arg(long, value_name = "OWNER/REPOSITORY", requires = "setup_trusted_publishing")]
trusted_publisher_repository: Option<String>,

/// GitHub Actions workflow path or filename (auto-detected by default)
#[arg(long, value_name = "FILE", requires = "setup_trusted_publishing")]
trusted_publisher_workflow: Option<String>,

/// Restrict trusted publishing to a GitHub Actions environment
#[arg(long, value_name = "NAME", requires = "setup_trusted_publishing")]
trusted_publisher_environment: Option<String>,

/// Registry passed to npm trust (defaults to the configured npm registry)
#[arg(long, value_name = "URL", requires = "setup_trusted_publishing")]
trusted_publisher_registry: Option<String>,

/// Also permit npm's staged publishing flow for this trusted publisher
#[arg(long, requires = "setup_trusted_publishing")]
allow_stage_publish: bool,

/// 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 @@ -1066,6 +1175,67 @@ pub async fn run_command_with_options(
commands::delegate::execute(cwd, "pack", &args, raw_subcommand).await
}

Commands::Release {
dry_run,
skip_publish,
first_release,
changelog,
no_changelog,
version,
preid,
otp,
setup_trusted_publishing,
trusted_publisher_repository,
trusted_publisher_workflow,
trusted_publisher_environment,
trusted_publisher_registry,
allow_stage_publish,
projects,
git_tag: _,
no_git_tag,
git_commit: _,
no_git_commit,
run_checks,
no_run_checks,
yes,
} => {
let run_checks = if setup_trusted_publishing {
false
} else if dry_run {
run_checks
} else {
!no_run_checks || run_checks
};
let trusted_publishing_setup = setup_trusted_publishing.then_some({
commands::release::TrustedPublishingSetupOptions {
repository: trusted_publisher_repository,
workflow: trusted_publisher_workflow,
environment: trusted_publisher_environment,
registry: trusted_publisher_registry,
allow_stage_publish,
}
});
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,
},
trusted_publishing_setup,
)
.await
}

Commands::Run { args } => {
maybe_print_runtime_header("run", &args, render_options.show_header);
commands::delegate::execute(cwd, "run", &args, raw_subcommand).await
Expand Down
6 changes: 6 additions & 0 deletions crates/vp_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/vp_global_cli/src/commands/env/exec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,10 +201,43 @@ fn classify_version(version: &str) -> VersionSelector<'_> {

#[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 @@ -216,10 +249,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
3 changes: 3 additions & 0 deletions crates/vp_global_cli/src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,9 @@ pub async fn prepend_js_runtime_to_path_env(project_path: &AbsolutePath) -> Resu
// Global package management
pub mod global;

// Workspace release management
pub mod release;

// Category B: JS Script Commands
pub mod config;
pub mod create;
Expand Down
Loading
Loading