1- import { cacheDir , downloadTool , find } from "@actions/tool-cache"
2- import { info } from "ci-log"
3- import { addPath } from "envosman"
4- import { join } from "patha"
5-
61import { tmpdir } from "os"
2+ import { cacheDir , downloadTool , find } from "@actions/tool-cache"
73import { GITHUB_ACTIONS } from "ci-info"
4+ import { info , warning } from "ci-log"
5+ import { addPath } from "envosman"
6+ import { chmod } from "fs/promises"
87import { pathExists } from "path-exists"
8+ import { join } from "patha"
99import retry from "retry-as-promised"
1010import { installAptPack } from "setup-apt"
1111import { maybeGetInput , rcOptions } from "../../cli-options.js"
@@ -88,39 +88,29 @@ export async function setupBin(
8888 const binDir = join ( installDir , binRelativeDir )
8989 const binFile = join ( binDir , binFileName )
9090
91+ await downloadExtractInstall ( binDir , binFile , name , version , url , setupDir , extractFunction , arch )
92+
93+ await cacheInstallation ( setupDir , name , version )
94+
95+ return { installDir, binDir }
96+ }
97+
98+ async function downloadExtractInstall (
99+ binDir : string ,
100+ binFile : string ,
101+ name : string ,
102+ version : string ,
103+ url : string ,
104+ setupDir : string ,
105+ extractFunction : ( ( file : string , dest : string ) => Promise < unknown > ) | undefined ,
106+ arch : string ,
107+ ) {
91108 // download ane extract the package into the installation directory.
92109 if ( ( await Promise . all ( [ pathExists ( binDir ) , pathExists ( binFile ) ] ) ) . includes ( false ) ) {
93110 try {
94- info ( `Download ${ name } ${ version } ` )
95- // try to download the package 4 times with 2 seconds delay
96- const downloaded = await retry (
97- ( ) => {
98- return downloadTool ( url )
99- } ,
100- { name : url , max : 4 , backoffBase : 2000 , report : ( err ) => info ( err ) } ,
101- )
102-
103- if ( ! didInit ) {
104- info ( "Installing extraction dependencies" )
105- if ( process . platform === "linux" ) {
106- if ( isArch ( ) ) {
107- await Promise . all ( [ setupPacmanPack ( "unzip" ) , setupPacmanPack ( "tar" ) , setupPacmanPack ( "xz" ) ] )
108- } else if ( hasDnf ( ) ) {
109- await setupDnfPack ( [ { name : "unzip" } , { name : "tar" } , { name : "xz" } ] )
110- } else if ( isUbuntu ( ) ) {
111- await installAptPack ( [ { name : "unzip" } , { name : "tar" } , { name : "xz-utils" } ] )
112- }
113- }
114- // eslint-disable-next-line require-atomic-updates
115- didInit = true
116- }
111+ const downloaded = await tryDownload ( name , version , url )
117112
118- info ( `Extracting ${ downloaded } to ${ setupDir } ` )
119- await extractFunction ?.( downloaded , setupDir )
120- // if (typeof extractedBinDir === "string") {
121- // binDir = extractedBinDir
122- // installDir = extractedBinDir
123- // }
113+ await extractPackage ( downloaded , setupDir , extractFunction )
124114 } catch ( err ) {
125115 throw new Error ( `Failed to download ${ name } ${ version } ${ arch } from ${ url } : ${ err } ` )
126116 }
@@ -131,12 +121,66 @@ export async function setupBin(
131121 info ( `Add ${ binDir } to PATH` )
132122 await addPath ( binDir , rcOptions )
133123
124+ // Check if the binary exists after extraction
125+ if ( ! ( await pathExists ( binFile ) ) ) {
126+ throw new Error ( `Failed to find the binary ${ binFile } after extracting ${ name } ${ version } ${ arch } ` )
127+ }
128+
129+ // make the binary executable on non-windows platforms
130+ if ( process . platform !== "win32" ) {
131+ try {
132+ await chmod ( binFile , "755" )
133+ } catch ( err ) {
134+ warning ( `Failed to make ${ binFile } executable: ${ err } ` )
135+ }
136+ }
137+ }
138+
139+ async function tryDownload ( name : string , version : string , url : string ) {
140+ info ( `Download ${ name } ${ version } ` )
141+ // try to download the package 4 times with 2 seconds delay
142+ const downloaded = await retry (
143+ ( ) => {
144+ return downloadTool ( url )
145+ } ,
146+ { name : url , max : 4 , backoffBase : 2000 , report : ( err ) => info ( err ) } ,
147+ )
148+ return downloaded
149+ }
150+
151+ async function extractPackage (
152+ downloaded : string ,
153+ setupDir : string ,
154+ extractFunction : ( ( file : string , dest : string ) => Promise < unknown > ) | undefined ,
155+ ) {
156+ info ( `Extracting ${ downloaded } to ${ setupDir } ` )
157+ await installExtractionDependencies ( )
158+
159+ await extractFunction ?.( downloaded , setupDir )
160+ }
161+
162+ async function installExtractionDependencies ( ) {
163+ if ( ! didInit ) {
164+ info ( "Installing extraction dependencies" )
165+ if ( process . platform === "linux" ) {
166+ if ( isArch ( ) ) {
167+ await Promise . all ( [ setupPacmanPack ( "unzip" ) , setupPacmanPack ( "tar" ) , setupPacmanPack ( "xz" ) ] )
168+ } else if ( hasDnf ( ) ) {
169+ await setupDnfPack ( [ { name : "unzip" } , { name : "tar" } , { name : "xz" } ] )
170+ } else if ( isUbuntu ( ) ) {
171+ await installAptPack ( [ { name : "unzip" } , { name : "tar" } , { name : "xz-utils" } ] )
172+ }
173+ }
174+ // eslint-disable-next-line require-atomic-updates
175+ didInit = true
176+ }
177+ }
178+
179+ async function cacheInstallation ( setupDir : string , name : string , version : string ) {
134180 // check if inside Github Actions. If so, cache the installation
135181 if ( GITHUB_ACTIONS && typeof process . env . RUNNER_TOOL_CACHE === "string" ) {
136182 if ( maybeGetInput ( "cache-tools" ) === "true" || process . env . CACHE_TOOLS === "true" ) {
137183 await cacheDir ( setupDir , name , version )
138184 }
139185 }
140-
141- return { installDir, binDir }
142186}
0 commit comments