-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathutils.ts
138 lines (128 loc) · 4.5 KB
/
utils.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
import {exec} from '@actions/exec'
import * as core from '@actions/core'
/**
* Wraps "@actions/exec" exec method to return the stdout output as a string string
* @param commandLine - command to execute
* @param command - optional arguments for tool
* @returns stdout
*/
export async function execReadOutput(commandLine: string, args?: string[]) {
let output = ''
await exec(commandLine, args, {
listeners: {stdout: (data) => (output += data.toString())}
})
return output.trim()
}
/**
* Wraps "@actions/exec" exec method to return a boolean indicating if the
* command exited successfully
* @param commandLine - command to execute
* @param command - optional arguments for tool
* @returns isSuccessful
*/
export async function execIsSuccessful(commandLine: string, args?: string[]) {
try {
await exec(commandLine, args)
return true
} catch (e) {
return false
}
}
/**
* Checks if a file with a given key exists in the specified S3 bucket
* Uses "aws s3api head-object"
* @param options.key - The key of a file in the S3 bucket
* @param options.bucket - The name of the S3 bucket (globally unique)
* @returns fileExists - boolean indicating if the file exists
*/
export async function fileExistsInS3({key, bucket}: {key: string; bucket: string}) {
return execIsSuccessful('aws s3api head-object', [`--bucket=${bucket}`, `--key=${key}`])
}
/**
* Writes a line of text into a file at a specified path, replacing any existing content
* Executes "echo "my text" > ./some/file"
* @param options.text - A string saved to the file
* @param options.path - The local path of the file (relative to working dir)
* @returns exitCode - shell command exit code
*/
export async function writeLineToFile({text, path}: {text: string; path: string}) {
await exec(`/bin/bash -c "echo ${text} > ${path}"`)
}
/**
* Uploads a local file at a specified path to a S3 bucket at a given key
* Executes "aws s3 cp"
* @param options.path - The local path of the file (relative to working dir)
* @param options.key - The key of a file to create in the S3 bucket
* @param options.bucket - The name of the S3 bucket (globally unique)
* @returns exitCode - shell command exit code
*/
export async function copyFileToS3({
path,
key,
bucket
}: {
path: string
key: string
bucket: string
}) {
await exec('aws s3 cp', [path, `s3://${bucket}/${key}`])
}
/**
* Read a file from the S3 bucket at a given key
* Executes "aws s3 cp"
* @param options.key - The key of a file to read from the S3 bucket
* @param options.bucket - The name of the S3 bucket (globally unique)
* @returns exitCode - shell command exit code
*/
export async function readFileFromS3({key, bucket}: {key: string; bucket: string}) {
// Download file and store it in temporary file
// Unfortunately we can't use pipes with @actions/exec
await exec('aws s3 cp', [`s3://${bucket}/${key}`, 'tmp'])
// Read content of the file
const data = await execReadOutput('cat', ['tmp'])
// Remove the temporary file
await exec('rm', ['tmp'])
return data
}
/**
* Deletes a file at a specified key from a given S3 bucket
* Executes "aws s3 rm"
* @param options.key - The key of a file to remove in the S3 bucket
* @param options.bucket - The name of the S3 bucket (globally unique)
* @returns exitCode - shell command exit code
*/
export async function removeFileFromS3({key, bucket}: {key: string; bucket: string}) {
await exec('aws s3 rm', [`s3://${bucket}/${key}`])
}
/**
* Executes the action function and correctly handles any errors caught
* @param action - The async function running the action script
*/
export async function runAction(action: () => Promise<unknown>) {
try {
return await action()
} catch (error: unknown) {
if (error instanceof Error) {
core.error(error.stack ?? error.message)
core.setFailed(error)
} else {
core.setFailed(String(error))
}
}
}
/**
* Validate if the passed git commit hash is present on the current branch
* @param commitHash - commit hash to validate
* @returns isHeadAncestor
*/
export async function isHeadAncestor(commitHash: string) {
return execIsSuccessful('git merge-base', [`--is-ancestor`, commitHash, `HEAD`])
}
/**
* Retrieves the commit hash for the provided ref
* ref can be either a specific commit, or HEAD
* @returns SHA-1 of the commit hash
*/
export async function getCommitHashFromRef(ref: string) {
return execReadOutput(`git rev-parse`, [ref])
}