Skip to content

Commit fc47a3b

Browse files
committed
@actions/core: abstract @actions/core usage
Introduce a simple abstraction of the @actions/core module, such that we can provide a different implementation in the future (for Azure Pipelines, for example). Rename 'run' to 'setup' (which is the sibling to 'cleanup'), and add a new 'run' function that takes only an ICore implementation, using @actions/core. Signed-off-by: Matthew John Cheetham <[email protected]>
1 parent aaca187 commit fc47a3b

File tree

5 files changed

+177
-33
lines changed

5 files changed

+177
-33
lines changed

main.ts

Lines changed: 31 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import * as core from '@actions/core'
1+
import {ICore} from './src/core'
2+
import {ActionsCore} from './src/actions_core'
23
import {mkdirp} from './src/downloader'
34
import {restoreCache, saveCache} from '@actions/cache'
45
import process from 'process'
@@ -11,9 +12,6 @@ import {
1112
import {getViaCIArtifacts} from './src/ci_artifacts'
1213
import * as fs from 'fs'
1314

14-
const flavor = core.getInput('flavor')
15-
const architecture = core.getInput('architecture')
16-
1715
/**
1816
* Some Azure VM types have a temporary disk which is local to the VM and therefore provides
1917
* _much_ faster disk IO than the OS Disk (or any other attached disk).
@@ -23,7 +21,7 @@ const architecture = core.getInput('architecture')
2321
*
2422
* https://learn.microsoft.com/en-us/azure/virtual-machines/managed-disks-overview#temporary-disk
2523
*/
26-
function getDriveLetterPrefix(): string {
24+
function getDriveLetterPrefix(core: ICore): string {
2725
if (fs.existsSync('D:/')) {
2826
core.info('Found a fast, temporary disk on this VM (D:/). Will use that.')
2927
return 'D:/'
@@ -32,7 +30,11 @@ function getDriveLetterPrefix(): string {
3230
return 'C:/'
3331
}
3432

35-
async function run(): Promise<void> {
33+
async function setup(
34+
core: ICore,
35+
flavor: string,
36+
architecture: string
37+
): Promise<void> {
3638
try {
3739
if (process.platform !== 'win32') {
3840
core.warning(
@@ -47,10 +49,10 @@ async function run(): Promise<void> {
4749

4850
const {artifactName, download, id} =
4951
flavor === 'minimal'
50-
? await getViaCIArtifacts(architecture, githubToken)
51-
: await getViaGit(flavor, architecture, githubToken)
52+
? await getViaCIArtifacts(core, architecture, githubToken)
53+
: await getViaGit(core, flavor, architecture, githubToken)
5254
const outputDirectory =
53-
core.getInput('path') || `${getDriveLetterPrefix()}${artifactName}`
55+
core.getInput('path') || `${getDriveLetterPrefix(core)}${artifactName}`
5456
core.setOutput('result', outputDirectory)
5557

5658
let useCache: boolean
@@ -158,7 +160,7 @@ async function run(): Promise<void> {
158160
}
159161
}
160162

161-
function cleanup(): void {
163+
function cleanup(core: ICore, flavor: string, architecture: string): void {
162164
if (core.getInput('cleanup') !== 'true') {
163165
core.info(
164166
`Won't clean up SDK files as the 'cleanup' input was not provided or doesn't equal 'true'.`
@@ -168,7 +170,7 @@ function cleanup(): void {
168170

169171
const outputDirectory =
170172
core.getInput('path') ||
171-
`${getDriveLetterPrefix()}${
173+
`${getDriveLetterPrefix(core)}${
172174
getArtifactMetadata(flavor, architecture).artifactName
173175
}`
174176

@@ -203,20 +205,22 @@ function cleanup(): void {
203205
core.info(`Finished cleaning up ${outputDirectory}.`)
204206
}
205207

206-
/**
207-
* Indicates whether the POST action is running
208-
*/
209-
export const isPost = !!core.getState('isPost')
210-
211-
if (!isPost) {
212-
run()
213-
/*
214-
* Publish a variable so that when the POST action runs, it can determine it should run the cleanup logic.
215-
* This is necessary since we don't have a separate entry point.
216-
* Inspired by https://github.com/actions/checkout/blob/v3.1.0/src/state-helper.ts#L56-L60
217-
*/
218-
core.saveState('isPost', 'true')
219-
} else {
220-
// If the POST action is running, we cleanup our artifacts
221-
cleanup()
208+
async function run(core: ICore): Promise<void> {
209+
const flavor = core.getInput('flavor')
210+
const architecture = core.getInput('architecture')
211+
const isPost = !!core.getState('isPost')
212+
if (!isPost) {
213+
setup(core, flavor, architecture)
214+
/*
215+
* Publish a variable so that when the POST action runs, it can determine it should run the cleanup logic.
216+
* This is necessary since we don't have a separate entry point.
217+
* Inspired by https://github.com/actions/checkout/blob/v3.1.0/src/state-helper.ts#L56-L60
218+
*/
219+
core.saveState('isPost', 'true')
220+
} else {
221+
// If the POST action is running, we cleanup our artifacts
222+
cleanup(core, flavor, architecture)
223+
}
222224
}
225+
226+
run(new ActionsCore())

src/actions_core.ts

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import {ICore} from '../src/core'
2+
import * as core from '@actions/core'
3+
4+
export class ActionsCore implements ICore {
5+
getInput(name: string): string {
6+
return core.getInput(name)
7+
}
8+
9+
setOutput(name: string, value: string): void {
10+
core.setOutput(name, value)
11+
}
12+
13+
addPath(inputPath: string): void {
14+
core.addPath(inputPath)
15+
}
16+
17+
exportVariable(name: string, value: string): void {
18+
core.exportVariable(name, value)
19+
}
20+
21+
info(message: string): void {
22+
core.info(message)
23+
}
24+
25+
warning(message: string): void {
26+
core.warning(message)
27+
}
28+
29+
error(message: string): void {
30+
core.error(message)
31+
}
32+
33+
setFailed(message: string): void {
34+
core.setFailed(message)
35+
}
36+
37+
startGroup(name: string): void {
38+
core.startGroup(name)
39+
}
40+
41+
endGroup(): void {
42+
core.endGroup()
43+
}
44+
45+
saveState(name: string, value: string): void {
46+
core.saveState(name, value)
47+
}
48+
49+
getState(name: string): string {
50+
return core.getState(name)
51+
}
52+
}

src/ci_artifacts.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import * as core from '@actions/core'
1+
import {ICore} from './core'
22
import {Octokit} from '@octokit/rest'
33
import {getArtifactMetadata} from './git'
44
import {spawn} from 'child_process'
@@ -11,6 +11,7 @@ async function sleep(milliseconds: number): Promise<void> {
1111
}
1212

1313
export async function getViaCIArtifacts(
14+
core: ICore,
1415
architecture: string,
1516
githubToken?: string
1617
): Promise<{

src/core.ts

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/**
2+
* Interface abstracting the core functionality needed for GitHub Actions and Azure Pipelines.
3+
* This allows us to avoid module shimming and provide clean implementations for different platforms.
4+
*/
5+
export interface ICore {
6+
/**
7+
* Gets an input from the action/task configuration.
8+
* @param name The name of the input
9+
* @returns The input value or empty string if not found
10+
*/
11+
getInput(name: string): string
12+
13+
/**
14+
* Sets an output for the action/task.
15+
* @param name The name of the output
16+
* @param value The output value
17+
*/
18+
setOutput(name: string, value: string): void
19+
20+
/**
21+
* Adds a path to the PATH environment variable.
22+
* @param inputPath The path to add
23+
*/
24+
addPath(inputPath: string): void
25+
26+
/**
27+
* Exports a variable to the environment.
28+
* @param name The variable name
29+
* @param value The variable value
30+
*/
31+
exportVariable(name: string, value: string): void
32+
33+
/**
34+
* Logs an informational message.
35+
* @param message The message to log
36+
*/
37+
info(message: string): void
38+
39+
/**
40+
* Logs a warning message.
41+
* @param message The warning message
42+
*/
43+
warning(message: string): void
44+
45+
/**
46+
* Logs an error message.
47+
* @param message The error message
48+
*/
49+
error(message: string): void
50+
51+
/**
52+
* Sets the action/task as failed with the given message.
53+
* @param message The failure message
54+
*/
55+
setFailed(message: string): void
56+
57+
/**
58+
* Starts a group for log output organization.
59+
* @param name The group name
60+
*/
61+
startGroup(name: string): void
62+
63+
/**
64+
* Ends the current log group.
65+
*/
66+
endGroup(): void
67+
68+
/**
69+
* Saves state for post-job execution.
70+
* @param name The state name
71+
* @param value The state value
72+
*/
73+
saveState(name: string, value: string): void
74+
75+
/**
76+
* Gets previously saved state.
77+
* @param name The state name
78+
* @returns The state value or empty string if not found
79+
*/
80+
getState(name: string): string
81+
}

src/git.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import * as core from '@actions/core'
1+
import {ICore} from './core'
22
import {spawnAndWaitForExitCode, SpawnReturnArgs} from './spawn'
33
import {Octokit} from '@octokit/rest'
44
import {delimiter} from 'path'
@@ -49,6 +49,7 @@ export function getArtifactMetadata(
4949
}
5050

5151
export async function clone(
52+
core: ICore,
5253
url: string,
5354
destination: string,
5455
verbose: number | boolean,
@@ -96,6 +97,7 @@ async function updateHEAD(
9697
}
9798

9899
export async function getViaGit(
100+
core: ICore,
99101
flavor: string,
100102
architecture: string,
101103
githubToken?: string
@@ -155,10 +157,13 @@ export async function getViaGit(
155157
): Promise<void> => {
156158
core.startGroup(`Cloning ${repo}`)
157159
const partialCloneArg = flavor === 'full' ? [] : ['--filter=blob:none']
158-
await clone(`https://github.com/${owner}/${repo}`, `.tmp`, verbose, [
159-
'--bare',
160-
...partialCloneArg
161-
])
160+
await clone(
161+
core,
162+
`https://github.com/${owner}/${repo}`,
163+
`.tmp`,
164+
verbose,
165+
['--bare', ...partialCloneArg]
166+
)
162167
core.endGroup()
163168

164169
let child: SpawnReturnArgs
@@ -177,6 +182,7 @@ export async function getViaGit(
177182
await updateHEAD('.tmp', head_sha)
178183
core.startGroup('Cloning build-extra')
179184
await clone(
185+
core,
180186
`https://github.com/${owner}/build-extra`,
181187
'.tmp/build-extra',
182188
verbose

0 commit comments

Comments
 (0)