Skip to content

Commit 0776757

Browse files
committed
Merge remote-tracking branch 'origin/main' into feat/verify-node-shasums-pgp
2 parents 1dc307a + 6f97f09 commit 0776757

201 files changed

Lines changed: 12369 additions & 6541 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/scripts/upgrade-deps.ts

Lines changed: 150 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -152,13 +152,41 @@ async function updatePnpmWorkspace(versions: PnpmWorkspaceVersions): Promise<voi
152152
let content = fs.readFileSync(filePath, 'utf8');
153153

154154
// oxlint's trailing \n in the pattern disambiguates from oxlint-tsgolint.
155+
// All @vitest/* catalog entries (browser + core direct deps) must stay pinned
156+
// to the same exact version as `vitest` itself, otherwise the catalog drifts
157+
// from VITEST_VERSION.
158+
const vitestExactVersionPackages = [
159+
'@vitest/browser',
160+
'@vitest/browser-playwright',
161+
'@vitest/browser-preview',
162+
'@vitest/browser-webdriverio',
163+
'@vitest/expect',
164+
'@vitest/mocker',
165+
'@vitest/pretty-format',
166+
'@vitest/runner',
167+
'@vitest/snapshot',
168+
'@vitest/spy',
169+
'@vitest/utils',
170+
];
171+
const vitestExactVersionEntries: PnpmWorkspaceEntry[] = vitestExactVersionPackages.map((pkg) => ({
172+
name: pkg,
173+
pattern: new RegExp(`'${pkg.replaceAll('/', '\\/')}': ([\\d.]+(?:-[\\w.]+)?)`),
174+
replacement: `'${pkg}': ${versions.vitest}`,
175+
newVersion: versions.vitest,
176+
}));
155177
const entries: PnpmWorkspaceEntry[] = [
156178
{
157179
name: 'vitest',
158-
pattern: /vitest-dev: npm:vitest@\^([\d.]+(?:-[\w.]+)?)/,
159-
replacement: `vitest-dev: npm:vitest@^${versions.vitest}`,
180+
// The `@voidzero-dev/vite-plus-test` wrapper (which used to be aliased
181+
// here via `vitest-dev: npm:vitest@^…`) has been removed. Vitest is now
182+
// a plain catalog entry pinned to an exact version (`vitest: x.y.z`),
183+
// so match that shape directly. The leading newline anchor disambiguates
184+
// from neighbouring keys like `vitepress-*` and `@vitest/browser`.
185+
pattern: /\n {2}vitest: ([\d.]+(?:-[\w.]+)?)\n/,
186+
replacement: `\n vitest: ${versions.vitest}\n`,
160187
newVersion: versions.vitest,
161188
},
189+
...vitestExactVersionEntries,
162190
{
163191
name: 'tsdown',
164192
pattern: /tsdown: \^([\d.]+(?:-[\w.]+)?)/,
@@ -246,34 +274,129 @@ async function updatePnpmWorkspace(versions: PnpmWorkspaceVersions): Promise<voi
246274
console.log('Updated pnpm-workspace.yaml');
247275
}
248276

249-
// ============ Update packages/test/package.json ============
250-
async function updateTestPackage(vitestVersion: string): Promise<void> {
251-
const filePath = path.join(ROOT, 'packages/test/package.json');
252-
const pkg: PackageJson = readJsonFile(filePath);
253-
const devDependencies = pkg.devDependencies;
254-
if (!devDependencies) {
255-
throw new Error('packages/test/package.json is missing devDependencies');
277+
// ============ Update VITEST_VERSION constant ============
278+
// Keeps the TypeScript source-of-truth (`packages/cli/src/utils/constants.ts`)
279+
// in sync with the `vitest:` catalog entry in pnpm-workspace.yaml. The
280+
// constant is consumed by both `packages/cli` and `ecosystem-ci/patch-project.ts`
281+
// (which re-imports it), so daily upstream bumps must update it here too.
282+
async function updateVitestVersionConstant(vitestVersion: string): Promise<void> {
283+
const filePath = path.join(ROOT, 'packages/cli/src/utils/constants.ts');
284+
const content = fs.readFileSync(filePath, 'utf8');
285+
const pattern = /export const VITEST_VERSION = '([\d.]+(?:-[\w.]+)?)';/;
286+
let oldVersion: string | undefined;
287+
const updated = content.replace(pattern, (_match: string, captured: string) => {
288+
oldVersion = captured;
289+
return `export const VITEST_VERSION = '${vitestVersion}';`;
290+
});
291+
if (oldVersion === undefined) {
292+
throw new Error(
293+
`Failed to match VITEST_VERSION in ${filePath} — the pattern ${pattern} is stale, ` +
294+
`please update it in .github/scripts/upgrade-deps.ts`,
295+
);
256296
}
297+
fs.writeFileSync(filePath, updated);
298+
recordChange('VITEST_VERSION constant', oldVersion, vitestVersion);
299+
console.log('Updated packages/cli/src/utils/constants.ts');
300+
}
257301

258-
// Update all @vitest/* devDependencies
259-
for (const dep of Object.keys(devDependencies)) {
260-
if (dep.startsWith('@vitest/')) {
261-
devDependencies[dep] = vitestVersion;
302+
// ============ Update .github/workflows/test-vp-create.yml ============
303+
// The `vp create` smoke-test workflow pins every vitest-family package via the
304+
// `VP_OVERRIDE_PACKAGES` env var so that template installs use the bundled
305+
// version. Daily upstream bumps must rewrite those pins so the workflow does
306+
// not drift behind the rest of the repo.
307+
async function updateTestVpCreateWorkflow(vitestVersion: string): Promise<void> {
308+
const filePath = path.join(ROOT, '.github/workflows/test-vp-create.yml');
309+
const content = fs.readFileSync(filePath, 'utf8');
310+
const vitestKeys = [
311+
'vitest',
312+
'@vitest/expect',
313+
'@vitest/runner',
314+
'@vitest/snapshot',
315+
'@vitest/spy',
316+
'@vitest/utils',
317+
'@vitest/mocker',
318+
'@vitest/pretty-format',
319+
'@vitest/coverage-v8',
320+
'@vitest/coverage-istanbul',
321+
];
322+
let updated = content;
323+
let oldVersion: string | undefined;
324+
for (const key of vitestKeys) {
325+
const pattern = new RegExp(`"${key.replaceAll('/', '\\/')}":"([\\d.]+(?:-[\\w.]+)?)"`);
326+
let matched = false;
327+
updated = updated.replace(pattern, (_match: string, captured: string) => {
328+
matched = true;
329+
oldVersion ??= captured;
330+
return `"${key}":"${vitestVersion}"`;
331+
});
332+
if (!matched) {
333+
throw new Error(
334+
`Failed to match "${key}" in ${filePath} — the pattern ${pattern} is stale, ` +
335+
`please update it in .github/scripts/upgrade-deps.ts`,
336+
);
262337
}
263338
}
339+
fs.writeFileSync(filePath, updated);
340+
recordChange('test-vp-create workflow', oldVersion ?? null, vitestVersion);
341+
console.log('Updated .github/workflows/test-vp-create.yml');
342+
}
264343

265-
// Update vitest-dev devDependency
266-
if (devDependencies['vitest-dev']) {
267-
devDependencies['vitest-dev'] = `^${vitestVersion}`;
268-
}
269-
270-
// Update @vitest/ui peerDependency if present
271-
if (pkg.peerDependencies?.['@vitest/ui']) {
272-
pkg.peerDependencies['@vitest/ui'] = vitestVersion;
344+
// ============ Update README.md manual-migration vitest pins ============
345+
// The manual-migration guide pins `vitest` to an exact version in three places —
346+
// the npm/Bun `overrides` block, the pnpm-workspace `overrides` block, and the
347+
// Yarn `resolutions` block — so a hand-migrated project shares one Vitest copy
348+
// with the bundled `vp test`. Those literals are NOT interpolated from
349+
// VITEST_VERSION, so a daily bump must rewrite them or the guide drifts behind the
350+
// bundled version. The packages/cli/README.md mirror (refreshed from the root
351+
// README's suffix at build time) is kept in sync here too so the daily PR stays
352+
// self-consistent without depending on a build step running first.
353+
async function updateReadmeVitestPins(vitestVersion: string): Promise<void> {
354+
const readmePaths = [path.join(ROOT, 'README.md'), path.join(ROOT, 'packages/cli/README.md')];
355+
// JSON form: `"vitest": "4.1.9"` — npm/Bun `overrides` + Yarn `resolutions` (2 blocks)
356+
const jsonPattern = /("vitest": ")[\d.]+(?:-[\w.]+)?(")/g;
357+
// YAML form: ` vitest: 4.1.9` — pnpm-workspace `overrides` (1 block)
358+
const yamlPattern = /(\n\s*vitest: )[\d.]+(?:-[\w.]+)?(\n)/g;
359+
// Both READMEs carry the same three manual-migration pins (the cli copy mirrors the
360+
// root's suffix). Assert the exact shape so a daily run fails loudly — like every
361+
// other updater here — if a block is reworded or removed, instead of silently
362+
// shipping a README where only some pins were bumped.
363+
const EXPECTED_JSON = 2;
364+
const EXPECTED_YAML = 1;
365+
let oldVersion: string | undefined;
366+
const capture = (match: string): void => {
367+
const found = /(\d[\d.]*(?:-[\w.]+)?)/.exec(match)?.[1];
368+
if (found && oldVersion === undefined) {
369+
oldVersion = found;
370+
}
371+
};
372+
for (const filePath of readmePaths) {
373+
if (!fs.existsSync(filePath)) {
374+
continue;
375+
}
376+
const content = fs.readFileSync(filePath, 'utf8');
377+
let jsonMatched = 0;
378+
let yamlMatched = 0;
379+
let updated = content.replace(jsonPattern, (match: string, pre: string, post: string) => {
380+
jsonMatched++;
381+
capture(match);
382+
return `${pre}${vitestVersion}${post}`;
383+
});
384+
updated = updated.replace(yamlPattern, (match: string, pre: string, post: string) => {
385+
yamlMatched++;
386+
capture(match);
387+
return `${pre}${vitestVersion}${post}`;
388+
});
389+
if (jsonMatched !== EXPECTED_JSON || yamlMatched !== EXPECTED_YAML) {
390+
throw new Error(
391+
`Expected ${EXPECTED_JSON} JSON + ${EXPECTED_YAML} YAML vitest pins in ${filePath}, ` +
392+
`found ${jsonMatched} + ${yamlMatched} — the manual-migration section changed, ` +
393+
`please update updateReadmeVitestPins in .github/scripts/upgrade-deps.ts`,
394+
);
395+
}
396+
fs.writeFileSync(filePath, updated);
397+
console.log(`Updated ${path.relative(ROOT, filePath)}`);
273398
}
274-
275-
fs.writeFileSync(filePath, JSON.stringify(pkg, null, 2) + '\n');
276-
console.log('Updated packages/test/package.json');
399+
recordChange('README vitest pins', oldVersion ?? null, vitestVersion);
277400
}
278401

279402
// ============ Update packages/core/package.json ============
@@ -430,7 +553,9 @@ await updatePnpmWorkspace({
430553
oxcParser: oxcParserVersion,
431554
oxcTransform: oxcTransformVersion,
432555
});
433-
await updateTestPackage(vitestVersion);
556+
await updateVitestVersionConstant(vitestVersion);
557+
await updateTestVpCreateWorkflow(vitestVersion);
558+
await updateReadmeVitestPins(vitestVersion);
434559
await updateCorePackage(devtoolsVersion);
435560

436561
writeMetaFiles();

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ jobs:
3232
id: check_skip
3333
# v0.0.9 still declares `using: node20`; emits a Node 20 deprecation warning until upstream ships a node24 release.
3434
# https://github.com/withgraphite/graphite-ci-action
35-
uses: withgraphite/graphite-ci-action@9bc969adfd43bb790da3b64b543c78c75cef9689 # v0.0.9
35+
uses: withgraphite/graphite-ci-action@b87de3d800df90082f5f1ba2817f4e1a6f3b0a7b # v0.0.10
3636
with:
3737
graphite_token: ${{ secrets.GRAPHITE_CI_OPTIMIZER_TOKEN }}
3838

.github/workflows/e2e-test.yml

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,9 +109,32 @@ jobs:
109109
- name: Pack packages into tgz
110110
run: |
111111
mkdir -p tmp/tgz
112+
# Every tgz consumer below references fixed `*-0.0.0.tgz` filenames.
113+
# A release commit can leave `packages/{core,cli}` at a published
114+
# version (e.g. 0.1.22), which would make `pnpm pack` emit
115+
# `*-0.1.22.tgz` instead. Pin both to 0.0.0 so the names stay stable.
116+
(cd packages/core && npm pkg set version=0.0.0)
117+
(cd packages/cli && npm pkg set version=0.0.0)
112118
cd packages/core && pnpm pack --pack-destination ../../tmp/tgz && cd ../..
113-
cd packages/test && pnpm pack --pack-destination ../../tmp/tgz && cd ../..
114119
cd packages/cli && pnpm pack --pack-destination ../../tmp/tgz && cd ../..
120+
# Bun is uniquely strict about peer-dep resolution:
121+
# 1. It checks the *resolved target's* package name and version
122+
# against the peer range (vitest 4.1.9 declares peer
123+
# `vite ^6 || ^7 || ^8`).
124+
# 2. A file: override pointing at the vite-plus-core tgz fails
125+
# both the name check (target is `@voidzero-dev/vite-plus-core`,
126+
# not `vite`) and the version check (0.0.0 is outside `^6|^7|^8`).
127+
# pnpm/npm/yarn don't enforce either, and using the same core tgz as
128+
# the file: target for both `vite` and `@voidzero-dev/vite-plus-core`
129+
# is the only configuration they install cleanly. See
130+
# https://github.com/oven-sh/bun/issues/8406.
131+
#
132+
# Generate a sibling vite-7.99.0.tgz: a copy of the core tgz with
133+
# `package.json#name` rewritten to "vite" and `version` to 7.99.0.
134+
# ecosystem-ci/patch-project.ts points its vite override at this
135+
# tgz only for bun-based projects (e.g. bun-vite-template); pnpm-,
136+
# npm- and yarn-based ecosystem projects use the real core tgz.
137+
pnpm exec tool repack-vite-tgz tmp/tgz/voidzero-dev-vite-plus-core-0.0.0.tgz tmp/tgz/vite-7.99.0.tgz vite 7.99.0
115138
# Copy vp binary for e2e-test job (findVpBinary expects it in target/)
116139
cp target/${{ matrix.target }}/release/vp tmp/tgz/vp 2>/dev/null || cp target/${{ matrix.target }}/release/vp.exe tmp/tgz/vp.exe 2>/dev/null || true
117140
cp target/${{ matrix.target }}/release/vp-shim.exe tmp/tgz/vp-shim.exe 2>/dev/null || true

.github/workflows/prepare_release.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ jobs:
5454
}
5555
update_json packages/cli/package.json
5656
update_json packages/core/package.json
57-
update_json packages/test/package.json
5857
update_toml packages/cli/binding/Cargo.toml
5958
update_toml crates/vite_global_cli/Cargo.toml
6059

.github/workflows/publish-to-pkg.pr.new.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,5 +136,4 @@ jobs:
136136
'./packages/cli/cli-npm/*' \
137137
'./packages/cli' \
138138
'./packages/core' \
139-
'./packages/prompts' \
140-
'./packages/test'
139+
'./packages/prompts'

.github/workflows/release.yml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,6 @@ jobs:
161161
- name: Publish
162162
run: |
163163
pnpm publish --filter=./packages/core --tag latest --access public --no-git-checks
164-
pnpm publish --filter=./packages/test --tag latest --access public --no-git-checks
165164
pnpm publish --filter=./packages/cli --tag latest --access public --no-git-checks
166165
167166
- name: Create release body
@@ -177,7 +176,6 @@ jobs:
177176
### Published Packages
178177
179178
- \`@voidzero-dev/vite-plus-core@${VERSION}\`
180-
- \`@voidzero-dev/vite-plus-test@${VERSION}\`
181179
- \`vite-plus@${VERSION}\`
182180
183181
### Installation
@@ -228,7 +226,6 @@ jobs:
228226
229227
**Published Packages:**
230228
• @voidzero-dev/vite-plus-core@${{ env.VERSION }}
231-
• @voidzero-dev/vite-plus-test@${{ env.VERSION }}
232229
• vite-plus@${{ env.VERSION }}
233230
234231
**Install:**

.github/workflows/test-vp-create.yml

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,34 @@ jobs:
9595
- name: Pack packages into tgz
9696
run: |
9797
mkdir -p tmp/tgz
98+
# Every tgz consumer below references fixed `*-0.0.0.tgz` filenames.
99+
# A release commit can leave `packages/{core,cli}` at a published
100+
# version (e.g. 0.1.22), which would make `pnpm pack` emit
101+
# `*-0.1.22.tgz` instead. Pin both to 0.0.0 so the names stay stable.
102+
(cd packages/core && npm pkg set version=0.0.0)
103+
(cd packages/cli && npm pkg set version=0.0.0)
98104
cd packages/core && pnpm pack --pack-destination ../../tmp/tgz && cd ../..
99-
cd packages/test && pnpm pack --pack-destination ../../tmp/tgz && cd ../..
100105
cd packages/cli && pnpm pack --pack-destination ../../tmp/tgz && cd ../..
106+
# Bun is uniquely strict about peer-dep resolution:
107+
# 1. It checks the *resolved target's* package name and version
108+
# against the peer range (vitest 4.1.9 declares peer
109+
# `vite ^6 || ^7 || ^8`).
110+
# 2. A file: override pointing at the vite-plus-core tgz fails
111+
# both the name check (target is `@voidzero-dev/vite-plus-core`,
112+
# not `vite`) and the version check (0.0.0 is outside `^6|^7|^8`).
113+
# pnpm/npm/yarn don't enforce either, and using the same core tgz as
114+
# the file: target for both `vite` and `@voidzero-dev/vite-plus-core`
115+
# is the only configuration they install cleanly. See
116+
# https://github.com/oven-sh/bun/issues/8406.
117+
#
118+
# Generate a sibling vite-7.99.0.tgz: a copy of the core tgz with
119+
# `package.json#name` rewritten to "vite" and `version` to 7.99.0.
120+
# Only the bun matrix entry below points its vite override at this
121+
# alias tgz; pnpm/npm/yarn keep pointing at the real core tgz so
122+
# pnpm's workspace resolver doesn't trip on a "vite@<version>"
123+
# registry lookup (the renamed tgz makes pnpm register the dep as
124+
# vite@7.99.0 and then probe npmjs.org to validate the version).
125+
pnpm exec tool repack-vite-tgz tmp/tgz/voidzero-dev-vite-plus-core-0.0.0.tgz tmp/tgz/vite-7.99.0.tgz vite 7.99.0
101126
# Copy vp binary for test jobs
102127
cp target/x86_64-unknown-linux-gnu/release/vp tmp/tgz/vp
103128
ls -la tmp/tgz
@@ -154,6 +179,13 @@ jobs:
154179
- yarn
155180
- bun
156181
env:
182+
# Bun's strict peer check requires the `vite` override target's tgz to be
183+
# named "vite" with a version satisfying vitest's `peer vite ^6 || ^7 || ^8`.
184+
# The bun matrix entry uses the masquerade tgz (vite-7.99.0.tgz). pnpm/npm/yarn
185+
# point at the real core tgz — anything else trips a registry lookup for
186+
# vite@<version> when sub-package and override targets are both file: tgz aliases.
187+
VITE_OVERRIDE_TGZ: ${{ matrix.package-manager == 'bun' && 'vite-7.99.0.tgz' || 'voidzero-dev-vite-plus-core-0.0.0.tgz' }}
188+
VP_VERSION: 'file:${{ github.workspace }}/tmp/tgz/vite-plus-0.0.0.tgz'
157189
# Force full dependency rewriting so the library template's existing
158190
# vite-plus dep gets overridden with the local tgz
159191
VP_FORCE_MIGRATE: '1'
@@ -170,22 +202,12 @@ jobs:
170202
name: vite-plus-packages
171203
path: tmp/tgz
172204

173-
- name: Resolve tgz paths
174-
run: |
175-
CLI_TGZ=$(ls "$GITHUB_WORKSPACE"/tmp/tgz/vite-plus-[0-9]*.tgz | head -n1)
176-
CORE_TGZ=$(ls "$GITHUB_WORKSPACE"/tmp/tgz/voidzero-dev-vite-plus-core-[0-9]*.tgz | head -n1)
177-
TEST_TGZ=$(ls "$GITHUB_WORKSPACE"/tmp/tgz/voidzero-dev-vite-plus-test-[0-9]*.tgz | head -n1)
178-
echo "CLI_TGZ=$CLI_TGZ" >> $GITHUB_ENV
179-
echo "VP_VERSION=file:$CLI_TGZ" >> $GITHUB_ENV
180-
printf 'VP_OVERRIDE_PACKAGES={"vite":"file:%s","vitest":"file:%s","@voidzero-dev/vite-plus-core":"file:%s","@voidzero-dev/vite-plus-test":"file:%s"}\n' \
181-
"$CORE_TGZ" "$TEST_TGZ" "$CORE_TGZ" "$TEST_TGZ" >> $GITHUB_ENV
182-
183205
- name: Install vp CLI
184206
run: |
185207
mkdir -p target/release
186208
cp tmp/tgz/vp target/release/vp
187209
chmod +x target/release/vp
188-
node $GITHUB_WORKSPACE/packages/tools/src/install-global-cli.ts --tgz "$CLI_TGZ"
210+
node $GITHUB_WORKSPACE/packages/tools/src/install-global-cli.ts --tgz $GITHUB_WORKSPACE/tmp/tgz/vite-plus-0.0.0.tgz
189211
echo "$HOME/.vite-plus/bin" >> $GITHUB_PATH
190212
191213
- name: Verify vp installation
@@ -195,6 +217,8 @@ jobs:
195217
196218
- name: Run vp create ${{ matrix.template.name }} with ${{ matrix.package-manager }}
197219
working-directory: ${{ runner.temp }}
220+
env:
221+
VP_OVERRIDE_PACKAGES: '{"vite":"file:${{ github.workspace }}/tmp/tgz/${{ env.VITE_OVERRIDE_TGZ }}","@voidzero-dev/vite-plus-core":"file:${{ github.workspace }}/tmp/tgz/voidzero-dev-vite-plus-core-0.0.0.tgz","vitest":"4.1.9","@vitest/expect":"4.1.9","@vitest/runner":"4.1.9","@vitest/snapshot":"4.1.9","@vitest/spy":"4.1.9","@vitest/utils":"4.1.9","@vitest/mocker":"4.1.9","@vitest/pretty-format":"4.1.9","@vitest/coverage-v8":"4.1.9","@vitest/coverage-istanbul":"4.1.9"}'
198222
run: |
199223
vp create ${{ matrix.template.create-args }} \
200224
--no-interactive \
@@ -268,10 +292,9 @@ jobs:
268292
run: |
269293
node -e "
270294
const path = require('path');
271-
const expected = require('$GITHUB_WORKSPACE/packages/cli/package.json').version;
272295
const pkg = require(path.resolve('node_modules/vite-plus/package.json'));
273-
if (pkg.version !== expected) {
274-
console.error('Expected vite-plus@' + expected + ', got ' + pkg.version);
296+
if (pkg.version !== '0.0.0') {
297+
console.error('Expected vite-plus@0.0.0, got ' + pkg.version);
275298
process.exit(1);
276299
}
277300
console.log('✓ vite-plus@' + pkg.version + ' installed correctly');

0 commit comments

Comments
 (0)