|
@@ -9,6 +9,15 @@ import { execa } from 'execa'
|
|
|
import { createRequire } from 'node:module'
|
|
import { createRequire } from 'node:module'
|
|
|
import { fileURLToPath } from 'node:url'
|
|
import { fileURLToPath } from 'node:url'
|
|
|
|
|
|
|
|
|
|
+/**
|
|
|
|
|
+ * @typedef {{
|
|
|
|
|
+ * name: string
|
|
|
|
|
+ * version: string
|
|
|
|
|
+ * dependencies?: { [dependenciesPackageName: string]: string }
|
|
|
|
|
+ * peerDependencies?: { [peerDependenciesPackageName: string]: string }
|
|
|
|
|
+ * }} Package
|
|
|
|
|
+ */
|
|
|
|
|
+
|
|
|
let versionUpdated = false
|
|
let versionUpdated = false
|
|
|
|
|
|
|
|
const { prompt } = enquirer
|
|
const { prompt } = enquirer
|
|
@@ -25,6 +34,7 @@ const args = minimist(process.argv.slice(2), {
|
|
|
|
|
|
|
|
const preId = args.preid || semver.prerelease(currentVersion)?.[0]
|
|
const preId = args.preid || semver.prerelease(currentVersion)?.[0]
|
|
|
const isDryRun = args.dry
|
|
const isDryRun = args.dry
|
|
|
|
|
+/** @type {boolean | undefined} */
|
|
|
let skipTests = args.skipTests
|
|
let skipTests = args.skipTests
|
|
|
const skipBuild = args.skipBuild
|
|
const skipBuild = args.skipBuild
|
|
|
const isCanary = args.canary
|
|
const isCanary = args.canary
|
|
@@ -43,7 +53,7 @@ const packages = fs
|
|
|
}
|
|
}
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
-const isCorePackage = pkgName => {
|
|
|
|
|
|
|
+const isCorePackage = (/** @type {string} */ pkgName) => {
|
|
|
if (!pkgName) return
|
|
if (!pkgName) return
|
|
|
|
|
|
|
|
if (pkgName === 'vue' || pkgName === '@vue/compat') {
|
|
if (pkgName === 'vue' || pkgName === '@vue/compat') {
|
|
@@ -56,7 +66,7 @@ const isCorePackage = pkgName => {
|
|
|
)
|
|
)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-const renamePackageToCanary = pkgName => {
|
|
|
|
|
|
|
+const renamePackageToCanary = (/** @type {string} */ pkgName) => {
|
|
|
if (pkgName === 'vue') {
|
|
if (pkgName === 'vue') {
|
|
|
return '@vue/canary'
|
|
return '@vue/canary'
|
|
|
}
|
|
}
|
|
@@ -68,25 +78,37 @@ const renamePackageToCanary = pkgName => {
|
|
|
return pkgName
|
|
return pkgName
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-const keepThePackageName = pkgName => pkgName
|
|
|
|
|
|
|
+const keepThePackageName = (/** @type {string} */ pkgName) => pkgName
|
|
|
|
|
|
|
|
|
|
+/** @type {string[]} */
|
|
|
const skippedPackages = []
|
|
const skippedPackages = []
|
|
|
|
|
|
|
|
|
|
+/** @type {ReadonlyArray<import('semver').ReleaseType>} */
|
|
|
const versionIncrements = [
|
|
const versionIncrements = [
|
|
|
'patch',
|
|
'patch',
|
|
|
'minor',
|
|
'minor',
|
|
|
'major',
|
|
'major',
|
|
|
- ...(preId ? ['prepatch', 'preminor', 'premajor', 'prerelease'] : [])
|
|
|
|
|
|
|
+ ...(preId
|
|
|
|
|
+ ? /** @type {const} */ (['prepatch', 'preminor', 'premajor', 'prerelease'])
|
|
|
|
|
+ : [])
|
|
|
]
|
|
]
|
|
|
|
|
|
|
|
-const inc = i => semver.inc(currentVersion, i, preId)
|
|
|
|
|
-const run = (bin, args, opts = {}) =>
|
|
|
|
|
- execa(bin, args, { stdio: 'inherit', ...opts })
|
|
|
|
|
-const dryRun = (bin, args, opts = {}) =>
|
|
|
|
|
- console.log(pico.blue(`[dryrun] ${bin} ${args.join(' ')}`), opts)
|
|
|
|
|
|
|
+const inc = (/** @type {import('semver').ReleaseType} */ i) =>
|
|
|
|
|
+ semver.inc(currentVersion, i, preId)
|
|
|
|
|
+const run = async (
|
|
|
|
|
+ /** @type {string} */ bin,
|
|
|
|
|
+ /** @type {ReadonlyArray<string>} */ args,
|
|
|
|
|
+ /** @type {import('execa').Options} */ opts = {}
|
|
|
|
|
+) => execa(bin, args, { stdio: 'inherit', ...opts })
|
|
|
|
|
+const dryRun = async (
|
|
|
|
|
+ /** @type {string} */ bin,
|
|
|
|
|
+ /** @type {ReadonlyArray<string>} */ args,
|
|
|
|
|
+ /** @type {import('execa').Options} */ opts = {}
|
|
|
|
|
+) => console.log(pico.blue(`[dryrun] ${bin} ${args.join(' ')}`), opts)
|
|
|
const runIfNotDry = isDryRun ? dryRun : run
|
|
const runIfNotDry = isDryRun ? dryRun : run
|
|
|
-const getPkgRoot = pkg => path.resolve(__dirname, '../packages/' + pkg)
|
|
|
|
|
-const step = msg => console.log(pico.cyan(msg))
|
|
|
|
|
|
|
+const getPkgRoot = (/** @type {string} */ pkg) =>
|
|
|
|
|
+ path.resolve(__dirname, '../packages/' + pkg)
|
|
|
|
|
+const step = (/** @type {string} */ msg) => console.log(pico.cyan(msg))
|
|
|
|
|
|
|
|
async function main() {
|
|
async function main() {
|
|
|
if (!(await isInSyncWithRemote())) {
|
|
if (!(await isInSyncWithRemote())) {
|
|
@@ -137,7 +159,7 @@ async function main() {
|
|
|
semver.inc(latestSameDayPatch, 'prerelease', args.tag)
|
|
semver.inc(latestSameDayPatch, 'prerelease', args.tag)
|
|
|
)
|
|
)
|
|
|
}
|
|
}
|
|
|
- } catch (e) {
|
|
|
|
|
|
|
+ } catch (/** @type {any} */ e) {
|
|
|
if (/E404/.test(e.message)) {
|
|
if (/E404/.test(e.message)) {
|
|
|
// the first patch version on that day
|
|
// the first patch version on that day
|
|
|
} else {
|
|
} else {
|
|
@@ -150,7 +172,7 @@ async function main() {
|
|
|
|
|
|
|
|
if (!targetVersion) {
|
|
if (!targetVersion) {
|
|
|
// no explicit version, offer suggestions
|
|
// no explicit version, offer suggestions
|
|
|
- // @ts-ignore
|
|
|
|
|
|
|
+ /** @type {{ release: string }} */
|
|
|
const { release } = await prompt({
|
|
const { release } = await prompt({
|
|
|
type: 'select',
|
|
type: 'select',
|
|
|
name: 'release',
|
|
name: 'release',
|
|
@@ -159,16 +181,16 @@ async function main() {
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
if (release === 'custom') {
|
|
if (release === 'custom') {
|
|
|
|
|
+ /** @type {{ version: string }} */
|
|
|
const result = await prompt({
|
|
const result = await prompt({
|
|
|
type: 'input',
|
|
type: 'input',
|
|
|
name: 'version',
|
|
name: 'version',
|
|
|
message: 'Input custom version',
|
|
message: 'Input custom version',
|
|
|
initial: currentVersion
|
|
initial: currentVersion
|
|
|
})
|
|
})
|
|
|
- // @ts-ignore
|
|
|
|
|
targetVersion = result.version
|
|
targetVersion = result.version
|
|
|
} else {
|
|
} else {
|
|
|
- targetVersion = release.match(/\((.*)\)/)[1]
|
|
|
|
|
|
|
+ targetVersion = release.match(/\((.*)\)/)?.[1] ?? ''
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -183,7 +205,7 @@ async function main() {
|
|
|
: `Releasing v${targetVersion}...`
|
|
: `Releasing v${targetVersion}...`
|
|
|
)
|
|
)
|
|
|
} else {
|
|
} else {
|
|
|
- // @ts-ignore
|
|
|
|
|
|
|
+ /** @type {{ yes: boolean }} */
|
|
|
const { yes: confirmRelease } = await prompt({
|
|
const { yes: confirmRelease } = await prompt({
|
|
|
type: 'confirm',
|
|
type: 'confirm',
|
|
|
name: 'yes',
|
|
name: 'yes',
|
|
@@ -201,7 +223,7 @@ async function main() {
|
|
|
skipTests ||= isCIPassed
|
|
skipTests ||= isCIPassed
|
|
|
|
|
|
|
|
if (isCIPassed && !skipPrompts) {
|
|
if (isCIPassed && !skipPrompts) {
|
|
|
- // @ts-ignore
|
|
|
|
|
|
|
+ /** @type {{ yes: boolean }} */
|
|
|
const { yes: promptSkipTests } = await prompt({
|
|
const { yes: promptSkipTests } = await prompt({
|
|
|
type: 'confirm',
|
|
type: 'confirm',
|
|
|
name: 'yes',
|
|
name: 'yes',
|
|
@@ -246,7 +268,7 @@ async function main() {
|
|
|
await run(`pnpm`, ['run', 'changelog'])
|
|
await run(`pnpm`, ['run', 'changelog'])
|
|
|
|
|
|
|
|
if (!skipPrompts) {
|
|
if (!skipPrompts) {
|
|
|
- // @ts-ignore
|
|
|
|
|
|
|
+ /** @type {{ yes: boolean }} */
|
|
|
const { yes: changelogOk } = await prompt({
|
|
const { yes: changelogOk } = await prompt({
|
|
|
type: 'confirm',
|
|
type: 'confirm',
|
|
|
name: 'yes',
|
|
name: 'yes',
|
|
@@ -346,7 +368,7 @@ async function isInSyncWithRemote() {
|
|
|
if (data.sha === (await getSha())) {
|
|
if (data.sha === (await getSha())) {
|
|
|
return true
|
|
return true
|
|
|
} else {
|
|
} else {
|
|
|
- // @ts-ignore
|
|
|
|
|
|
|
+ /** @type {{ yes: boolean }} */
|
|
|
const { yes } = await prompt({
|
|
const { yes } = await prompt({
|
|
|
type: 'confirm',
|
|
type: 'confirm',
|
|
|
name: 'yes',
|
|
name: 'yes',
|
|
@@ -372,6 +394,10 @@ async function getBranch() {
|
|
|
return (await execa('git', ['rev-parse', '--abbrev-ref', 'HEAD'])).stdout
|
|
return (await execa('git', ['rev-parse', '--abbrev-ref', 'HEAD'])).stdout
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+/**
|
|
|
|
|
+ * @param {string} version
|
|
|
|
|
+ * @param {(pkgName: string) => string} getNewPackageName
|
|
|
|
|
+ */
|
|
|
function updateVersions(version, getNewPackageName = keepThePackageName) {
|
|
function updateVersions(version, getNewPackageName = keepThePackageName) {
|
|
|
// 1. update root package.json
|
|
// 1. update root package.json
|
|
|
updatePackage(path.resolve(__dirname, '..'), version, getNewPackageName)
|
|
updatePackage(path.resolve(__dirname, '..'), version, getNewPackageName)
|
|
@@ -381,8 +407,14 @@ function updateVersions(version, getNewPackageName = keepThePackageName) {
|
|
|
)
|
|
)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+/**
|
|
|
|
|
+ * @param {string} pkgRoot
|
|
|
|
|
+ * @param {string} version
|
|
|
|
|
+ * @param {(pkgName: string) => string} getNewPackageName
|
|
|
|
|
+ */
|
|
|
function updatePackage(pkgRoot, version, getNewPackageName) {
|
|
function updatePackage(pkgRoot, version, getNewPackageName) {
|
|
|
const pkgPath = path.resolve(pkgRoot, 'package.json')
|
|
const pkgPath = path.resolve(pkgRoot, 'package.json')
|
|
|
|
|
+ /** @type {Package} */
|
|
|
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'))
|
|
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'))
|
|
|
pkg.name = getNewPackageName(pkg.name)
|
|
pkg.name = getNewPackageName(pkg.name)
|
|
|
pkg.version = version
|
|
pkg.version = version
|
|
@@ -393,6 +425,12 @@ function updatePackage(pkgRoot, version, getNewPackageName) {
|
|
|
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n')
|
|
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n')
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+/**
|
|
|
|
|
+ * @param {Package} pkg
|
|
|
|
|
+ * @param {'dependencies' | 'peerDependencies'} depType
|
|
|
|
|
+ * @param {string} version
|
|
|
|
|
+ * @param {(pkgName: string) => string} getNewPackageName
|
|
|
|
|
+ */
|
|
|
function updateDeps(pkg, depType, version, getNewPackageName) {
|
|
function updateDeps(pkg, depType, version, getNewPackageName) {
|
|
|
const deps = pkg[depType]
|
|
const deps = pkg[depType]
|
|
|
if (!deps) return
|
|
if (!deps) return
|
|
@@ -408,6 +446,11 @@ function updateDeps(pkg, depType, version, getNewPackageName) {
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+/**
|
|
|
|
|
+ * @param {string} pkgName
|
|
|
|
|
+ * @param {string} version
|
|
|
|
|
+ * @param {ReadonlyArray<string>} additionalFlags
|
|
|
|
|
+ */
|
|
|
async function publishPackage(pkgName, version, additionalFlags) {
|
|
async function publishPackage(pkgName, version, additionalFlags) {
|
|
|
if (skippedPackages.includes(pkgName)) {
|
|
if (skippedPackages.includes(pkgName)) {
|
|
|
return
|
|
return
|
|
@@ -443,7 +486,7 @@ async function publishPackage(pkgName, version, additionalFlags) {
|
|
|
}
|
|
}
|
|
|
)
|
|
)
|
|
|
console.log(pico.green(`Successfully published ${pkgName}@${version}`))
|
|
console.log(pico.green(`Successfully published ${pkgName}@${version}`))
|
|
|
- } catch (e) {
|
|
|
|
|
|
|
+ } catch (/** @type {any} */ e) {
|
|
|
if (e.stderr.match(/previously published/)) {
|
|
if (e.stderr.match(/previously published/)) {
|
|
|
console.log(pico.red(`Skipping already published: ${pkgName}`))
|
|
console.log(pico.red(`Skipping already published: ${pkgName}`))
|
|
|
} else {
|
|
} else {
|