@@ -11,7 +11,7 @@ const VERSIONED_ARCHIVE_VERSION = "2.99.0";
1111const DEFAULT_VERSION = "latest" ;
1212const GITHUB_RELEASES_API = "https://api.github.com/repos/supabase/cli/releases/latest" ;
1313
14- type ArchiveFormat = "tar" | "zip" ;
14+ type ArchiveFormat = "apk" | " tar" | "zip" ;
1515
1616type DownloadArchive = {
1717 url : string ;
@@ -188,7 +188,19 @@ async function resolveLatestVersion(): Promise<string> {
188188 return normalizeVersion ( release . tag_name ) ;
189189}
190190
191- function getArchiveFormat ( version : string , platform : NodeJS . Platform ) : ArchiveFormat {
191+ function getArchiveFormat (
192+ version : string ,
193+ platform : NodeJS . Platform ,
194+ isMuslLinux : boolean ,
195+ ) : ArchiveFormat {
196+ if (
197+ platform === "linux" &&
198+ isMuslLinux &&
199+ semver . order ( version , VERSIONED_ARCHIVE_VERSION ) >= 0
200+ ) {
201+ return "apk" ;
202+ }
203+
192204 if ( platform === "win32" && semver . order ( version , VERSIONED_ARCHIVE_VERSION ) >= 0 ) {
193205 return "zip" ;
194206 }
@@ -200,6 +212,7 @@ function getArchiveFilename(
200212 version : string ,
201213 platform : NodeJS . Platform ,
202214 arch : NodeJS . Architecture ,
215+ archiveFormat : ArchiveFormat ,
203216) : string {
204217 const archivePlatform = getArchivePlatform ( platform ) ;
205218 const archiveArch = getArchiveArch ( arch ) ;
@@ -208,6 +221,10 @@ function getArchiveFilename(
208221 return `supabase_${ version } _${ archivePlatform } _${ archiveArch } .tar.gz` ;
209222 }
210223
224+ if ( platform === "linux" && archiveFormat === "apk" ) {
225+ return `supabase_${ version } _${ archivePlatform } _${ archiveArch } .apk` ;
226+ }
227+
211228 if ( semver . order ( version , VERSIONED_ARCHIVE_VERSION ) >= 0 ) {
212229 const extension = platform === "win32" ? "zip" : "tar.gz" ;
213230 return `supabase_${ version } _${ archivePlatform } _${ archiveArch } .${ extension } ` ;
@@ -220,17 +237,45 @@ export async function getDownloadArchive(
220237 version : string ,
221238 platform = process . platform ,
222239 arch = process . arch ,
240+ isMuslLinux ?: boolean ,
223241) : Promise < DownloadArchive > {
224242 const resolvedVersion =
225243 version . toLowerCase ( ) === "latest" ? await resolveLatestVersion ( ) : normalizeVersion ( version ) ;
226- const filename = getArchiveFilename ( resolvedVersion , platform , arch ) ;
244+ const format = getArchiveFormat (
245+ resolvedVersion ,
246+ platform ,
247+ isMuslLinux ?? ( await detectMuslLinux ( platform ) ) ,
248+ ) ;
249+ const filename = getArchiveFilename ( resolvedVersion , platform , arch , format ) ;
227250
228251 return {
229252 url : `https://github.com/supabase/cli/releases/download/v${ resolvedVersion } /${ filename } ` ,
230- format : getArchiveFormat ( resolvedVersion , platform ) ,
253+ format,
231254 } ;
232255}
233256
257+ async function detectMuslLinux ( platform = process . platform ) : Promise < boolean > {
258+ if ( platform !== "linux" ) {
259+ return false ;
260+ }
261+
262+ if ( existsSync ( "/etc/alpine-release" ) ) {
263+ return true ;
264+ }
265+
266+ try {
267+ const output = await $ `ldd --version` . quiet ( ) . text ( ) ;
268+ return output . toLowerCase ( ) . includes ( "musl" ) ;
269+ } catch ( error ) {
270+ const output = error instanceof Error ? error . message : String ( error ) ;
271+ return output . toLowerCase ( ) . includes ( "musl" ) ;
272+ }
273+ }
274+
275+ export function getCliPath ( extractedPath : string , archiveFormat : ArchiveFormat ) : string {
276+ return archiveFormat === "apk" ? path . join ( extractedPath , "usr" , "bin" ) : extractedPath ;
277+ }
278+
234279function getCliExecutablePath ( cliPath : string ) : string {
235280 if ( process . platform !== "win32" ) {
236281 return path . join ( cliPath , "supabase" ) ;
@@ -263,10 +308,11 @@ export async function run(): Promise<void> {
263308 const version = resolveVersion ( core . getInput ( "version" ) ) ;
264309 const archive = await getDownloadArchive ( version ) ;
265310 const archivePath = await tc . downloadTool ( archive . url ) ;
266- const cliPath =
311+ const extractedPath =
267312 archive . format === "zip"
268313 ? await tc . extractZip ( archivePath )
269314 : await tc . extractTar ( archivePath ) ;
315+ const cliPath = getCliPath ( extractedPath , archive . format ) ;
270316 const installedVersion = await determineInstalledVersion ( cliPath ) ;
271317 core . setOutput ( "version" , installedVersion ) ;
272318 core . addPath ( cliPath ) ;
0 commit comments