From eda4df3b0f71f00740b77371ebbea0acfb6066a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BF=A0=20/=20green?= Date: Sun, 24 Mar 2024 23:41:50 +0900 Subject: [PATCH] chore: use @vitejs/release-scripts in v3 (#16255) --- package.json | 1 + pnpm-lock.yaml | 98 ++++++++++++++++++ scripts/publishCI.ts | 53 ++-------- scripts/release.ts | 152 +++++---------------------- scripts/releaseUtils.ts | 221 ++-------------------------------------- 5 files changed, 144 insertions(+), 381 deletions(-) diff --git a/package.json b/package.json index 47f36632fc7767..32c73fd6041e87 100644 --- a/package.json +++ b/package.json @@ -60,6 +60,7 @@ "@types/ws": "^8.5.3", "@typescript-eslint/eslint-plugin": "^5.41.0", "@typescript-eslint/parser": "^5.41.0", + "@vitejs/release-scripts": "^1.3.1", "conventional-changelog-cli": "^2.2.2", "esbuild": "^0.14.47", "eslint": "^8.26.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c2d9089c6ff255..b63605e83da0aa 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -34,6 +34,7 @@ importers: '@types/ws': ^8.5.3 '@typescript-eslint/eslint-plugin': ^5.41.0 '@typescript-eslint/parser': ^5.41.0 + '@vitejs/release-scripts': ^1.3.1 conventional-changelog-cli: ^2.2.2 esbuild: ^0.14.47 eslint: ^8.26.0 @@ -90,6 +91,7 @@ importers: '@types/ws': 8.5.3 '@typescript-eslint/eslint-plugin': 5.41.0_ffukdn5orh6tcfytlcazewwqli '@typescript-eslint/parser': 5.41.0_t64u7vh5pvkzkn6jnkohfgcmb4 + '@vitejs/release-scripts': 1.3.1 conventional-changelog-cli: 2.2.2 esbuild: 0.14.47 eslint: 8.26.0 @@ -2863,6 +2865,17 @@ packages: eslint-visitor-keys: 3.3.0 dev: true + /@vitejs/release-scripts/1.3.1: + resolution: {integrity: sha512-upGTQoH03TJNuwb/G+PZXxRBdQLZlslXhOo9xZ0HpWm6M33T7LR+bj6XtBYQq3c0cDhVjgQ2NpHVSZL0xoKelQ==} + dependencies: + execa: 8.0.1 + mri: 1.2.0 + picocolors: 1.0.0 + prompts: 2.4.2 + publint: 0.2.7 + semver: 7.6.0 + dev: true + /@vue/babel-helper-vue-transform-on/1.0.2: resolution: {integrity: sha512-hz4R8tS5jMn8lDq6iD+yWL6XNB699pGIVLk7WSJnn1dbpjaazsjZQkieJoRX6gW5zpYSCFqQ7jUquPNY65tQYA==} dev: false @@ -5420,6 +5433,21 @@ packages: strip-final-newline: 3.0.0 dev: true + /execa/8.0.1: + resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} + engines: {node: '>=16.17'} + dependencies: + cross-spawn: 7.0.3 + get-stream: 8.0.1 + human-signals: 5.0.0 + is-stream: 3.0.0 + merge-stream: 2.0.0 + npm-run-path: 5.1.0 + onetime: 6.0.0 + signal-exit: 4.1.0 + strip-final-newline: 3.0.0 + dev: true + /express/4.18.2: resolution: {integrity: sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==} engines: {node: '>= 0.10.0'} @@ -5737,6 +5765,11 @@ packages: engines: {node: '>=10'} dev: true + /get-stream/8.0.1: + resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} + engines: {node: '>=16'} + dev: true + /get-symbol-description/1.0.0: resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==} engines: {node: '>= 0.4'} @@ -6004,6 +6037,11 @@ packages: engines: {node: '>=12.20.0'} dev: true + /human-signals/5.0.0: + resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} + engines: {node: '>=16.17.0'} + dev: true + /iconv-lite/0.4.24: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} engines: {node: '>=0.10.0'} @@ -6028,6 +6066,13 @@ packages: postcss: 8.4.18 dev: true + /ignore-walk/5.0.1: + resolution: {integrity: sha512-yemi4pMf51WKT7khInJqAvsIGzoqYXblnsz0ql8tM+yi1EKYTY1evX4NAbJrLL/Aanr2HyZeluqU+Oi7MGHokw==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + dependencies: + minimatch: 5.1.0 + dev: true + /ignore/5.2.0: resolution: {integrity: sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==} engines: {node: '>= 4'} @@ -7051,6 +7096,29 @@ packages: resolution: {integrity: sha512-qizSNPO93t1YUuUhP22btGOo3chcvDFqFaj2TRybP0DMxkHOCTYwp3n34fel4a31ORXy4m1Xq0Gyqpb5m33qIg==} dev: false + /npm-bundled/2.0.1: + resolution: {integrity: sha512-gZLxXdjEzE/+mOstGDqR6b0EkhJ+kM6fxM6vUuckuctuVPh80Q6pw/rSZj9s4Gex9GxWtIicO1pc8DB9KZWudw==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + dependencies: + npm-normalize-package-bin: 2.0.0 + dev: true + + /npm-normalize-package-bin/2.0.0: + resolution: {integrity: sha512-awzfKUO7v0FscrSpRoogyNm0sajikhBWpU0QMrW09AMi9n1PoKU6WaIqUzuJSQnpciZZmJ/jMZ2Egfmb/9LiWQ==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + dev: true + + /npm-packlist/5.1.3: + resolution: {integrity: sha512-263/0NGrn32YFYi4J533qzrQ/krmmrWwhKkzwTuM4f/07ug51odoaNjUexxO4vxlzURHcmYMH1QjvHjsNDKLVg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + hasBin: true + dependencies: + glob: 8.0.3 + ignore-walk: 5.0.1 + npm-bundled: 2.0.1 + npm-normalize-package-bin: 2.0.0 + dev: true + /npm-run-all/4.1.5: resolution: {integrity: sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==} engines: {node: '>= 4'} @@ -7685,6 +7753,16 @@ packages: dev: true optional: true + /publint/0.2.7: + resolution: {integrity: sha512-tLU4ee3110BxWfAmCZggJmCUnYWgPTr0QLnx08sqpLYa8JHRiOudd+CgzdpfU5x5eOaW2WMkpmOrFshRFYK7Mw==} + engines: {node: '>=16'} + hasBin: true + dependencies: + npm-packlist: 5.1.3 + picocolors: 1.0.0 + sade: 1.8.1 + dev: true + /pug-attrs/3.0.0: resolution: {integrity: sha512-azINV9dUtzPMFQktvTXciNAfAuVh/L/JCl0vtPCwvOA21uZrC08K/UnmrL+SXGEVc1FwzjW62+xw5S/uaLj6cA==} dependencies: @@ -8130,6 +8208,13 @@ packages: tslib: 2.4.0 dev: true + /sade/1.8.1: + resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==} + engines: {node: '>=6'} + dependencies: + mri: 1.2.0 + dev: true + /safe-buffer/5.1.2: resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} dev: true @@ -8202,6 +8287,14 @@ packages: dependencies: lru-cache: 6.0.0 + /semver/7.6.0: + resolution: {integrity: sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==} + engines: {node: '>=10'} + hasBin: true + dependencies: + lru-cache: 6.0.0 + dev: true + /send/0.18.0: resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==} engines: {node: '>= 0.8.0'} @@ -8302,6 +8395,11 @@ packages: /signal-exit/3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + /signal-exit/4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + dev: true + /simple-git-hooks/2.8.1: resolution: {integrity: sha512-DYpcVR1AGtSfFUNzlBdHrQGPsOhuuEJ/FkmPOOlFysP60AHd3nsEpkGq/QEOdtUyT1Qhk7w9oLmFoMG+75BDog==} hasBin: true diff --git a/scripts/publishCI.ts b/scripts/publishCI.ts index 903eb5f36f8733..058c2551d88f2d 100644 --- a/scripts/publishCI.ts +++ b/scripts/publishCI.ts @@ -1,47 +1,10 @@ -import semver from 'semver' -import { - args, - getActiveVersion, - getPackageInfo, - publishPackage, - step -} from './releaseUtils' +;(async () => { + const { publish } = await import('@vitejs/release-scripts') -async function main() { - const tag = args._[0] + // Check the tag passed in CI, and skip provenance if tag has `@` due to + // https://github.com/slsa-framework/slsa-github-generator/pull/2758 not released + const tag = process.argv.slice(2)[0] ?? '' + const provenance = !tag.includes('@') - if (!tag) { - throw new Error('No tag specified') - } - - let pkgName = 'vite' - let version - - if (tag.includes('@')) [pkgName, version] = tag.split('@') - else version = tag - - if (version.startsWith('v')) version = version.slice(1) - - const { currentVersion, pkgDir } = getPackageInfo(pkgName) - if (currentVersion !== version) - throw new Error( - `Package version from tag "${version}" mismatches with current version "${currentVersion}"` - ) - - const activeVersion = await getActiveVersion(pkgName) - - step('Publishing package...') - const releaseTag = version.includes('beta') - ? 'beta' - : version.includes('alpha') - ? 'alpha' - : semver.lt(currentVersion, activeVersion) - ? 'previous' - : undefined - await publishPackage(pkgDir, releaseTag) -} - -main().catch((err) => { - console.error(err) - process.exit(1) -}) + publish({ defaultPackage: 'vite', provenance, packageManager: 'pnpm' }) +})() diff --git a/scripts/release.ts b/scripts/release.ts index 36d9b22f397726..20e8d1c1d96958 100644 --- a/scripts/release.ts +++ b/scripts/release.ts @@ -1,128 +1,30 @@ -import prompts from 'prompts' -import semver from 'semver' import colors from 'picocolors' -import { - args, - getPackageInfo, - getVersionChoices, - isDryRun, - logRecentCommits, - packages, - run, - runIfNotDry, - step, - updateTemplateVersions, - updateVersion -} from './releaseUtils' - -async function main(): Promise { - let targetVersion: string | undefined - - const { pkg }: { pkg: string } = await prompts({ - type: 'select', - name: 'pkg', - message: 'Select package', - choices: packages.map((i) => ({ value: i, title: i })) - }) - - if (!pkg) return - - await logRecentCommits(pkg) - - const { currentVersion, pkgName, pkgPath, pkgDir } = getPackageInfo(pkg) - - if (!targetVersion) { - const { release }: { release: string } = await prompts({ - type: 'select', - name: 'release', - message: 'Select release type', - choices: getVersionChoices(currentVersion) - }) - - if (release === 'custom') { - const res: { version: string } = await prompts({ - type: 'text', - name: 'version', - message: 'Input custom version', - initial: currentVersion - }) - targetVersion = res.version - } else { - targetVersion = release +import { logRecentCommits, run, updateTemplateVersions } from './releaseUtils' +;(async () => { + const { release } = await import('@vitejs/release-scripts') + + release({ + repo: 'vite', + packages: ['vite', 'create-vite', 'plugin-legacy'], + toTag: (pkg, version) => + pkg === 'vite' ? `v${version}` : `${pkg}@${version}`, + logChangelog: (pkg) => logRecentCommits(pkg), + generateChangelog: async (pkgName) => { + if (pkgName === 'create-vite') await updateTemplateVersions() + + console.log(colors.cyan('\nGenerating changelog...')) + const changelogArgs = [ + 'conventional-changelog', + '-p', + 'angular', + '-i', + 'CHANGELOG.md', + '-s', + '--commit-path', + '.' + ] + if (pkgName !== 'vite') changelogArgs.push('--lerna-package', pkgName) + await run('npx', changelogArgs, { cwd: `packages/${pkgName}` }) } - } - - if (!semver.valid(targetVersion)) { - throw new Error(`invalid target version: ${targetVersion}`) - } - - const tag = - pkgName === 'vite' ? `v${targetVersion}` : `${pkgName}@${targetVersion}` - - if (targetVersion.includes('beta') && !args.tag) { - args.tag = 'beta' - } - if (targetVersion.includes('alpha') && !args.tag) { - args.tag = 'alpha' - } - - const { yes }: { yes: boolean } = await prompts({ - type: 'confirm', - name: 'yes', - message: `Releasing ${colors.yellow(tag)} Confirm?` }) - - if (!yes) { - return - } - - step('\nUpdating package version...') - updateVersion(pkgPath, targetVersion) - if (pkgName === 'create-vite') updateTemplateVersions() - - step('\nGenerating changelog...') - const changelogArgs = [ - 'conventional-changelog', - '-p', - 'angular', - '-i', - 'CHANGELOG.md', - '-s', - '--commit-path', - '.' - ] - if (pkgName !== 'vite') changelogArgs.push('--lerna-package', pkgName) - await run('npx', changelogArgs, { cwd: pkgDir }) - - const { stdout } = await run('git', ['diff'], { stdio: 'pipe' }) - if (stdout) { - step('\nCommitting changes...') - await runIfNotDry('git', ['add', '-A']) - await runIfNotDry('git', ['commit', '-m', `release: ${tag}`]) - await runIfNotDry('git', ['tag', tag]) - } else { - console.log('No changes to commit.') - return - } - - step('\nPushing to GitHub...') - await runIfNotDry('git', ['push', 'origin', `refs/tags/${tag}`]) - await runIfNotDry('git', ['push']) - - if (isDryRun) { - console.log(`\nDry run finished - run git diff to see package changes.`) - } else { - console.log( - colors.green( - '\nPushed, publishing should starts shortly on CI.\nhttps://github.com/vitejs/vite/actions/workflows/publish.yml' - ) - ) - } - - console.log() -} - -main().catch((err) => { - console.error(err) - process.exit(1) -}) +})() diff --git a/scripts/releaseUtils.ts b/scripts/releaseUtils.ts index daf51fc9180304..0f5b8943c2933c 100644 --- a/scripts/releaseUtils.ts +++ b/scripts/releaseUtils.ts @@ -1,191 +1,19 @@ -/** - * modified from https://github.com/vuejs/core/blob/master/scripts/release.js - */ -import { existsSync, readdirSync, writeFileSync } from 'node:fs' +import { readdirSync, writeFileSync } from 'node:fs' import path from 'node:path' +import semver from 'semver' import colors from 'picocolors' import type { Options as ExecaOptions, ExecaReturnValue } from 'execa' import { execa } from 'execa' -import type { ReleaseType } from 'semver' -import semver from 'semver' import fs from 'fs-extra' -import minimist from 'minimist' - -export const args = minimist(process.argv.slice(2)) - -export const isDryRun = !!args.dry - -if (isDryRun) { - console.log(colors.inverse(colors.yellow(' DRY RUN '))) - console.log() -} - -export const packages = [ - 'vite', - 'create-vite', - 'plugin-legacy', - 'plugin-react', - 'plugin-vue', - 'plugin-vue-jsx' -] - -export const versionIncrements: ReleaseType[] = [ - 'patch', - 'minor', - 'major' - // 'prepatch', - // 'preminor', - // 'premajor', - // 'prerelease' -] - -interface Pkg { - name: string - version: string - private?: boolean -} -export function getPackageInfo(pkgName: string): { - pkg: Pkg - pkgName: string - pkgDir: string - pkgPath: string - currentVersion: string -} { - const pkgDir = path.resolve(__dirname, '../packages/' + pkgName) - - if (!existsSync(pkgDir)) { - throw new Error(`Package ${pkgName} not found`) - } - - const pkgPath = path.resolve(pkgDir, 'package.json') - const pkg: Pkg = require(pkgPath) - const currentVersion = pkg.version - - if (pkg.private) { - throw new Error(`Package ${pkgName} is private`) - } - - return { - pkg, - pkgName, - pkgDir, - pkgPath, - currentVersion - } -} export async function run( bin: string, args: string[], - opts: ExecaOptions = {} -): Promise> { + opts: ExecaOptions = {} +): Promise { return execa(bin, args, { stdio: 'inherit', ...opts }) } -export async function dryRun( - bin: string, - args: string[], - opts?: ExecaOptions -): Promise { - return console.log( - colors.blue(`[dryrun] ${bin} ${args.join(' ')}`), - opts || '' - ) -} - -export const runIfNotDry = isDryRun ? dryRun : run - -export function step(msg: string): void { - return console.log(colors.cyan(msg)) -} - -interface VersionChoice { - title: string - value: string -} -export function getVersionChoices(currentVersion: string): VersionChoice[] { - const currentBeta = currentVersion.includes('beta') - const currentAlpha = currentVersion.includes('alpha') - const isStable = !currentBeta && !currentAlpha - - function inc(i: ReleaseType, tag = currentAlpha ? 'alpha' : 'beta') { - return semver.inc(currentVersion, i, tag)! - } - - let versionChoices: VersionChoice[] = [ - { - title: 'next', - value: inc(isStable ? 'patch' : 'prerelease') - } - ] - - if (isStable) { - versionChoices.push( - { - title: 'beta-minor', - value: inc('preminor') - }, - { - title: 'beta-major', - value: inc('premajor') - }, - { - title: 'alpha-minor', - value: inc('preminor', 'alpha') - }, - { - title: 'alpha-major', - value: inc('premajor', 'alpha') - }, - { - title: 'minor', - value: inc('minor') - }, - { - title: 'major', - value: inc('major') - } - ) - } else if (currentAlpha) { - versionChoices.push({ - title: 'beta', - value: inc('patch') + '-beta.0' - }) - } else { - versionChoices.push({ - title: 'stable', - value: inc('patch') - }) - } - versionChoices.push({ value: 'custom', title: 'custom' }) - - versionChoices = versionChoices.map((i) => { - i.title = `${i.title} (${i.value})` - return i - }) - - return versionChoices -} - -export function updateVersion(pkgPath: string, version: string): void { - const pkg = fs.readJSONSync(pkgPath) - pkg.version = version - writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n') -} - -export async function publishPackage( - pkdDir: string, - tag?: string -): Promise { - const publicArgs = ['publish', '--access', 'public'] - if (tag) { - publicArgs.push(`--tag`, tag) - } - await runIfNotDry('npm', publicArgs, { - cwd: pkdDir - }) -} - export async function getLatestTag(pkgName: string): Promise { const tags = (await run('git', ['tag'], { stdio: 'pipe' })).stdout .split(/\n/) @@ -193,17 +21,9 @@ export async function getLatestTag(pkgName: string): Promise { const prefix = pkgName === 'vite' ? 'v' : `${pkgName}@` return tags .filter((tag) => tag.startsWith(prefix)) - .sort() - .reverse()[0] -} - -export async function getActiveVersion(pkgName: string): Promise { - const npmName = - pkgName === 'vite' || pkgName === 'create-vite' - ? pkgName - : `@vitejs/${pkgName}` - return (await run('npm', ['info', npmName, 'version'], { stdio: 'pipe' })) - .stdout + .sort((a, b) => + semver.rcompare(a.slice(prefix.length), b.slice(prefix.length)) + )[0] } export async function logRecentCommits(pkgName: string): Promise { @@ -235,38 +55,17 @@ export async function logRecentCommits(pkgName: string): Promise { } export async function updateTemplateVersions(): Promise { - const viteVersion = ( - await fs.readJSON(path.resolve(__dirname, '../packages/vite/package.json')) - ).version + const viteVersion = fs.readJSONSync('packages/vite/package.json').version if (/beta|alpha|rc/.test(viteVersion)) return - const dir = path.resolve(__dirname, '../packages/create-vite') - + const dir = 'packages/create-vite' const templates = readdirSync(dir).filter((dir) => dir.startsWith('template-') ) for (const template of templates) { const pkgPath = path.join(dir, template, `package.json`) - const pkg = require(pkgPath) + const pkg = fs.readJSONSync(pkgPath) pkg.devDependencies.vite = `^` + viteVersion - if (template.startsWith('template-vue')) { - pkg.devDependencies['@vitejs/plugin-vue'] = - `^` + - ( - await fs.readJSON( - path.resolve(__dirname, '../packages/plugin-vue/package.json') - ) - ).version - } - if (template.startsWith('template-react')) { - pkg.devDependencies['@vitejs/plugin-react'] = - `^` + - ( - await fs.readJSON( - path.resolve(__dirname, '../packages/plugin-react/package.json') - ) - ).version - } writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n') } }