1+ import * as readline from "node:readline/promises" ;
2+ import { program } from "commander" ;
13import * as semver from "semver" ;
2- import { $ , argv , chalk } from "zx" ;
4+ import { $ , chalk } from "zx" ;
35
46async function main ( ) {
7+ // Setup commander
8+ program
9+ . name ( "release" )
10+ . description ( "Release a new version of RivetKit" )
11+ . version ( "1.0.0" , "-v, --cli-version" , "Show CLI version" )
12+ . option ( "--major" , "Bump major version" )
13+ . option ( "--minor" , "Bump minor version" )
14+ . option ( "--patch" , "Bump patch version" )
15+ . option ( "--version <version>" , "Set specific version" )
16+ . argument ( "[version]" , "Version to release (legacy format)" )
17+ . parse ( ) ;
18+
19+ // Get version from arguments or calculate based on flags
20+ const version = await getVersionFromArgs ( program . opts ( ) , program . args ) ;
21+
22+ // Confirm before proceeding
23+ const confirmed = await confirmRelease ( version ) ;
24+ if ( ! confirmed ) {
25+ console . log ( chalk . yellow ( "Release cancelled" ) ) ;
26+ process . exit ( 0 ) ;
27+ }
28+
529 // Clean the workspace first
630 await cleanWorkspace ( ) ;
731
@@ -10,7 +34,6 @@ async function main() {
1034 // await checkPythonEnvironment();
1135
1236 // Update version
13- const version = getVersionFromArgs ( ) ;
1437 await bumpPackageVersions ( version ) ;
1538 // await updateRustClientVersion(version);
1639 // await updatePythonClientVersion(version);
@@ -37,6 +60,27 @@ async function main() {
3760 await createGitHubRelease ( version ) ;
3861}
3962
63+ async function confirmRelease ( version : string ) : Promise < boolean > {
64+ console . log (
65+ chalk . blue ( "\n📦 About to release version:" ) ,
66+ chalk . yellow . bold ( version ) ,
67+ ) ;
68+
69+ const rl = readline . createInterface ( {
70+ input : process . stdin ,
71+ output : process . stdout ,
72+ } ) ;
73+
74+ try {
75+ const answer = await rl . question (
76+ chalk . cyan ( "\nDo you want to proceed with the release? (y/N): " ) ,
77+ ) ;
78+ return answer . toLowerCase ( ) === "y" || answer . toLowerCase ( ) === "yes" ;
79+ } finally {
80+ rl . close ( ) ;
81+ }
82+ }
83+
4084async function runTypeCheck ( ) {
4185 console . log ( chalk . blue ( "Checking types..." ) ) ;
4286 try {
@@ -291,15 +335,60 @@ async function checkPythonEnvironment() {
291335 console . log ( chalk . green ( "✅ Python environment is good" ) ) ;
292336}
293337
294- function getVersionFromArgs ( ) {
295- const version = argv . _ [ 0 ] ;
338+ async function getCurrentVersion ( ) : Promise < string > {
339+ // Get version from the main package
340+ const { stdout } =
341+ await $ `cat packages/rivetkit/package.json | jq -r '.version'` ;
342+ const version = stdout . trim ( ) ;
343+ return version ;
344+ }
345+
346+ async function getVersionFromArgs (
347+ options : any ,
348+ args : string [ ] ,
349+ ) : Promise < string > {
350+ // Check if explicit version is provided via --version flag
351+ if ( options . version ) {
352+ const version = options . version ;
353+ validateVersion ( version ) ;
354+ return version ;
355+ }
356+
357+ // Check if version provided as positional argument (legacy)
358+ if ( args [ 0 ] ) {
359+ const version = args [ 0 ] ;
360+ validateVersion ( version ) ;
361+ return version ;
362+ }
363+
364+ // Check for version bump flags
365+ if ( ! options . major && ! options . minor && ! options . patch ) {
366+ program . help ( ) ;
367+ }
368+
369+ // Get current version and calculate new one
370+ const currentVersion = await getCurrentVersion ( ) ;
371+ console . log ( chalk . blue ( "Current version:" ) , currentVersion ) ;
372+
373+ let newVersion : string | null = null ;
296374
297- if ( ! version ) {
298- console . error ( "Usage: tsx publish.ts <version>" ) ;
375+ if ( options . major ) {
376+ newVersion = semver . inc ( currentVersion , "major" ) ;
377+ } else if ( options . minor ) {
378+ newVersion = semver . inc ( currentVersion , "minor" ) ;
379+ } else if ( options . patch ) {
380+ newVersion = semver . inc ( currentVersion , "patch" ) ;
381+ }
382+
383+ if ( ! newVersion ) {
384+ console . error ( chalk . red ( "Error: Failed to calculate new version" ) ) ;
299385 process . exit ( 1 ) ;
300386 }
301387
302- // Validate version format (x.x.x or x.x.x-rc.x)
388+ return newVersion ;
389+ }
390+
391+ function validateVersion ( version : string ) : void {
303392 const versionRegex = / ^ \d + \. \d + \. \d + ( - r c \. \d + ) ? $ / ;
304393 if ( ! versionRegex . test ( version ) ) {
305394 console . error ( chalk . red ( `Invalid version format: ${ version } ` ) ) ;
@@ -308,8 +397,6 @@ function getVersionFromArgs() {
308397 ) ;
309398 process . exit ( 1 ) ;
310399 }
311-
312- return version ;
313400}
314401
315402async function bumpPackageVersions ( version : string ) {
0 commit comments