Skip to content

Commit 8bbc989

Browse files
committed
Add ARM64/aarch64 support, add cleanup logic
1 parent 8c19a8a commit 8bbc989

File tree

5 files changed

+201
-32
lines changed

5 files changed

+201
-32
lines changed

action.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ inputs:
1111
default: 'minimal'
1212
architecture:
1313
required: false
14-
description: 'The architecture of the SDK: x86_64 or i686'
14+
description: 'The architecture of the SDK: x86_64, i686 or aarch64. Note that "aarch64" uses the x86_64 SDK, but adds "clangarm64" to the path.'
1515
default: 'x86_64'
1616
msys:
1717
required: false
@@ -32,3 +32,4 @@ inputs:
3232
runs:
3333
using: 'node16'
3434
main: 'dist/index.js'
35+
post: 'dist/index.js'

dist/index.js

Lines changed: 85 additions & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/index.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

main.ts

Lines changed: 93 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,14 @@ import * as core from '@actions/core'
22
import {mkdirp} from './src/downloader'
33
import {restoreCache, saveCache} from '@actions/cache'
44
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+
9+
const flavor = core.getInput('flavor')
10+
const architecture = core.getInput('architecture')
11+
const architectureToDownload =
12+
architecture === 'aarch64' ? 'x86_64' : architecture
713

814
async function run(): Promise<void> {
915
try {
@@ -13,12 +19,14 @@ async function run(): Promise<void> {
1319
)
1420
return
1521
}
16-
const flavor = core.getInput('flavor')
17-
const architecture = core.getInput('architecture')
22+
1823
const verbose = core.getInput('verbose')
1924
const msysMode = core.getInput('msys') === 'true'
2025

21-
const {artifactName, download, id} = await getViaGit(flavor, architecture)
26+
const {artifactName, download, id} = await getViaGit(
27+
flavor,
28+
architectureToDownload
29+
)
2230
const outputDirectory = core.getInput('path') || `C:/${artifactName}`
2331
let useCache: boolean
2432
switch (core.getInput('cache')) {
@@ -61,7 +69,22 @@ async function run(): Promise<void> {
6169
}
6270
}
6371

64-
const mingw = architecture === 'i686' ? 'MINGW32' : 'MINGW64'
72+
let mingw = ''
73+
74+
switch (architecture) {
75+
case 'i686':
76+
mingw = 'MINGW32'
77+
break
78+
case 'x86_64':
79+
mingw = 'MINGW64'
80+
break
81+
case 'aarch64':
82+
mingw = 'CLANGARM64'
83+
break
84+
default:
85+
core.setFailed(`Invalid architecture ${architecture} specified`)
86+
}
87+
6588
const msystem = msysMode ? 'MSYS' : mingw
6689

6790
const binPaths = [
@@ -109,9 +132,72 @@ async function run(): Promise<void> {
109132
})) {
110133
ln(`/dev/${linkPath}`, `/proc/self/${target}`)
111134
}
135+
136+
if (msystem === 'CLANGARM64') {
137+
// ARM64 dependencies aren't included yet in the Git for Windows SDK. Ask Pacman to install them.
138+
await installArm64Dependencies(outputDirectory)
139+
}
112140
} catch (error) {
113141
core.setFailed(error instanceof Error ? error.message : `${error}`)
114142
}
115143
}
116144

117-
run()
145+
async function installArm64Dependencies(
146+
outputDirectory: string
147+
): Promise<void> {
148+
core.info('Installing CLANGARM64 dependencies...')
149+
mkdirp(`${outputDirectory}/clangarm64`)
150+
fs.appendFileSync(
151+
`${outputDirectory}/etc/pacman.conf`,
152+
`
153+
[clangarm64]
154+
Server = https://mirror.msys2.org/mingw/clangarm64/`
155+
)
156+
157+
const child = spawn('pacman.exe', [
158+
'-Sy',
159+
'--noconfirm',
160+
'base-devel',
161+
'mingw-w64-clang-aarch64-openssl',
162+
'mingw-w64-clang-aarch64-zlib',
163+
'mingw-w64-clang-aarch64-curl',
164+
'mingw-w64-clang-aarch64-expat',
165+
'mingw-w64-clang-aarch64-libiconv',
166+
'mingw-w64-clang-aarch64-toolchain',
167+
'mingw-w64-clang-aarch64-pcre2',
168+
'mingw-w64-clang-aarch64-libssp'
169+
])
170+
171+
child.stdout.on('data', data => {
172+
core.info(data)
173+
})
174+
175+
child.stderr.on('data', data => {
176+
core.error(data)
177+
})
178+
179+
return new Promise((resolve, reject) => {
180+
child.on('error', error => reject(error))
181+
child.on('close', status =>
182+
status === 0
183+
? resolve()
184+
: reject(new Error(`Process exited with status code ${status}`))
185+
)
186+
})
187+
}
188+
189+
function cleanup(): void {
190+
const {artifactName} = getArtifactMetadata(flavor, architectureToDownload)
191+
const outputDirectory = core.getInput('path') || `C:/${artifactName}`
192+
193+
core.info(`Cleaning up ${outputDirectory}...`)
194+
fs.rmSync(outputDirectory, {recursive: true, force: true})
195+
core.info(`Finished cleaning up ${outputDirectory}.`)
196+
}
197+
198+
// If the POST action is running, we cleanup our artifacts
199+
if (process.env['STATE_isPost']) {
200+
cleanup()
201+
} else {
202+
run()
203+
}

src/git.ts

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,18 @@ const gitExePath = 'C:/Program Files/Git/cmd/git.exe'
1717
* is much faster than, say, using only 2 workers.
1818
*/
1919
const GIT_CONFIG_PARAMETERS = `'checkout.workers=56'`
20+
const REPO_OWNER = 'git-for-windows'
21+
22+
export function getArtifactMetadata(
23+
flavor: string,
24+
architecture: string
25+
): {bitness: string; repo: string; artifactName: string} {
26+
const bitness = architecture === 'i686' ? '32' : '64'
27+
const repo = `git-sdk-${bitness}`
28+
const artifactName = `${repo}-${flavor}`
29+
30+
return {bitness, repo, artifactName}
31+
}
2032

2133
async function clone(
2234
url: string,
@@ -65,16 +77,15 @@ export async function getViaGit(
6577
verbose?: number | boolean
6678
) => Promise<void>
6779
}> {
68-
const bitness = architecture === 'i686' ? '32' : '64'
69-
const owner = 'git-for-windows'
70-
const repo = `git-sdk-${bitness}`
71-
const artifactName = `${repo}-${flavor}`
72-
80+
const {bitness, repo, artifactName} = getArtifactMetadata(
81+
flavor,
82+
architecture
83+
)
7384
const octokit = new Octokit()
7485
let head_sha: string
7586
if (flavor === 'minimal') {
7687
const info = await octokit.actions.listWorkflowRuns({
77-
owner,
88+
owner: REPO_OWNER,
7889
repo,
7990
workflow_id: 938271,
8091
status: 'success',
@@ -83,7 +94,7 @@ export async function getViaGit(
8394
head_sha = info.data.workflow_runs[0].head_sha
8495
} else {
8596
const info = await octokit.repos.getBranch({
86-
owner,
97+
owner: REPO_OWNER,
8798
repo,
8899
branch: 'main'
89100
})
@@ -101,7 +112,7 @@ export async function getViaGit(
101112
): Promise<void> => {
102113
core.startGroup(`Cloning ${repo}`)
103114
const partialCloneArg = flavor === 'full' ? [] : ['--filter=blob:none']
104-
await clone(`https://github.com/${owner}/${repo}`, `.tmp`, verbose, [
115+
await clone(`https://github.com/${REPO_OWNER}/${repo}`, `.tmp`, verbose, [
105116
'--bare',
106117
...partialCloneArg
107118
])
@@ -123,7 +134,7 @@ export async function getViaGit(
123134
} else {
124135
core.startGroup('Cloning build-extra')
125136
await clone(
126-
`https://github.com/${owner}/build-extra`,
137+
`https://github.com/${REPO_OWNER}/build-extra`,
127138
'.tmp/build-extra',
128139
verbose
129140
)

0 commit comments

Comments
 (0)