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
-
6
1
import { tmpdir } from "os"
2
+ import { cacheDir , downloadTool , find } from "@actions/tool-cache"
7
3
import { GITHUB_ACTIONS } from "ci-info"
4
+ import { info , warning } from "ci-log"
5
+ import { addPath } from "envosman"
6
+ import { chmod } from "fs/promises"
8
7
import { pathExists } from "path-exists"
8
+ import { join } from "patha"
9
9
import retry from "retry-as-promised"
10
10
import { installAptPack } from "setup-apt"
11
11
import { maybeGetInput , rcOptions } from "../../cli-options.js"
@@ -88,39 +88,29 @@ export async function setupBin(
88
88
const binDir = join ( installDir , binRelativeDir )
89
89
const binFile = join ( binDir , binFileName )
90
90
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
+ ) {
91
108
// download ane extract the package into the installation directory.
92
109
if ( ( await Promise . all ( [ pathExists ( binDir ) , pathExists ( binFile ) ] ) ) . includes ( false ) ) {
93
110
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 )
117
112
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 )
124
114
} catch ( err ) {
125
115
throw new Error ( `Failed to download ${ name } ${ version } ${ arch } from ${ url } : ${ err } ` )
126
116
}
@@ -131,12 +121,66 @@ export async function setupBin(
131
121
info ( `Add ${ binDir } to PATH` )
132
122
await addPath ( binDir , rcOptions )
133
123
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 ) {
134
180
// check if inside Github Actions. If so, cache the installation
135
181
if ( GITHUB_ACTIONS && typeof process . env . RUNNER_TOOL_CACHE === "string" ) {
136
182
if ( maybeGetInput ( "cache-tools" ) === "true" || process . env . CACHE_TOOLS === "true" ) {
137
183
await cacheDir ( setupDir , name , version )
138
184
}
139
185
}
140
-
141
- return { installDir, binDir }
142
186
}
0 commit comments