Skip to content

Commit 3bcb4c4

Browse files
committed
src/action.ts: move shared action logic to action.ts
Move the shared orchestration logic of the action out of main.ts into a new file src/action.ts. The main.ts file now just calls through to the run() function, with an ICore instance using @actions/core and @actions/cache. Signed-off-by: Matthew John Cheetham <[email protected]>
1 parent 2166dcc commit 3bcb4c4

File tree

4 files changed

+244
-241
lines changed

4 files changed

+244
-241
lines changed

dist/index.js

Lines changed: 20 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: 1 addition & 226 deletions
Original file line numberDiff line numberDiff line change
@@ -1,229 +1,4 @@
1-
import {ICore} from './src/core'
1+
import {run} from './src/action'
22
import {ActionsCore} from './src/actions_core'
3-
import {mkdirp} from './src/downloader'
4-
import process from 'process'
5-
import {spawnSync} from 'child_process'
6-
import {
7-
getArtifactMetadata,
8-
getViaGit,
9-
gitForWindowsUsrBinPath
10-
} from './src/git'
11-
import {getViaCIArtifacts} from './src/ci_artifacts'
12-
import * as fs from 'fs'
13-
14-
/**
15-
* Some Azure VM types have a temporary disk which is local to the VM and therefore provides
16-
* _much_ faster disk IO than the OS Disk (or any other attached disk).
17-
*
18-
* Hosted GitHub Actions runners also leverage this disk and do their work in D:/a/_work, so let's
19-
* use it too if we can. It leads to a ~25% speed increase when doing heavy IO operations.
20-
*
21-
* https://learn.microsoft.com/en-us/azure/virtual-machines/managed-disks-overview#temporary-disk
22-
*/
23-
function getDriveLetterPrefix(core: ICore): string {
24-
if (fs.existsSync('D:/')) {
25-
core.info('Found a fast, temporary disk on this VM (D:/). Will use that.')
26-
return 'D:/'
27-
}
28-
29-
return 'C:/'
30-
}
31-
32-
async function setup(
33-
core: ICore,
34-
flavor: string,
35-
architecture: string
36-
): Promise<void> {
37-
try {
38-
if (process.platform !== 'win32') {
39-
core.warning(
40-
`Skipping this Action because it only works on Windows, not on ${process.platform}`
41-
)
42-
return
43-
}
44-
45-
const githubToken = core.getInput('github-token')
46-
const verbose = core.getInput('verbose')
47-
const msysMode = core.getInput('msys') === 'true'
48-
49-
const {artifactName, download, id} =
50-
flavor === 'minimal'
51-
? await getViaCIArtifacts(core, architecture, githubToken)
52-
: await getViaGit(core, flavor, architecture, githubToken)
53-
const outputDirectory =
54-
core.getInput('path') || `${getDriveLetterPrefix(core)}${artifactName}`
55-
core.setOutput('result', outputDirectory)
56-
57-
let useCache: boolean
58-
switch (core.getInput('cache')) {
59-
case 'true':
60-
useCache = true
61-
break
62-
case 'auto':
63-
useCache = !['full', 'minimal'].includes(flavor)
64-
break
65-
default:
66-
useCache = false
67-
}
68-
69-
if (!core.isCacheAvailable()) {
70-
useCache = false
71-
}
72-
73-
let needToDownload = true
74-
try {
75-
if (useCache && (await core.restoreCache([outputDirectory], id))) {
76-
core.info(`Cached ${id} was successfully restored`)
77-
needToDownload = false
78-
}
79-
} catch (e) {
80-
core.warning(`Cannot use @actions/cache (${e})`)
81-
useCache = false
82-
}
83-
84-
if (needToDownload) {
85-
core.info(`Downloading ${artifactName}`)
86-
await download(
87-
outputDirectory,
88-
verbose.match(/^\d+$/) ? parseInt(verbose) : verbose === 'true'
89-
)
90-
91-
try {
92-
if (useCache && !(await core.saveCache([outputDirectory], id))) {
93-
core.warning(`Failed to cache ${id}`)
94-
}
95-
} catch (e) {
96-
core.warning(
97-
`Failed to cache ${id}: ${e instanceof Error ? e.message : e}`
98-
)
99-
}
100-
}
101-
102-
const mingw = {
103-
i686: 'MINGW32',
104-
x86_64: 'MINGW64',
105-
aarch64: 'CLANGARM64'
106-
}[architecture]
107-
108-
if (mingw === undefined) {
109-
core.setFailed(`Invalid architecture ${architecture} specified`)
110-
return
111-
}
112-
113-
const msystem = msysMode ? 'MSYS' : mingw
114-
115-
const binPaths = [
116-
// Set up PATH so that Git for Windows' SDK's `bash.exe`, `prove` and `gcc` are found
117-
'/usr/bin/core_perl',
118-
'/usr/bin',
119-
`/${mingw.toLocaleLowerCase()}/bin`
120-
]
121-
122-
for (const binPath of msysMode ? binPaths.reverse() : binPaths) {
123-
core.addPath(`${outputDirectory}${binPath}`)
124-
}
125-
126-
core.exportVariable('MSYSTEM', msystem)
127-
if (
128-
!('LANG' in process.env) &&
129-
!('LC_ALL' in process.env) &&
130-
!('LC_CTYPE' in process.env)
131-
) {
132-
core.exportVariable('LC_CTYPE', 'C.UTF-8')
133-
}
134-
135-
// ensure that /dev/fd/*, /dev/mqueue and friends exist
136-
for (const path of ['/dev/mqueue', '/dev/shm']) {
137-
mkdirp(`${outputDirectory}${path}`)
138-
}
139-
140-
const ln = (linkPath: string, target: string): void => {
141-
const child = spawnSync(
142-
flavor === 'minimal' ? 'ln.exe' : 'usr\\bin\\ln.exe',
143-
['-s', target, linkPath],
144-
{
145-
cwd: outputDirectory,
146-
env: {
147-
MSYS: 'winsymlinks:sys'
148-
}
149-
}
150-
)
151-
if (child.error) throw child.error
152-
}
153-
for (const [linkPath, target] of Object.entries({
154-
fd: 'fd',
155-
stdin: 'fd/0',
156-
stdout: 'fd/1',
157-
stderr: 'fd/2'
158-
})) {
159-
ln(`/dev/${linkPath}`, `/proc/self/${target}`)
160-
}
161-
} catch (error) {
162-
core.setFailed(error instanceof Error ? error.message : `${error}`)
163-
}
164-
}
165-
166-
function cleanup(core: ICore, flavor: string, architecture: string): void {
167-
if (core.getInput('cleanup') !== 'true') {
168-
core.info(
169-
`Won't clean up SDK files as the 'cleanup' input was not provided or doesn't equal 'true'.`
170-
)
171-
return
172-
}
173-
174-
const outputDirectory =
175-
core.getInput('path') ||
176-
`${getDriveLetterPrefix(core)}${
177-
getArtifactMetadata(flavor, architecture).artifactName
178-
}`
179-
180-
/**
181-
* Shelling out to `rm -rf` is more than twice as fast as Node's `fs.rmSync` method.
182-
* Let's use it if it's available, and otherwise fall back to `fs.rmSync`.
183-
*/
184-
const cleanupMethod = fs.existsSync(`${gitForWindowsUsrBinPath}/bash.exe`)
185-
? 'rm -rf'
186-
: 'node'
187-
188-
core.info(
189-
`Cleaning up ${outputDirectory} using the "${cleanupMethod}" method...`
190-
)
191-
192-
if (cleanupMethod === 'rm -rf') {
193-
const child = spawnSync(
194-
`${gitForWindowsUsrBinPath}/bash.exe`,
195-
['-c', `rm -rf "${outputDirectory}"`],
196-
{
197-
encoding: 'utf-8',
198-
env: {PATH: '/usr/bin'}
199-
}
200-
)
201-
202-
if (child.error) throw child.error
203-
if (child.stderr) core.error(child.stderr)
204-
} else {
205-
fs.rmSync(outputDirectory, {recursive: true, force: true})
206-
}
207-
208-
core.info(`Finished cleaning up ${outputDirectory}.`)
209-
}
210-
211-
async function run(core: ICore): Promise<void> {
212-
const flavor = core.getInput('flavor')
213-
const architecture = core.getInput('architecture')
214-
const isPost = !!core.getState('isPost')
215-
if (!isPost) {
216-
setup(core, flavor, architecture)
217-
/*
218-
* Publish a variable so that when the POST action runs, it can determine it should run the cleanup logic.
219-
* This is necessary since we don't have a separate entry point.
220-
* Inspired by https://github.com/actions/checkout/blob/v3.1.0/src/state-helper.ts#L56-L60
221-
*/
222-
core.saveState('isPost', 'true')
223-
} else {
224-
// If the POST action is running, we cleanup our artifacts
225-
cleanup(core, flavor, architecture)
226-
}
227-
}
2283

2294
run(new ActionsCore())

0 commit comments

Comments
 (0)