chore: 优化发布流程

This commit is contained in:
winixt 2025-09-10 11:39:33 +08:00
parent 720296fc82
commit c1fa59fcf8
9 changed files with 340 additions and 894 deletions

2
.npmrc
View File

@ -1,2 +1,4 @@
registry=https://registry.npmmirror.com
link-workspace-packages=true
prefer-workspace-packages=true
shamefully-hoist=true

View File

@ -32,11 +32,11 @@
"hooks:sync": "simple-git-hooks"
},
"dependencies": {
"chalk": "^5.0.1",
"conventional-changelog-cli": "^4.1.0",
"enquirer": "^2.3.6",
"consola": "^3.4.2",
"conventional-changelog-cli": "^5.0.0",
"execa": "^6.1.0",
"minimist": "^1.2.6",
"picocolors": "^1.1.1",
"semver": "^7.3.6",
"tsup": "^8.5.0",
"turbo": "^2.5.6"
@ -55,8 +55,7 @@
"simple-git-hooks": "^2.9.0",
"typescript": "^5.9.2",
"vitepress": "1.0.0-alpha.73",
"vue": "^3.5.21",
"yargs-parser": "^21.1.1"
"vue": "^3.5.21"
},
"simple-git-hooks": {
"pre-commit": "npx lint-staged",

View File

@ -15,14 +15,14 @@
"access": "public"
},
"dependencies": {
"@fesjs/builder-vite": "file:../../../builder-vite",
"@fesjs/fes": "file:../../../fes",
"@fesjs/builder-vite": "workspace:*",
"@fesjs/fes": "workspace:*",
"@fesjs/fes-design": "^0.8.0",
"@fesjs/plugin-access": "file:../../../plugin-access",
"@fesjs/plugin-layout": "file:../../../plugin-layout",
"@fesjs/plugin-model": "file:../../../plugin-model",
"@fesjs/plugin-qiankun": "file:../../../plugin-qiankun",
"@fesjs/plugin-watermark": "file:../../../plugin-watermark",
"@fesjs/plugin-access": "workspace:*",
"@fesjs/plugin-layout": "workspace:*",
"@fesjs/plugin-model": "workspace:*",
"@fesjs/plugin-qiankun": "workspace:*",
"@fesjs/plugin-watermark": "workspace:*",
"vue": "^3.5.21"
}
}

View File

@ -14,11 +14,11 @@
"access": "public"
},
"dependencies": {
"@fesjs/builder-vite": "file:../../../builder-vite",
"@fesjs/fes": "file:../../../fes",
"@fesjs/builder-vite": "workspace:*",
"@fesjs/fes": "workspace:*",
"@fesjs/fes-design": "^0.8.0",
"@fesjs/plugin-qiankun": "file:../../../plugin-qiankun",
"@fesjs/plugin-watermark": "file:../../../plugin-watermark",
"@fesjs/plugin-qiankun": "workspace:*",
"@fesjs/plugin-watermark": "workspace:*",
"vue": "^3.5.21"
}
}

View File

@ -16,14 +16,14 @@
"access": "public"
},
"dependencies": {
"@fesjs/builder-webpack": "file:../../../builder-webpack",
"@fesjs/fes": "file:../../../fes",
"@fesjs/builder-webpack": "workspace:*",
"@fesjs/fes": "workspace:*",
"@fesjs/fes-design": "^0.8.0",
"@fesjs/plugin-access": "file:../../../plugin-access",
"@fesjs/plugin-layout": "file:../../../plugin-layout",
"@fesjs/plugin-model": "file:../../../plugin-model",
"@fesjs/plugin-qiankun": "file:../../../plugin-qiankun",
"@fesjs/plugin-watermark": "file:../../../plugin-watermark",
"@fesjs/plugin-access": "workspace:*",
"@fesjs/plugin-layout": "workspace:*",
"@fesjs/plugin-model": "workspace:*",
"@fesjs/plugin-qiankun": "workspace:*",
"@fesjs/plugin-watermark": "workspace:*",
"vue": "^3.5.21"
}
}

View File

@ -19,11 +19,11 @@
"access": "public"
},
"dependencies": {
"@fesjs/builder-webpack": "file:../../../builder-webpack",
"@fesjs/fes": "file:../../../fes",
"@fesjs/builder-webpack": "workspace:*",
"@fesjs/fes": "workspace:*",
"@fesjs/fes-design": "^0.8.0",
"@fesjs/plugin-qiankun": "file:../../../plugin-qiankun",
"@fesjs/plugin-watermark": "file:../../../plugin-watermark",
"@fesjs/plugin-qiankun": "workspace:*",
"@fesjs/plugin-watermark": "workspace:*",
"vue": "^3.5.21"
}
}

1089
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@ -2,19 +2,18 @@ import fs from 'node:fs';
import path from 'node:path';
import process from 'node:process';
import * as url from 'node:url';
import chalk from 'chalk';
import enquirer from 'enquirer';
import consola from 'consola';
import { execa } from 'execa';
import minimist from 'minimist';
import pc from 'picocolors';
import semver from 'semver';
import { getPublicPkgs } from './shared.mjs';
import buildConfig from '../build.config.js';
const { prompt } = enquirer;
const __dirname = url.fileURLToPath(new URL('.', import.meta.url));
const { preid: preId, dry: isDryRun } = minimist(process.argv.slice(2));
const packages = buildConfig.pkgs;
const packages = getPublicPkgs();
const versionIncrements = ['patch', 'minor', 'major', 'prepatch', 'preminor', 'premajor', 'prerelease'];
@ -35,10 +34,10 @@ function autoIncVersion(version) {
}
const run = (bin, args, opts = {}) => execa(bin, args, { stdio: 'inherit', ...opts });
const dryRun = (bin, args, opts = {}) => console.log(chalk.blue(`[dryrun] ${bin} ${args.join(' ')}`), opts);
const dryRun = (bin, args, opts = {}) => consola.info(`[dryrun] ${bin} ${args.join(' ')}`, opts);
const runIfNotDry = isDryRun ? dryRun : run;
const getPkgRoot = pkg => path.resolve(__dirname, `../packages/${pkg}`);
const step = msg => console.log(chalk.cyan(msg));
const step = msg => consola.log(msg);
function arrToObj(arr, key) {
return arr.reduce((acc, cur) => {
acc[cur[key]] = cur;
@ -55,8 +54,6 @@ async function publishPackage(pkg, runIfNotDry) {
}
await runIfNotDry(
// note: use of pnpm is intentional here as we rely on its publishing
// behavior.
'npm',
['publish', ...(_releaseTag ? ['--tag', _releaseTag] : []), '--access', 'public', '--registry', 'https://registry.npmjs.org'],
{
@ -64,11 +61,11 @@ async function publishPackage(pkg, runIfNotDry) {
stdio: 'pipe',
},
);
console.log('Successfully published :', chalk.green(`${pkg.name}@${pkg.newVersion}`));
console.log('Successfully published :', pc.green(`${pkg.name}@${pkg.newVersion}`));
}
catch (e) {
if (e.stderr.match(/previously published/)) {
console.log(chalk.red(`Skipping already published: ${pkg.name}`));
console.log(pc.red(`Skipping already published: ${pkg.name}`));
}
else { throw e; }
@ -143,26 +140,25 @@ async function filterChangedPackages() {
async function createPackageNewVersion(name, version) {
// no explicit version, offer suggestions
const { release } = await prompt({
const release = await consola.prompt(`Select release type: ${name}`, {
type: 'select',
name: 'release',
message: `Select release type: ${name}`,
choices: versionIncrements.map(i => `${i} (${incVersion(version, i)})`).concat(['custom']),
options: versionIncrements.map((i) => {
return {
value: incVersion(version, i),
label: `${i} (${incVersion(version, i)})`,
};
}).concat({
value: 'custom',
label: 'custom',
}),
});
let newVersion;
let newVersion = release;
if (release === 'custom') {
newVersion = (
await prompt({
type: 'input',
name: 'version',
message: `Input custom version: ${name}`,
initial: version,
})
).version;
}
else {
newVersion = release.match(/\((.*)\)/)[1];
newVersion = await consola.prompt(`Input custom version: ${name}`, {
type: 'text',
default: version,
});
}
if (!semver.valid(newVersion)) {
@ -217,7 +213,7 @@ async function main() {
const changedPackages = await filterChangedPackages();
if (!changedPackages.length) {
console.log(chalk.yellow(`No changes to commit.`));
consola.warn(`No changes to commit.`);
return;
}
@ -235,12 +231,10 @@ async function main() {
const passiveUpdatePkgs = genOtherPkgsVersion(updatedPkgs);
const packagesVersion = passiveUpdatePkgs.concat(updatedPkgs);
const { yes } = await prompt({
const yes = await consola.prompt(`These packages will be released: \n${packagesVersion
.map(pkg => `${pc.magenta(pkg.name)}: v${pkg.version} > ${pc.green(`v${pkg.newVersion}`)}`)
.join('\n')}\nConfirm?`, {
type: 'confirm',
name: 'yes',
message: `These packages will be released: \n${packagesVersion
.map(pkg => `${chalk.magenta(pkg.name)}: v${pkg.version} > ${chalk.green(`v${pkg.newVersion}`)}`)
.join('\n')}\nConfirm?`,
});
if (!yes) {

View File

@ -1,5 +1,31 @@
import { copyFileSync, mkdirSync, readdirSync } from 'node:fs';
import { copyFileSync, mkdirSync, readdirSync, readFileSync } from 'node:fs';
import { dirname, join } from 'node:path';
import process from 'node:process';
export function getPublicPkgs() {
const packagesDir = join(process.cwd(), 'packages');
const dirs = readdirSync(packagesDir, { withFileTypes: true })
.filter(dirent => dirent.isDirectory())
.map(dirent => dirent.name);
const publicPkgs = [];
for (const dir of dirs) {
const pkgJsonPath = join(packagesDir, dir, 'package.json');
try {
const pkgJson = JSON.parse(readFileSync(pkgJsonPath, 'utf8'));
// 如果没有 private 字段或者 private 为 false则是需要发布的包
if (!pkgJson.private) {
publicPkgs.push(dir);
}
}
catch (error) {
// 如果读取或解析 package.json 失败,跳过该目录
console.warn(`Warning: Could not read package.json for ${dir}`, error.message);
}
}
return publicPkgs;
}
export function copyTplFiles(srcDir, dstDir) {
function walk(currentSrc, currentDst) {