diff --git a/README.md b/README.md index 361e082..3a37f7c 100644 --- a/README.md +++ b/README.md @@ -68,8 +68,8 @@ npx vr publish | Params | Instructions | | ---------------------- | ------------------- | | -r --remote \ | Specify remote name | -| -s --skip-npm-publish | Skip npm publish | -| -sgt --skip-git-tag | Skip git tag | +| -s --skip-npm-publish | Skip npm publish | +| -sgt --skip-git-tag | Skip git tag | #### changelog @@ -89,9 +89,9 @@ npx vr publish #### publish -```shell -vr publish -``` +| 参数 | 说明 | +| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | +| -c --check-remote-version | Detects whether the remote version of the npm package is the same as the package version to be published locally, and if it is, skip the release | ### Custom Handle @@ -120,7 +120,11 @@ release({ task }) #### Types ```ts -function publish(preRelease: boolean | undefined): Promise +interface PublishCommandOptions { + preRelease?: boolean + checkRemoteVersion?: boolean +} +function publish({ preRelease, checkRemoteVersion }: PublishCommandOptions): Promise function updateVersion(version: string): void interface ReleaseCommandOptions { remote?: string diff --git a/README.zh-CN.md b/README.zh-CN.md index bffc49e..21d2c51 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -68,8 +68,8 @@ npx vr publish | 参数 | 说明 | | ---------------------- | ---------------- | | -r --remote \ | 指定远程仓库名称 | -| -s --skip-npm-publish | 跳过 npm 发布 | -| -sgt --skip-git-tag | 跳过 git tag | +| -s --skip-npm-publish | 跳过 npm 发布 | +| -sgt --skip-git-tag | 跳过 git tag | #### changelog @@ -89,9 +89,9 @@ npx vr publish #### publish -```shell -vr publish -``` +| 参数 | 说明 | +| ------------------------- | --------------------------------------------------------------------- | +| -c --check-remote-version | 检测npm包的远程版本是否与要在本地发布的包版本相同,如果是,则跳过发布 | ### 自定义处理 @@ -120,7 +120,11 @@ release({ task }) #### 类型 ```ts -function publish(preRelease: boolean | undefined): Promise +interface PublishCommandOptions { + preRelease?: boolean + checkRemoteVersion?: boolean +} +function publish({ preRelease, checkRemoteVersion }: PublishCommandOptions): Promise function updateVersion(version: string): void interface ReleaseCommandOptions { remote?: string diff --git a/bin/index.js b/bin/index.js index 2701fcf..78a50c3 100644 --- a/bin/index.js +++ b/bin/index.js @@ -14,8 +14,9 @@ program program .command('publish') + .option('-c --check-remote-version', 'Check remote version') .description('Publish to npm') - .action(async () => publish()) + .action(async (options) => publish(options)) program .command('changelog') diff --git a/src/release.ts b/src/release.ts index 5f0b067..113adb8 100644 --- a/src/release.ts +++ b/src/release.ts @@ -1,6 +1,6 @@ import fse from 'fs-extra' import logger from './logger' -import semver from 'semver' +import semver, { type ReleaseType } from 'semver' import inquirer from 'inquirer' import { execa } from 'execa' import { createSpinner } from 'nanospinner' @@ -19,10 +19,30 @@ async function isWorktreeEmpty() { return !ret.stdout } -export async function publish(preRelease: boolean | undefined) { +interface PublishCommandOptions { + preRelease?: boolean + checkRemoteVersion?: boolean +} +export async function publish({ preRelease, checkRemoteVersion }: PublishCommandOptions) { const s = createSpinner('Publishing all packages').start() const args = ['-r', 'publish', '--no-git-checks', '--access', 'public'] + if (checkRemoteVersion) { + const packageJson = getPackageJsons().find((packageJson) => !packageJson.config.private) + if (packageJson) { + const { config } = packageJson + try { + await execa('npm', ['view', `${config.name}@${config.version}`, 'version']) + s.warn({ + text: `The npm package has a same remote version ${config.version}, publishing automatically skipped.`, + }) + return + } catch { + /* empty */ + } + } + } + if (preRelease) { args.push('--tag', 'alpha') } @@ -51,16 +71,28 @@ async function pushGit(version: string, remote = 'origin', skipGitTag = false) { ret.stdout && logger.info(ret.stdout) } -export function updateVersion(version: string) { - const packageJsons = glob.sync('packages/*/package.json') - packageJsons.push('package.json') +function getPackageJsons() { + const packageJsons = ['package.json', ...glob.sync('packages/*/package.json')] + + return packageJsons.map((path) => { + const filePath = resolve(cwd, path) + return { + config: readJSONSync(filePath) as { + name: string + version: string + private: boolean + }, + filePath, + } + }) +} - packageJsons.forEach((path: string) => { - const file = resolve(cwd, path) - const config = readJSONSync(file) +export function updateVersion(version: string) { + const packageJsons = getPackageJsons() + packageJsons.forEach(({ config, filePath }) => { config.version = version - writeFileSync(file, JSON.stringify(config, null, 2)) + writeFileSync(filePath, JSON.stringify(config, null, 2)) }) } @@ -109,7 +141,7 @@ async function confirmRefs(remote = 'origin') { return ret[name] } -async function getReleaseType() { +async function getReleaseType(): Promise { const name = 'Please select release type' const ret = await prompt([ { @@ -167,7 +199,7 @@ export async function release(options: ReleaseCommandOptions) { } if (!options.skipNpmPublish) { - await publish(isPreRelease) + await publish({ preRelease: isPreRelease }) } if (!isPreRelease) {