generated from actions/typescript-action
-
Notifications
You must be signed in to change notification settings - Fork 142
/
main.ts
190 lines (171 loc) · 6.59 KB
/
main.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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
import * as core from '@actions/core'
import {context, GitHub} from '@actions/github'
type Format = 'space-delimited' | 'csv' | 'json'
type FileStatus = 'added' | 'modified' | 'removed' | 'renamed'
async function run(): Promise<void> {
try {
// Create GitHub client with the API token.
const client = new GitHub(core.getInput('token', {required: true}))
const format = core.getInput('format', {required: true}) as Format
// Ensure that the format parameter is set properly.
if (format !== 'space-delimited' && format !== 'csv' && format !== 'json') {
core.setFailed(`Format must be one of 'string-delimited', 'csv', or 'json', got '${format}'.`)
}
// Debug log the payload.
core.debug(`Payload keys: ${Object.keys(context.payload)}`)
// Get event name.
const eventName = context.eventName
// Define the base and head commits to be extracted from the payload.
let base: string | undefined
let head: string | undefined
switch (eventName) {
case 'pull_request':
base = context.payload.pull_request?.base?.sha
head = context.payload.pull_request?.head?.sha
break
case 'push':
base = context.payload.before
head = context.payload.after
break
default:
core.setFailed(
`This action only supports pull requests and pushes, ${context.eventName} events are not supported. ` +
"Please submit an issue on this action's GitHub repo if you believe this in correct."
)
}
// Log the base and head commits
core.info(`Base commit: ${base}`)
core.info(`Head commit: ${head}`)
// Ensure that the base and head properties are set on the payload.
if (!base || !head) {
core.setFailed(
`The base and head commits are missing from the payload for this ${context.eventName} event. ` +
"Please submit an issue on this action's GitHub repo."
)
// To satisfy TypeScript, even though this is unreachable.
base = ''
head = ''
}
// Use GitHub's compare two commits API.
// https://developer.github.com/v3/repos/commits/#compare-two-commits
const response = await client.repos.compareCommits({
base,
head,
owner: context.repo.owner,
repo: context.repo.repo
})
// Ensure that the request was successful.
if (response.status !== 200) {
core.setFailed(
`The GitHub API for comparing the base and head commits for this ${context.eventName} event returned ${response.status}, expected 200. ` +
"Please submit an issue on this action's GitHub repo."
)
}
// Ensure that the head commit is ahead of the base commit.
if (response.data.status !== 'ahead') {
core.setFailed(
`The head commit for this ${context.eventName} event is not ahead of the base commit. ` +
"Please submit an issue on this action's GitHub repo."
)
}
// Get the changed files from the response payload.
const files = response.data.files
const all = [] as string[],
added = [] as string[],
modified = [] as string[],
removed = [] as string[],
renamed = [] as string[],
addedModified = [] as string[]
for (const file of files) {
const filename = file.filename
// If we're using the 'space-delimited' format and any of the filenames have a space in them,
// then fail the step.
if (format === 'space-delimited' && filename.includes(' ')) {
core.setFailed(
`One of your files includes a space. Consider using a different output format or removing spaces from your filenames. ` +
"Please submit an issue on this action's GitHub repo."
)
}
all.push(filename)
switch (file.status as FileStatus) {
case 'added':
added.push(filename)
addedModified.push(filename)
break
case 'modified':
modified.push(filename)
addedModified.push(filename)
break
case 'removed':
removed.push(filename)
break
case 'renamed':
renamed.push(filename)
break
default:
core.setFailed(
`One of your files includes an unsupported file status '${file.status}', expected 'added', 'modified', 'removed', or 'renamed'.`
)
}
}
// Format the arrays of changed files.
let allFormatted: string,
addedFormatted: string,
modifiedFormatted: string,
removedFormatted: string,
renamedFormatted: string,
addedModifiedFormatted: string
switch (format) {
case 'space-delimited':
// If any of the filenames have a space in them, then fail the step.
for (const file of all) {
if (file.includes(' '))
core.setFailed(
`One of your files includes a space. Consider using a different output format or removing spaces from your filenames.`
)
}
allFormatted = all.join(' ')
addedFormatted = added.join(' ')
modifiedFormatted = modified.join(' ')
removedFormatted = removed.join(' ')
renamedFormatted = renamed.join(' ')
addedModifiedFormatted = addedModified.join(' ')
break
case 'csv':
allFormatted = all.join(',')
addedFormatted = added.join(',')
modifiedFormatted = modified.join(',')
removedFormatted = removed.join(',')
renamedFormatted = renamed.join(',')
addedModifiedFormatted = addedModified.join(',')
break
case 'json':
allFormatted = JSON.stringify(all)
addedFormatted = JSON.stringify(added)
modifiedFormatted = JSON.stringify(modified)
removedFormatted = JSON.stringify(removed)
renamedFormatted = JSON.stringify(renamed)
addedModifiedFormatted = JSON.stringify(addedModified)
break
}
// Log the output values.
core.info(`All: ${allFormatted}`)
core.info(`Added: ${addedFormatted}`)
core.info(`Modified: ${modifiedFormatted}`)
core.info(`Removed: ${removedFormatted}`)
core.info(`Renamed: ${renamedFormatted}`)
core.info(`Added or modified: ${addedModifiedFormatted}`)
// Set step output context.
core.setOutput('all', allFormatted)
core.setOutput('added', addedFormatted)
core.setOutput('modified', modifiedFormatted)
core.setOutput('removed', removedFormatted)
core.setOutput('renamed', renamedFormatted)
core.setOutput('added_modified', addedModifiedFormatted)
// For backwards-compatibility
core.setOutput('deleted', removedFormatted)
} catch (error) {
core.setFailed(error.message)
}
}
run()