@@ -10,6 +10,8 @@ import { writeConfig } from './config.js';
1010const REPO_OWNER = 'Kinin-Code-Offical' ;
1111const REPO_NAME = 'cloudsqlctl' ;
1212const GITHUB_API_URL = `https://api.github.com/repos/${ REPO_OWNER } /${ REPO_NAME } /releases/latest` ;
13+ const GITHUB_RELEASES_URL = `https://api.github.com/repos/${ REPO_OWNER } /${ REPO_NAME } /releases` ;
14+ const GITHUB_RELEASE_TAG_URL = `https://api.github.com/repos/${ REPO_OWNER } /${ REPO_NAME } /releases/tags` ;
1315const TIMEOUT_MS = 60000 ;
1416const MAX_RETRIES = 2 ;
1517
@@ -42,8 +44,53 @@ export async function getLatestRelease(): Promise<ReleaseInfo> {
4244 }
4345}
4446
45- export async function checkForUpdates ( currentVersion : string ) : Promise < UpdateStatus > {
46- const release = await getLatestRelease ( ) ;
47+ function normalizeTag ( tag : string ) : string {
48+ return tag . startsWith ( 'v' ) ? tag : `v${ tag } ` ;
49+ }
50+
51+ export async function getReleaseByTag ( tag : string ) : Promise < ReleaseInfo > {
52+ try {
53+ const response = await axios . get ( `${ GITHUB_RELEASE_TAG_URL } /${ normalizeTag ( tag ) } ` , {
54+ timeout : TIMEOUT_MS ,
55+ headers : { 'User-Agent' : 'cloudsqlctl/upgrade' }
56+ } ) ;
57+ return response . data ;
58+ } catch ( error ) {
59+ logger . error ( 'Failed to fetch release by tag' , error ) ;
60+ throw error ;
61+ }
62+ }
63+
64+ export async function getLatestPrerelease ( ) : Promise < ReleaseInfo > {
65+ try {
66+ const response = await axios . get ( GITHUB_RELEASES_URL , {
67+ timeout : TIMEOUT_MS ,
68+ headers : { 'User-Agent' : 'cloudsqlctl/upgrade' }
69+ } ) ;
70+ const releases = Array . isArray ( response . data ) ? response . data : [ ] ;
71+ const prerelease = releases . find ( ( r : { prerelease ?: boolean ; draft ?: boolean } ) => r . prerelease && ! r . draft ) ;
72+ if ( ! prerelease ) {
73+ throw new Error ( 'No prerelease found' ) ;
74+ }
75+ return prerelease ;
76+ } catch ( error ) {
77+ logger . error ( 'Failed to fetch latest prerelease info' , error ) ;
78+ throw error ;
79+ }
80+ }
81+
82+ export async function checkForUpdates (
83+ currentVersion : string ,
84+ options : { channel ?: 'stable' | 'beta' ; targetVersion ?: string } = { }
85+ ) : Promise < UpdateStatus > {
86+ let release : ReleaseInfo ;
87+ if ( options . targetVersion ) {
88+ release = await getReleaseByTag ( options . targetVersion ) ;
89+ } else if ( options . channel === 'beta' ) {
90+ release = await getLatestPrerelease ( ) ;
91+ } else {
92+ release = await getLatestRelease ( ) ;
93+ }
4794 // Remove 'v' prefix if present for semver comparison
4895 const latestVer = release . tag_name . replace ( / ^ v / , '' ) ;
4996 const currentVer = currentVersion . replace ( / ^ v / , '' ) ;
0 commit comments