|
1 |
| -import fs from 'node:fs' |
2 |
| -import path from 'node:path' |
| 1 | +import { resolve } from 'node:path' |
3 | 2 | import { fileURLToPath } from 'node:url'
|
4 | 3 |
|
5 | 4 | import minimist from 'minimist'
|
6 |
| -import semver from 'semver' |
7 |
| -import prompts from 'prompts' |
8 |
| -import { dryRun, logger, run } from './utils' |
9 |
| - |
10 |
| -import type { ReleaseType } from 'semver' |
| 5 | +import { logger, release, run } from '@vexip-ui/scripts' |
11 | 6 |
|
12 | 7 | const args = minimist<{
|
13 | 8 | d?: boolean,
|
14 | 9 | dry?: boolean,
|
15 |
| - t?: string, |
16 |
| - tag?: string |
| 10 | + p: string, |
| 11 | + preid?: string |
17 | 12 | }>(process.argv.slice(2))
|
18 | 13 |
|
19 | 14 | const isDryRun = args.dry || args.d
|
20 |
| -const releaseTag = args.tag || args.t |
21 |
| - |
22 |
| -const runIfNotDry = isDryRun ? dryRun : run |
23 |
| -const logStep = (msg: string) => logger.withStartLn(() => logger.infoText(msg)) |
24 |
| -const logSkipped = (msg = 'Skipped') => logger.warningText(`(${msg})`) |
25 | 15 |
|
26 |
| -main().catch(error => { |
| 16 | +const rootDir = resolve(fileURLToPath(import.meta.url), '../..') |
| 17 | + |
| 18 | +release({ |
| 19 | + pkgDir: resolve(rootDir, 'package.json'), |
| 20 | + isDryRun, |
| 21 | + preId: args.preid, |
| 22 | + publish: true, |
| 23 | + runTest: () => run('pnpm', ['test']), |
| 24 | + runBuild: () => run('pnpm', ['build']), |
| 25 | + runChangelog: () => run('pnpm', ['changelog']) |
| 26 | +}).catch(error => { |
27 | 27 | logger.error(error)
|
28 | 28 | process.exit(1)
|
29 | 29 | })
|
30 |
| - |
31 |
| -async function main() { |
32 |
| - const rootDir = path.resolve(fileURLToPath(import.meta.url), '../..') |
33 |
| - const pkg = JSON.parse( |
34 |
| - fs.readFileSync(path.join(rootDir, 'package.json'), 'utf-8') |
35 |
| - ) |
36 |
| - const currentVersion = pkg.version |
37 |
| - const preId = args.preid || args.p || (semver.prerelease(currentVersion)?.[0]) |
38 |
| - |
39 |
| - const versionIncrements: ReleaseType[] = [ |
40 |
| - 'patch', |
41 |
| - 'minor', |
42 |
| - 'major', |
43 |
| - ...(preId ? ['prepatch', 'preminor', 'premajor', 'prerelease'] as const : []) |
44 |
| - ] |
45 |
| - |
46 |
| - const inc = (i: ReleaseType) => semver.inc(currentVersion, i, preId) |
47 |
| - |
48 |
| - const { release } = await prompts({ |
49 |
| - type: 'select', |
50 |
| - name: 'release', |
51 |
| - message: 'Select release type:', |
52 |
| - choices: versionIncrements |
53 |
| - .map(i => `${i} (${inc(i)})`) |
54 |
| - .concat(['custom']) |
55 |
| - .map(i => ({ title: i, value: i })) |
56 |
| - }) |
57 |
| - |
58 |
| - const version = |
59 |
| - release === 'custom' |
60 |
| - ? (await prompts({ |
61 |
| - type: 'text', |
62 |
| - name: 'version', |
63 |
| - message: 'Input custom version:' |
64 |
| - })).version |
65 |
| - : release.match(/\((.*)\)/)![1] |
66 |
| - |
67 |
| - if (!semver.valid(version)) { |
68 |
| - throw new Error(`Invalid target version: ${version}`) |
69 |
| - } |
70 |
| - |
71 |
| - const { confirm } = await prompts([ |
72 |
| - { |
73 |
| - type: 'confirm', |
74 |
| - name: 'confirm', |
75 |
| - message: `Confirm release v${version}?` |
76 |
| - } |
77 |
| - ]) |
78 |
| - |
79 |
| - if (!confirm) return |
80 |
| - |
81 |
| - // 执行单元测试 |
82 |
| - logStep('Running test...') |
83 |
| - |
84 |
| - if (!isDryRun) { |
85 |
| - await run('pnpm', ['test']) |
86 |
| - } else { |
87 |
| - logSkipped() |
88 |
| - } |
89 |
| - |
90 |
| - logStep('Updating version...') |
91 |
| - |
92 |
| - pkg.version = version |
93 |
| - fs.writeFileSync(path.resolve(rootDir, 'package.json'), JSON.stringify(pkg, null, 2) + '\n') |
94 |
| - |
95 |
| - // 构建库 |
96 |
| - logStep('Building package...') |
97 |
| - |
98 |
| - if (!isDryRun) { |
99 |
| - await run('pnpm', ['build']) |
100 |
| - } else { |
101 |
| - logSkipped() |
102 |
| - } |
103 |
| - |
104 |
| - // 更新 Change Log |
105 |
| - logStep('Updating changelog...') |
106 |
| - |
107 |
| - await run('pnpm', ['changelog']) |
108 |
| - |
109 |
| - // 提交改动 |
110 |
| - logStep('Comitting changes...') |
111 |
| - |
112 |
| - const { stdout } = await run('git', ['diff'], { stdio: 'pipe' }) |
113 |
| - |
114 |
| - if (stdout) { |
115 |
| - await runIfNotDry('git', ['add', '-A']) |
116 |
| - await runIfNotDry('git', ['commit', '-m', `release: v${version}`]) |
117 |
| - await runIfNotDry('git', ['tag', `v${version}`]) |
118 |
| - } else { |
119 |
| - logSkipped('No changes to commit') |
120 |
| - } |
121 |
| - |
122 |
| - // 发布 |
123 |
| - logStep('Publishing package...') |
124 |
| - |
125 |
| - const publishArgs = [ |
126 |
| - 'publish', |
127 |
| - '--access', |
128 |
| - 'public', |
129 |
| - '--registry', |
130 |
| - 'https://registry.npmjs.org/', |
131 |
| - '--no-git-checks' |
132 |
| - ] |
133 |
| - |
134 |
| - if (isDryRun) { |
135 |
| - publishArgs.push('--dry-run') |
136 |
| - } |
137 |
| - |
138 |
| - if (releaseTag) { |
139 |
| - publishArgs.push('--tag', releaseTag) |
140 |
| - } |
141 |
| - |
142 |
| - try { |
143 |
| - await run('pnpm', publishArgs, { stdio: 'pipe' }) |
144 |
| - logger.successText(`Successfully published v${version}'`) |
145 |
| - } catch (err: any) { |
146 |
| - if (err.stderr?.match(/previously published/)) { |
147 |
| - logger.errorText(`Skipping already published v'${version}'`) |
148 |
| - } else { |
149 |
| - throw err |
150 |
| - } |
151 |
| - } |
152 |
| - |
153 |
| - // 推送到远程仓库 |
154 |
| - logStep('Pushing to Remote Repository...') |
155 |
| - |
156 |
| - await runIfNotDry('git', ['push', 'origin', `refs/tags/v${version}`]) |
157 |
| - await runIfNotDry('git', ['push']) |
158 |
| - |
159 |
| - logger.withBothLn(() => { |
160 |
| - if (isDryRun) { |
161 |
| - logger.success('Dry run finished - run git diff to see package changes') |
162 |
| - } else { |
163 |
| - logger.success('Release successfully') |
164 |
| - } |
165 |
| - }) |
166 |
| -} |
0 commit comments