@@ -2,8 +2,15 @@ import * as core from '@actions/core'
2
2
import { mkdirp } from './src/downloader'
3
3
import { restoreCache , saveCache } from '@actions/cache'
4
4
import process from 'process'
5
- import { spawnSync } from 'child_process'
6
- import { getViaGit } from './src/git'
5
+ import { spawn , spawnSync } from 'child_process'
6
+ import { getArtifactMetadata , getViaGit } from './src/git'
7
+ import * as fs from 'fs'
8
+ import * as coreCommand from '@actions/core/lib/command'
9
+
10
+ const flavor = core . getInput ( 'flavor' )
11
+ const architecture = core . getInput ( 'architecture' )
12
+ const architectureToDownload =
13
+ architecture === 'aarch64' ? 'x86_64' : architecture
7
14
8
15
async function run ( ) : Promise < void > {
9
16
try {
@@ -13,12 +20,14 @@ async function run(): Promise<void> {
13
20
)
14
21
return
15
22
}
16
- const flavor = core . getInput ( 'flavor' )
17
- const architecture = core . getInput ( 'architecture' )
23
+
18
24
const verbose = core . getInput ( 'verbose' )
19
25
const msysMode = core . getInput ( 'msys' ) === 'true'
20
26
21
- const { artifactName, download, id} = await getViaGit ( flavor , architecture )
27
+ const { artifactName, download, id} = await getViaGit (
28
+ flavor ,
29
+ architectureToDownload
30
+ )
22
31
const outputDirectory = core . getInput ( 'path' ) || `C:/${ artifactName } `
23
32
let useCache : boolean
24
33
switch ( core . getInput ( 'cache' ) ) {
@@ -61,7 +70,22 @@ async function run(): Promise<void> {
61
70
}
62
71
}
63
72
64
- const mingw = architecture === 'i686' ? 'MINGW32' : 'MINGW64'
73
+ let mingw = ''
74
+
75
+ switch ( architecture ) {
76
+ case 'i686' :
77
+ mingw = 'MINGW32'
78
+ break
79
+ case 'x86_64' :
80
+ mingw = 'MINGW64'
81
+ break
82
+ case 'aarch64' :
83
+ mingw = 'CLANGARM64'
84
+ break
85
+ default :
86
+ core . setFailed ( `Invalid architecture ${ architecture } specified` )
87
+ }
88
+
65
89
const msystem = msysMode ? 'MSYS' : mingw
66
90
67
91
const binPaths = [
@@ -109,9 +133,84 @@ async function run(): Promise<void> {
109
133
} ) ) {
110
134
ln ( `/dev/${ linkPath } ` , `/proc/self/${ target } ` )
111
135
}
136
+
137
+ if ( msystem === 'CLANGARM64' ) {
138
+ // ARM64 dependencies aren't included yet in the Git for Windows SDK. Ask Pacman to install them.
139
+ await installArm64Dependencies ( outputDirectory )
140
+ }
112
141
} catch ( error ) {
113
142
core . setFailed ( error instanceof Error ? error . message : `${ error } ` )
114
143
}
115
144
}
116
145
117
- run ( )
146
+ async function installArm64Dependencies (
147
+ outputDirectory : string
148
+ ) : Promise < void > {
149
+ core . info ( 'Installing CLANGARM64 dependencies...' )
150
+ mkdirp ( `${ outputDirectory } /clangarm64` )
151
+ fs . appendFileSync (
152
+ `${ outputDirectory } /etc/pacman.conf` ,
153
+ `
154
+ [clangarm64]
155
+ Server = https://mirror.msys2.org/mingw/clangarm64/`
156
+ )
157
+
158
+ const child = spawn ( 'pacman.exe' , [
159
+ '-Sy' ,
160
+ '--noconfirm' ,
161
+ 'base-devel' ,
162
+ 'mingw-w64-clang-aarch64-openssl' ,
163
+ 'mingw-w64-clang-aarch64-zlib' ,
164
+ 'mingw-w64-clang-aarch64-curl' ,
165
+ 'mingw-w64-clang-aarch64-expat' ,
166
+ 'mingw-w64-clang-aarch64-libiconv' ,
167
+ 'mingw-w64-clang-aarch64-toolchain' ,
168
+ 'mingw-w64-clang-aarch64-pcre2' ,
169
+ 'mingw-w64-clang-aarch64-libssp'
170
+ ] )
171
+
172
+ child . stdout . on ( 'data' , data => {
173
+ core . info ( data )
174
+ } )
175
+
176
+ child . stderr . on ( 'data' , data => {
177
+ core . error ( data )
178
+ } )
179
+
180
+ return new Promise ( ( resolve , reject ) => {
181
+ child . on ( 'error' , error => reject ( error ) )
182
+ child . on ( 'close' , status =>
183
+ status === 0
184
+ ? resolve ( )
185
+ : reject ( new Error ( `Process exited with status code ${ status } ` ) )
186
+ )
187
+ } )
188
+ }
189
+
190
+ function cleanup ( ) : void {
191
+ const { artifactName} = getArtifactMetadata ( flavor , architectureToDownload )
192
+ const outputDirectory = core . getInput ( 'path' ) || `C:/${ artifactName } `
193
+
194
+ core . info ( `Cleaning up ${ outputDirectory } ...` )
195
+ fs . rmSync ( outputDirectory , { recursive : true , force : true } )
196
+ core . info ( `Finished cleaning up ${ outputDirectory } .` )
197
+ }
198
+
199
+ /**
200
+ * Indicates whether the POST action is running
201
+ */
202
+ export const isPost = ! ! process . env [ 'STATE_isPost' ]
203
+
204
+ // Publish a variable so that when the POST action runs, it can determine it should run the cleanup logic.
205
+ // This is necessary since we don't have a separate entry point.
206
+ if ( ! isPost ) {
207
+ coreCommand . issueCommand ( 'save-state' , { name : 'isPost' } , 'true' )
208
+ }
209
+
210
+ // If the POST action is running, we cleanup our artifacts
211
+ // Inspired from https://github.com/actions/checkout/blob/2541b1294d2704b0964813337f33b291d3f8596b/src/state-helper.ts#L67-L71
212
+ if ( isPost ) {
213
+ cleanup ( )
214
+ } else {
215
+ run ( )
216
+ }
0 commit comments