Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 6 additions & 0 deletions .github/scripts/__tests__/upgrade-deps-utils.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,9 @@ test('selects the highest stable version from the supported major', () => {
test('returns undefined when the supported major has no stable release', () => {
expect(findLatestStableVersionForMajor(['4.2.0-beta.1', '5.0.0'], 4)).toBeUndefined();
});

test('keeps Vitest upgrades on v5 after the migration', () => {
expect(
findLatestStableVersionForMajor(['4.1.11', '5.0.0', '5.1.0', '5.2.0-beta.1', '6.0.0'], 5),
).toBe('5.1.0');
});
7 changes: 2 additions & 5 deletions .github/scripts/upgrade-deps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ type PnpmWorkspaceEntry = {
const STABLE_SEMVER_TAG_RE = /^v?\d+\.\d+\.\d+$/;
// Vitest major upgrades can change the bundled API, export shims, and CLI
// behavior. Advance this only after Vite+ has adapted to the new major.
const SUPPORTED_VITEST_MAJOR = 4;
const SUPPORTED_VITEST_MAJOR = 5;

const isFullSha = (s: string): boolean => /^[0-9a-f]{40}$/.test(s);

Expand Down Expand Up @@ -211,18 +211,15 @@ async function updatePnpmWorkspace(versions: PnpmWorkspaceVersions): Promise<voi
let content = fs.readFileSync(filePath, 'utf8');

// oxlint's trailing \n in the pattern disambiguates from oxlint-tsgolint.
// All @vitest/* catalog entries (browser + core direct deps) must stay pinned
// Official @vitest/* catalog entries (browser + core direct deps) stay pinned
// to the same exact version as `vitest` itself, otherwise the catalog drifts
// from VITEST_VERSION.
const vitestExactVersionPackages = [
'@vitest/browser',
'@vitest/browser-playwright',
'@vitest/browser-preview',
'@vitest/browser-webdriverio',
'@vitest/expect',
'@vitest/mocker',
'@vitest/pretty-format',
'@vitest/runner',
'@vitest/snapshot',
'@vitest/spy',
'@vitest/utils',
Expand Down
15 changes: 14 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -389,10 +389,13 @@ jobs:
include:
- os: namespace-profile-linux-x64-default
target: x86_64-unknown-linux-gnu
test-node: 22.18.0
- os: namespace-profile-mac-default
target: aarch64-apple-darwin
test-node: 24.11.0
- os: namespace-profile-windows-4c-8g
target: x86_64-pc-windows-msvc
test-node: 26.0.0
runs-on: ${{ matrix.os }}
steps:
- uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2
Expand Down Expand Up @@ -467,10 +470,20 @@ jobs:
run: vp check

- name: Run unit tests
run: RUST_BACKTRACE=1 pnpm test:unit
run: vp env exec --node ${{ matrix.test-node }} node packages/cli/dist/bin.js test run
env:
RUST_BACKTRACE: '1'
RUST_MIN_STACK: 8388608

- name: Test vendored workspaces with Vitest v5
if: runner.os == 'Linux'
run: |
pnpm --filter @rolldown/test-dev-server build
pnpm exec playwright install --with-deps chromium
pnpm test:vendored
env:
PLAYWRIGHT_BROWSERS_PATH: '0'

- name: Test global package install (powershell)
if: ${{ matrix.os != 'namespace-profile-linux-x64-default' }}
shell: pwsh
Expand Down
7 changes: 4 additions & 3 deletions .github/workflows/upgrade-deps.yml
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,9 @@ jobs:

### Background
- Upgrade script: `./.github/scripts/upgrade-deps.ts`
- Vitest is intentionally capped at the latest stable `4.x` release until
Vite+ adapts to a newer major. Do not remove or bypass that cap.
- Vitest is capped at the latest stable `5.x` release. Keep the exact
version selected by the upgrade script when merging upstream catalogs.
Official Vitest packages must use that version. Do not bypass the cap.
- Sync-remote tool: `pnpm tool sync-remote` (source in
`packages/tools/src/sync-remote-deps.ts`) — clones rolldown/vite into the
working tree, merges their pnpm-workspace catalogs into the root
Expand All @@ -119,7 +120,7 @@ jobs:
cross-major semver conflict in the merged catalog, e.g.
`Incompatible semver ranges for <pkg>: ^X vs ^Y`. The merger refuses to
auto-resolve cross-major conflicts for packages outside its synced list
(oxc-*, vitest deps). For passthrough deps that vp does NOT import
(oxc-* and tinybench). For passthrough deps that vp does NOT import
directly (e.g. `diff`, `acorn`, `astring`, anything only present in
`rolldown/scripts/package.json` or vite's internals), bump vp's
`pnpm-workspace.yaml` catalog entry to match the rolldown/vite version,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Help requests with additional arguments delegate to the underlying tool.
## `vp test --help --coverage`

```
vitest/4.1.11
vitest/5.0.0

Usage:
$ vitest [...filters]
Expand All @@ -17,6 +17,7 @@ Commands:
dev [...filters]
bench [...filters]
init <project>
doctor [...filters]
list [...filters]
[...filters]
complete [shell]
Expand All @@ -28,6 +29,7 @@ For more info, run any command with the `--help` flag:
$ vitest dev --help
$ vitest bench --help
$ vitest init --help
$ vitest doctor --help
$ vitest list --help
$ vitest --help
$ vitest complete --help
Expand All @@ -47,7 +49,7 @@ Options:
--coverage.allowExternal Collect coverage of files outside the project root (default: false)
--coverage.skipFull Do not show files with 100% statement, branch, and function coverage (default: false)
--coverage.thresholds.100 Shortcut to set all coverage thresholds to 100 (default: false)
--coverage.thresholds.perFile Check thresholds per file. See --coverage.thresholds.lines, --coverage.thresholds.functions, --coverage.thresholds.branches and --coverage.thresholds.statements for the actual thresholds (default: false)
--coverage.thresholds.perFile <boolean> Check thresholds per file. See --coverage.thresholds.lines, --coverage.thresholds.functions, --coverage.thresholds.branches and --coverage.thresholds.statements for the actual thresholds (default: false). Object form is available in config files only.
--coverage.thresholds.autoUpdate <boolean|function> Update threshold values: "lines", "functions", "branches" and "statements" to configuration file when current coverage is above the configured thresholds (default: false)
--coverage.thresholds.lines <number> Threshold for lines. Visit https://github.com/istanbuljs/nyc#coverage-thresholds for more information. This option is not available for custom providers
--coverage.thresholds.functions <number> Threshold for functions. Visit https://github.com/istanbuljs/nyc#coverage-thresholds for more information. This option is not available for custom providers
Expand All @@ -63,4 +65,5 @@ Options:
--coverage.changed <commit/branch> Collect coverage only for files changed since a specified commit or branch (e.g., origin/main or HEAD~1). Inherits value from --changed by default.
--coverage.excludeAfterRemap Apply exclusions again after coverage has been remapped to original sources. (default: false)
--coverage.htmlDir <path> Directory of HTML coverage output to be served in UI mode and HTML reporter.
--coverage.autoAttachSubprocess Track coverage of the node:child_process and node:worker_threads spawned during test run. Supported only by v8 provider. (default: false)
```
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ peerDependencyRules:
the guidance's `vp pm approve-builds` command approves the gated build

```
✓ Lockfile passes supply-chain policies (verified <duration> ago)
Already up to date
node_modules/.pnpm/core-js@3.39.0/node_modules/core-js: Running postinstall script, done in <duration>
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ peerDependencyRules:
the guidance's `vp pm approve-builds` command approves the gated build

```
✓ Lockfile passes supply-chain policies (verified <duration> ago)
Already up to date
node_modules/.pnpm/core-js@3.39.0/node_modules/core-js: Running postinstall script, done in <duration>
```

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "migration-agent-claude",
"dependencies": {
"vitest": "^3.0.0"
"vitest": "^4.1.0"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ migration with --agent claude should write CLAUDE.md
```
VITE+ - The Unified Toolchain for the Web

Vitest v5: 1 review item

package.json
1:1 REVIEW [configless-defaults] No test config exists. Vitest v5 clears mocks by default. A separate confirmed action can create compatibility config, but a new config can change config discovery and project structure.
◇ Migrated . to Vite+ <version>
• Node <version> pnpm <version>
• 2 config updates applied, 1 file had imports rewritten
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ migration preserves inline arrays in an existing bunfig.toml
```
VITE+ - The Unified Toolchain for the Web

Vitest v5: 1 review item

package.json
1:1 REVIEW [configless-defaults] No test config exists. Vitest v5 clears mocks by default. A separate confirmed action can create compatibility config, but a new config can change config discovery and project structure.
◇ Migrated . to Vite+ <version>
• Node <version> bun <version>
• 2 config updates applied
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ migration does not create bunfig.toml
```
VITE+ - The Unified Toolchain for the Web

Vitest v5: 1 review item

package.json
1:1 REVIEW [configless-defaults] No test config exists. Vitest v5 clears mocks by default. A separate confirmed action can create compatibility config, but a new config can change config discovery and project structure.
◇ Migrated . to Vite+ <version>
• Node <version> bun <version>
• 2 config updates applied
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ migration preserves bunfig.toml without an install section
```
VITE+ - The Unified Toolchain for the Web

Vitest v5: 1 review item

package.json
1:1 REVIEW [configless-defaults] No test config exists. Vitest v5 clears mocks by default. A separate confirmed action can create compatibility config, but a new config can change config discovery and project structure.
◇ Migrated . to Vite+ <version>
• Node <version> bun <version>
• 2 config updates applied
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,10 @@ import { defineConfig } from 'vite-plus';
export default defineConfig({
plugins: [foo()],
test: {
clearMocks: false,
dir: join(import.meta.dirname, 'test'),
browser: {
locators: { exact: false },
enabled: true,
provider: playwright(),
headless: true,
Expand Down Expand Up @@ -86,7 +88,7 @@ catalog:
vite: npm:@voidzero-dev/vite-plus-core@<version>
vitest: <version>
vite-plus: <version>
'@vitest/browser-webdriverio': <version>
'@vitest/browser-webdriverio': ^5.0.0-beta.5 || >=5.0.0
'@vitest/browser-playwright': <version>
'@vitest/coverage-v8': <version>
allowBuilds:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ migration should rewrite imports to vite-plus
```
VITE+ - The Unified Toolchain for the Web

Vitest v5: 1 review item

package.json
1:1 REVIEW [configless-defaults] No test config exists. Vitest v5 clears mocks by default and uses exact browser locators. A separate confirmed action can create compatibility config, but a new config can change config discovery and project structure.
◇ Migrated . to Vite+ <version>
• Node <version> pnpm <version>
• 2 config updates applied, 1 file had imports rewritten
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,10 @@ export default defineConfig({
},
plugins: lazyPlugins(() => [react()]),
test: {
clearMocks: false,
dir: join(import.meta.dirname, 'test'),
browser: {
locators: { exact: false },
enabled: true,
provider: playwright(),
headless: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,27 @@ migration should work with bun object-form workspaces
```
VITE+ - The Unified Toolchain for the Web

Vitest v5: 2 review items

packages/app/package.json
1:1 REVIEW [configless-defaults] No test config exists. Vitest v5 clears mocks by default. A separate confirmed action can create compatibility config, but a new config can change config discovery and project structure.

packages/utils/package.json
1:1 REVIEW [configless-defaults] No test config exists. Vitest v5 clears mocks by default. A separate confirmed action can create compatibility config, but a new config can change config discovery and project structure.

✔ Merged .oxlintrc.json into vite.config.ts
◇ Migrated . to Vite+ <version>
• Node <version> bun <version>
• 2 config updates applied, 1 file had imports rewritten
• Inline Vite plugins wrapped with lazyPlugins for check/lint/fmt
! Warnings:
- Vitest v5: 2 review items

packages/app/package.json
1:1 REVIEW [configless-defaults] No test config exists. Vitest v5 clears mocks by default. A separate confirmed action can create compatibility config, but a new config can change config discovery and project structure.

packages/utils/package.json
1:1 REVIEW [configless-defaults] No test config exists. Vitest v5 clears mocks by default. A separate confirmed action can create compatibility config, but a new config can change config discovery and project structure.
```

## `vpt print-file vite.config.ts`
Expand Down Expand Up @@ -43,6 +59,7 @@ export default defineConfig({
}
]
},
test: { clearMocks: false },
plugins: lazyPlugins(() => [react()]),
});
```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,29 @@ migration should merge vite.config.ts and remove oxlintrc and oxfmtrc
```
VITE+ - The Unified Toolchain for the Web

Vitest v5: 2 review items

packages/app/package.json
1:1 REVIEW [configless-defaults] No test config exists. Vitest v5 clears mocks by default. A separate confirmed action can create compatibility config, but a new config can change config discovery and project structure.

packages/utils/package.json
1:1 REVIEW [configless-defaults] No test config exists. Vitest v5 clears mocks by default. A separate confirmed action can create compatibility config, but a new config can change config discovery and project structure.

✔ Merged .oxlintrc.json into vite.config.ts

✔ Merged .oxfmtrc.json into vite.config.ts
◇ Migrated . to Vite+ <version>
• Node <version> pnpm <version>
• 4 config updates applied, 1 file had imports rewritten
• Inline Vite plugins wrapped with lazyPlugins for check/lint/fmt
! Warnings:
- Vitest v5: 2 review items

packages/app/package.json
1:1 REVIEW [configless-defaults] No test config exists. Vitest v5 clears mocks by default. A separate confirmed action can create compatibility config, but a new config can change config discovery and project structure.

packages/utils/package.json
1:1 REVIEW [configless-defaults] No test config exists. Vitest v5 clears mocks by default. A separate confirmed action can create compatibility config, but a new config can change config discovery and project structure.
```

## `vpt print-file vite.config.ts`
Expand Down Expand Up @@ -51,6 +67,7 @@ export default defineConfig({
}
]
},
test: { clearMocks: false },
plugins: lazyPlugins(() => [react()]),
});
```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
name = "migration_monorepo_root_vitest_adjacent"
vp = "global"
steps = [
{ argv = ["vpt", "write-file", "node_modules/vitest/package.json", "{\"name\":\"vitest\",\"version\":\"4.1.11\"}"], comment = "record the original runner version without adding a direct dependency", snapshot = false },
{ argv = ["vp", "migrate", "--no-interactive"], comment = "root with a vitest-adjacent dep but no direct vitest still gets a direct vitest pin", continue-on-failure = true },
{ argv = ["vpt", "print-file", "package.json"], comment = "vitest pinned at the root even though vite-plus is injected first", continue-on-failure = true },
]
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
# migration_monorepo_root_vitest_adjacent

## `vpt write-file node_modules/vitest/package.json '{"name":"vitest","version":"4.1.11"}'`

record the original runner version without adding a direct dependency


## `vp migrate --no-interactive`

root with a vitest-adjacent dep but no direct vitest still gets a direct vitest pin

```
VITE+ - The Unified Toolchain for the Web

Vitest v5: 1 review item

package.json
1:1 REVIEW [configless-defaults] No test config exists. Vitest v5 clears mocks by default and uses exact browser locators. A separate confirmed action can create compatibility config, but a new config can change config discovery and project structure.
◇ Migrated . to Vite+ <version>
• Node <version> pnpm <version>
• 2 config updates applied
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
name = "migration_monorepo_skip_vite_peer_dependency"
vp = "global"
steps = [
{ argv = ["vpt", "write-file", "node_modules/vitest/package.json", "{\"name\":\"vitest\",\"version\":\"4.1.11\"}"], comment = "record the original runner version without adding a direct dependency", snapshot = false },
{ argv = ["vp", "migrate", "--no-interactive"], comment = "migration should preserve vite peer contracts in workspace packages", continue-on-failure = true },
{ argv = ["vpt", "print-file", "packages/vite-plugin/src/index.ts"], comment = "vite-plugin has vite in peerDeps: vite imports stay public, vitest rewrites", continue-on-failure = true },
{ argv = ["vpt", "print-file", "package.json"], comment = "check root package.json (no peerDependencies)", continue-on-failure = true },
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,29 @@
# migration_monorepo_skip_vite_peer_dependency

## `vpt write-file node_modules/vitest/package.json '{"name":"vitest","version":"4.1.11"}'`

record the original runner version without adding a direct dependency


## `vp migrate --no-interactive`

migration should preserve vite peer contracts in workspace packages

```
VITE+ - The Unified Toolchain for the Web

Vitest v5: 1 review item

packages/vite-plugin/package.json
1:1 REVIEW [configless-defaults] No test config exists. Vitest v5 clears mocks by default. A separate confirmed action can create compatibility config, but a new config can change config discovery and project structure.
◇ Migrated . to Vite+ <version>
• Node <version> pnpm <version>
• 2 config updates applied, 1 file had imports rewritten
! Warnings:
- Vitest v5: 1 review item

packages/vite-plugin/package.json
1:1 REVIEW [configless-defaults] No test config exists. Vitest v5 clears mocks by default. A separate confirmed action can create compatibility config, but a new config can change config discovery and project structure.
```

## `vpt print-file packages/vite-plugin/src/index.ts`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
name = "migration_monorepo_yarn4"
vp = "global"
steps = [
{ argv = ["vpt", "write-file", "node_modules/vitest/package.json", "{\"name\":\"vitest\",\"version\":\"4.1.11\"}"], comment = "record the original runner version without adding a direct dependency", snapshot = false },
{ argv = ["vp", "migrate", "--no-interactive"], comment = "migration should merge vite.config.ts and remove oxlintrc", continue-on-failure = true },
{ argv = ["vpt", "print-file", "vite.config.ts"], comment = "check vite.config.ts", continue-on-failure = true },
{ argv = ["vpt", "stat-file", ".oxlintrc.json", "--assert-not", "file"], comment = "check .oxlintrc.json is removed", continue-on-failure = true },
Expand Down
Loading
Loading