11import path from 'path' ;
22import * as url from 'url' ;
3+ import cac from 'cac' ;
34import { $ } from 'execa' ;
45import fs from 'fs-extra' ;
5- import { inc } from 'semver' ;
66
7- const RELEASE_TAG = process . env . TAG || 'beta' ;
8- const RELEASE_DRY_RUN = process . env . DRY_RUN || 'true' ;
9- const RELEASE_VERSION_TYPE = process . env . VERSION || 'prerelease' ;
7+ let cli = cac ( 'release' ) ;
8+ cli . option (
9+ '--dry-run <run>' ,
10+ 'Perform a dry run without publishing or pushing tags' ,
11+ {
12+ default : 'false' ,
13+ } ,
14+ ) ;
15+ cli . option ( '--tag <tag>' , 'The npm tag to publish under (default: canary)' , {
16+ default : 'canary' ,
17+ } ) ;
1018
1119const __dirname = url . fileURLToPath ( new URL ( '.' , import . meta. url ) ) ;
1220const PKG_PATH = path . resolve ( __dirname , '../package.json' ) ;
1321const pkg = fs . readJsonSync ( PKG_PATH ) ;
14- const currentVersion = pkg . version ;
15- const nextVersion = inc ( currentVersion , RELEASE_VERSION_TYPE ) ;
16- if ( ! nextVersion ) {
22+ const publishVersion = pkg . version ;
23+
24+ const parsed = cli . parse ( ) ;
25+ const npmTag = parsed . options . tag ;
26+ const isDryRun = parsed . options . dryRun ;
27+
28+ const allowedTags = [ 'latest' , 'canary' , 'alpha' , 'beta' , 'rc' ] ;
29+ if ( ! allowedTags . includes ( npmTag ) ) {
1730 throw new Error (
18- `Failed to generate next version from " ${ currentVersion } " with type " ${ RELEASE_VERSION_TYPE } " ` ,
31+ `Invalid npm tag: ${ npmTag } . Allowed tags: ${ allowedTags . join ( ', ' ) } ` ,
1932 ) ;
2033}
2134
22- console . info ( `Release ${ RELEASE_TAG } version ${ nextVersion } ` ) ;
23-
24- // Update pkg version
25- console . info ( `Updating version from ${ currentVersion } to ${ nextVersion } ` ) ;
26- pkg . version = nextVersion ;
27- fs . writeJsonSync ( PKG_PATH , pkg , { spaces : 2 } ) ;
35+ const prereleaseTags = [ 'alpha' , 'beta' , 'rc' , 'canary' ] ;
36+ if (
37+ npmTag === 'latest' &&
38+ prereleaseTags . some ( ( tag ) => publishVersion . includes ( tag ) )
39+ ) {
40+ throw Error ( `Can't release ${ publishVersion } to latest tag` ) ;
41+ }
2842
29- // Publish to npm
30- console . info ( `Publishing to npm with tag ${ RELEASE_TAG } ` ) ;
31- const dryRun = RELEASE_DRY_RUN === 'true' ? [ '--dry-run' ] : [ ] ;
43+ console . info ( `Release ${ npmTag } version ${ publishVersion } ` ) ;
3244
3345try {
34- await $ `pnpm publish ${ dryRun } --tag ${ RELEASE_TAG } --no-git-checks` ;
46+ const flags = isDryRun
47+ ? [ '--dry-run' , `--tag` , npmTag , `--no-git-checks` ]
48+ : [ `--tag` , npmTag , `--no-git-checks` ] ;
49+ await $ `pnpm publish ${ flags } ` ;
3550 console . info ( `Published successfully` ) ;
3651} catch ( e ) {
3752 console . error ( `Publish failed: ${ e . message } ` ) ;
3853 process . exit ( 1 ) ;
3954}
4055
41- // Push tag to github
42- if ( RELEASE_DRY_RUN !== 'true' ) {
56+ // Push tag to GitHub
57+ if ( ! isDryRun ) {
4358 console . info ( `Pushing tag to github` ) ;
44- const tagName = `v${ nextVersion } ` ;
59+ const tagName = `v${ publishVersion } ` ;
4560 try {
4661 await $ `git config --global --add safe.directory /github/workspace` ;
4762 await $ `git config --global user.name "github-actions[bot]"` ;
@@ -54,17 +69,6 @@ if (RELEASE_DRY_RUN !== 'true') {
5469 console . error ( `Push tag failed: ${ e . message } ` ) ;
5570 process . exit ( 1 ) ;
5671 }
57-
58- try {
59- await $ `git add --all` ;
60- const commitMsg = `release ${ tagName } ` ;
61- await $ `git commit -m ${ commitMsg } ` ;
62- await $ `git push` ;
63- console . info ( `Pushed branch successfully` ) ;
64- } catch ( e ) {
65- console . error ( `Update branch failed: ${ e . message } ` ) ;
66- process . exit ( 1 ) ;
67- }
6872}
6973
7074console . info ( `Release completed` ) ;
0 commit comments