@jsenv/github-pull-request-impact 1.6.4 → 1.6.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -1,17 +1,13 @@
|
|
|
1
|
-
# GitHub pull request impact
|
|
1
|
+
# GitHub pull request impact [](https://www.npmjs.com/package/@jsenv/github-pull-request-impact)
|
|
2
2
|
|
|
3
3
|
Report pull request impact on something.
|
|
4
4
|
|
|
5
|
-
[](https://www.npmjs.com/package/@jsenv/github-pull-request-impact)
|
|
6
|
-
[](https://github.com/jsenv/github-pull-request-impact/actions?workflow=main)
|
|
7
|
-
[](https://codecov.io/gh/jsenv/github-pull-request-impact)
|
|
8
|
-
|
|
9
5
|
# Presentation
|
|
10
6
|
|
|
11
7
|
Under construction.
|
|
12
8
|
|
|
13
|
-
This repository publishes `@jsenv/github-pull-request-impact` on
|
|
9
|
+
This repository publishes `@jsenv/github-pull-request-impact` on NPM. This package is reused internally by:
|
|
14
10
|
|
|
15
|
-
- [@jsenv/performance-impact](
|
|
16
|
-
- [@jsenv/file-size-impact](
|
|
17
|
-
- [@jsenv/lighthouse-score-impact](
|
|
11
|
+
- [@jsenv/performance-impact](../jsenv-performance-impact)
|
|
12
|
+
- [@jsenv/file-size-impact](../jsenv-file-size-impact)
|
|
13
|
+
- [@jsenv/lighthouse-score-impact](../jsenv-performance-impact)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jsenv/github-pull-request-impact",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.8",
|
|
4
4
|
"description": "Report pull request impact on something",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": {
|
|
@@ -10,13 +10,15 @@
|
|
|
10
10
|
},
|
|
11
11
|
"repository": {
|
|
12
12
|
"type": "git",
|
|
13
|
-
"url": "https://github.com/jsenv/
|
|
13
|
+
"url": "https://github.com/jsenv/workflow",
|
|
14
|
+
"directory": "packages/jsenv-github-pull-request-impact"
|
|
14
15
|
},
|
|
15
16
|
"engines": {
|
|
16
|
-
"node": ">=
|
|
17
|
+
"node": ">=16.13.0"
|
|
17
18
|
},
|
|
18
19
|
"publishConfig": {
|
|
19
|
-
"access": "public"
|
|
20
|
+
"access": "public",
|
|
21
|
+
"registry": "https://registry.npmjs.org"
|
|
20
22
|
},
|
|
21
23
|
"type": "module",
|
|
22
24
|
"exports": {
|
|
@@ -25,42 +27,31 @@
|
|
|
25
27
|
},
|
|
26
28
|
"./*": "./*"
|
|
27
29
|
},
|
|
30
|
+
"main": "./main.js",
|
|
28
31
|
"files": [
|
|
29
32
|
"/src/",
|
|
30
33
|
"/main.js"
|
|
31
34
|
],
|
|
32
35
|
"scripts": {
|
|
33
|
-
"eslint
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
+
"eslint": "npx eslint . --ext=.js,.mjs",
|
|
37
|
+
"importmap": "node ./script/importmap/importmap.mjs",
|
|
38
|
+
"test": "node ./script/test/test.mjs",
|
|
36
39
|
"test-with-coverage": "npm run test -- --coverage",
|
|
37
|
-
"prettier
|
|
38
|
-
"prettier-format-stage": "npm run prettier-format -- --staged",
|
|
39
|
-
"prettier-check": "npm run prettier-format -- --dry-run",
|
|
40
|
-
"log-performance-report": "node .github/workflows/performance_impact/generate_performance_report.js --log",
|
|
41
|
-
"upload-coverage": "node ./script/upload-coverage/upload-coverage.js",
|
|
42
|
-
"prepublishOnly": "node ./script/transform-package/remove-postinstall.js",
|
|
43
|
-
"postpublish": "node ./script/transform-package/restore-postinstall.js"
|
|
40
|
+
"prettier": "prettier --write ."
|
|
44
41
|
},
|
|
45
42
|
"dependencies": {
|
|
46
|
-
"@jsenv/
|
|
43
|
+
"@jsenv/filesystem": "2.7.1",
|
|
47
44
|
"@jsenv/logger": "4.0.1",
|
|
48
|
-
"
|
|
49
|
-
"@jsenv/util": "4.1.1"
|
|
45
|
+
"node-fetch": "2.6.7"
|
|
50
46
|
},
|
|
51
47
|
"devDependencies": {
|
|
52
|
-
"@jsenv/assert": "2.
|
|
53
|
-
"@jsenv/
|
|
54
|
-
"@jsenv/
|
|
55
|
-
"@jsenv/eslint-
|
|
56
|
-
"@jsenv/
|
|
57
|
-
"
|
|
58
|
-
"
|
|
59
|
-
"
|
|
60
|
-
"@jsenv/performance-impact": "1.2.1",
|
|
61
|
-
"@jsenv/prettier-check-project": "5.6.1",
|
|
62
|
-
"eslint": "7.31.0",
|
|
63
|
-
"eslint-plugin-import": "2.23.4",
|
|
64
|
-
"prettier": "2.3.2"
|
|
48
|
+
"@jsenv/assert": "2.4.1",
|
|
49
|
+
"@jsenv/core": "25.3.0",
|
|
50
|
+
"@jsenv/eslint-config": "16.0.9",
|
|
51
|
+
"@jsenv/importmap-eslint-resolver": "5.2.5",
|
|
52
|
+
"@jsenv/importmap-node-module": "5.1.3",
|
|
53
|
+
"eslint": "8.7.0",
|
|
54
|
+
"eslint-plugin-import": "2.25.4",
|
|
55
|
+
"prettier": "2.5.1"
|
|
65
56
|
}
|
|
66
57
|
}
|
|
@@ -4,16 +4,14 @@
|
|
|
4
4
|
* @jsenv/file-size-impact, @jsenv/performance-impact and @jsenv/lighthouse-score-impact
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { createLogger } from "@jsenv/logger"
|
|
8
7
|
import {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
} from "@jsenv/
|
|
13
|
-
import { assertAndNormalizeDirectoryUrl, urlToFileSystemPath } from "@jsenv/util"
|
|
8
|
+
assertAndNormalizeDirectoryUrl,
|
|
9
|
+
urlToFileSystemPath,
|
|
10
|
+
} from "@jsenv/filesystem"
|
|
11
|
+
import { createLogger } from "@jsenv/logger"
|
|
14
12
|
|
|
13
|
+
import * as githubRESTAPI from "./internal/github_rest_api.js"
|
|
15
14
|
import { exec } from "./internal/exec.js"
|
|
16
|
-
import { GET, POST, PATCH } from "./internal/git_hub_api.js"
|
|
17
15
|
import { renderGeneratedByText } from "./internal/renderGeneratedByText.js"
|
|
18
16
|
import { createGitHubPullRequestCommentText } from "./internal/createGitHubPullRequestCommentText.js"
|
|
19
17
|
|
|
@@ -21,8 +19,6 @@ export const commentGitHubPullRequestImpact = async ({
|
|
|
21
19
|
logLevel,
|
|
22
20
|
commandLogs = false,
|
|
23
21
|
infoLogs = true,
|
|
24
|
-
cancellationToken = createCancellationToken(),
|
|
25
|
-
cancelOnSIGINT = true,
|
|
26
22
|
projectDirectoryUrl,
|
|
27
23
|
|
|
28
24
|
githubToken,
|
|
@@ -47,51 +43,46 @@ export const commentGitHubPullRequestImpact = async ({
|
|
|
47
43
|
}) => {
|
|
48
44
|
projectDirectoryUrl = assertAndNormalizeDirectoryUrl(projectDirectoryUrl)
|
|
49
45
|
if (typeof collectInfo !== "function") {
|
|
50
|
-
throw new TypeError(
|
|
46
|
+
throw new TypeError(
|
|
47
|
+
`collectInfo must be a function but received ${collectInfo}`,
|
|
48
|
+
)
|
|
51
49
|
}
|
|
52
50
|
if (typeof commentIdentifier !== "string") {
|
|
53
|
-
throw new TypeError(
|
|
51
|
+
throw new TypeError(
|
|
52
|
+
`commentIdentifier must be a string but received ${commentIdentifier}`,
|
|
53
|
+
)
|
|
54
54
|
}
|
|
55
55
|
if (typeof githubToken !== "string") {
|
|
56
|
-
throw new TypeError(
|
|
56
|
+
throw new TypeError(
|
|
57
|
+
`githubToken must be a string but received ${githubToken}`,
|
|
58
|
+
)
|
|
57
59
|
}
|
|
58
60
|
if (typeof repositoryOwner !== "string") {
|
|
59
|
-
throw new TypeError(
|
|
61
|
+
throw new TypeError(
|
|
62
|
+
`repositoryOwner must be a string but received ${repositoryOwner}`,
|
|
63
|
+
)
|
|
60
64
|
}
|
|
61
65
|
if (typeof repositoryName !== "string") {
|
|
62
|
-
throw new TypeError(
|
|
66
|
+
throw new TypeError(
|
|
67
|
+
`repositoryName must be a string but received ${repositoryName}`,
|
|
68
|
+
)
|
|
63
69
|
}
|
|
64
70
|
pullRequestNumber = String(pullRequestNumber)
|
|
65
71
|
if (typeof pullRequestNumber !== "string") {
|
|
66
|
-
throw new TypeError(
|
|
72
|
+
throw new TypeError(
|
|
73
|
+
`pullRequestNumber must be a string but received ${pullRequestNumber}`,
|
|
74
|
+
)
|
|
67
75
|
}
|
|
68
76
|
|
|
69
77
|
const logger = createLogger({ logLevel })
|
|
70
78
|
|
|
71
79
|
let cleanup = () => {}
|
|
72
80
|
|
|
73
|
-
if (cancelOnSIGINT) {
|
|
74
|
-
const processCancellationSource = createCancellationSource()
|
|
75
|
-
const processCancellationToken = processCancellationSource.token
|
|
76
|
-
cancellationToken = composeCancellationToken(cancellationToken, processCancellationToken)
|
|
77
|
-
const SIGINTCallback = () => {
|
|
78
|
-
processCancellationSource.cancel("process SIGINT")
|
|
79
|
-
}
|
|
80
|
-
process.once("SIGINT", SIGINTCallback)
|
|
81
|
-
|
|
82
|
-
// beware if someday something do things on cleanup
|
|
83
|
-
// to call the old cleanup function
|
|
84
|
-
cleanup = () => {
|
|
85
|
-
process.removeListener("SIGINT", SIGINTCallback)
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
81
|
try {
|
|
90
82
|
return await commentPrImpact({
|
|
91
83
|
logger,
|
|
92
84
|
commandLogs,
|
|
93
85
|
infoLogs,
|
|
94
|
-
cancellationToken,
|
|
95
86
|
projectDirectoryUrl,
|
|
96
87
|
|
|
97
88
|
githubToken,
|
|
@@ -120,7 +111,6 @@ const commentPrImpact = async ({
|
|
|
120
111
|
logger,
|
|
121
112
|
infoLogs,
|
|
122
113
|
commandLogs,
|
|
123
|
-
cancellationToken,
|
|
124
114
|
projectDirectoryUrl,
|
|
125
115
|
|
|
126
116
|
githubToken,
|
|
@@ -156,8 +146,8 @@ const commentPrImpact = async ({
|
|
|
156
146
|
const pullApiUrl = `https://api.github.com/repos/${repositoryOwner}/${repositoryName}/pulls/${pullRequestNumber}`
|
|
157
147
|
// https://developer.github.com/v3/pulls/#get-a-pull-request
|
|
158
148
|
logger.debug(`get pull request ${pullApiUrl}`)
|
|
159
|
-
const pullRequest = await GET(
|
|
160
|
-
|
|
149
|
+
const pullRequest = await githubRESTAPI.GET({
|
|
150
|
+
url: pullApiUrl,
|
|
161
151
|
githubToken,
|
|
162
152
|
})
|
|
163
153
|
const pullRequestHtmlUrl = pullRequest.html_url
|
|
@@ -187,11 +177,13 @@ const commentPrImpact = async ({
|
|
|
187
177
|
|
|
188
178
|
logger.debug(`searching comment in pull request ${pullRequestHtmlUrl}`)
|
|
189
179
|
const pullRequestCommentApiUrl = pullRequest.comments_url
|
|
190
|
-
const comments = await GET(
|
|
180
|
+
const comments = await pullApiUrl.GET({
|
|
181
|
+
url: pullRequestCommentApiUrl,
|
|
191
182
|
githubToken,
|
|
192
|
-
cancellationToken,
|
|
193
183
|
})
|
|
194
|
-
const existingComment = comments.find(({ body }) =>
|
|
184
|
+
const existingComment = comments.find(({ body }) =>
|
|
185
|
+
body.includes(commentIdentifier),
|
|
186
|
+
)
|
|
195
187
|
if (existingComment) {
|
|
196
188
|
logger.debug(`comment found at ${existingComment.html_url}.`)
|
|
197
189
|
} else {
|
|
@@ -224,27 +216,29 @@ const commentPrImpact = async ({
|
|
|
224
216
|
return existingComment
|
|
225
217
|
}
|
|
226
218
|
logger.info(`updating comment at ${existingComment.html_url}`)
|
|
227
|
-
const comment = await PATCH(
|
|
228
|
-
`https://api.github.com/repos/${repositoryOwner}/${repositoryName}/issues/comments/${existingComment.id}`,
|
|
229
|
-
|
|
230
|
-
{
|
|
231
|
-
)
|
|
219
|
+
const comment = await githubRESTAPI.PATCH({
|
|
220
|
+
url: `https://api.github.com/repos/${repositoryOwner}/${repositoryName}/issues/comments/${existingComment.id}`,
|
|
221
|
+
githubToken,
|
|
222
|
+
body: { body: commentBody },
|
|
223
|
+
})
|
|
232
224
|
logger.info("comment updated")
|
|
233
225
|
return comment
|
|
234
226
|
}
|
|
235
227
|
|
|
236
228
|
logger.info(`creating comment`)
|
|
237
|
-
const comment = await POST(
|
|
238
|
-
`https://api.github.com/repos/${repositoryOwner}/${repositoryName}/issues/${pullRequestNumber}/comments`,
|
|
239
|
-
|
|
240
|
-
{
|
|
241
|
-
)
|
|
229
|
+
const comment = await githubRESTAPI.POST({
|
|
230
|
+
url: `https://api.github.com/repos/${repositoryOwner}/${repositoryName}/issues/${pullRequestNumber}/comments`,
|
|
231
|
+
githubToken,
|
|
232
|
+
body: { body: commentBody },
|
|
233
|
+
})
|
|
242
234
|
logger.info(`comment created at ${comment.html_url}`)
|
|
243
235
|
return comment
|
|
244
236
|
}
|
|
245
237
|
|
|
246
|
-
const isFork =
|
|
247
|
-
|
|
238
|
+
const isFork =
|
|
239
|
+
pullRequest.base.repo.full_name !== pullRequest.head.repo.full_name
|
|
240
|
+
const isInPullRequestWorkflow =
|
|
241
|
+
process.env.GITHUB_EVENT_NAME === "pull_request"
|
|
248
242
|
if (isFork && isInPullRequestWorkflow) {
|
|
249
243
|
logger.warn(formatGithubTokenNotAllowedToCommentWarning())
|
|
250
244
|
}
|
|
@@ -260,10 +254,13 @@ const commentPrImpact = async ({
|
|
|
260
254
|
let beforeMergeInfo
|
|
261
255
|
try {
|
|
262
256
|
// cannot use depth=1 arg otherwise git merge might have merge conflicts
|
|
263
|
-
await execCommandInProjectDirectory(
|
|
264
|
-
|
|
257
|
+
await execCommandInProjectDirectory(
|
|
258
|
+
`git fetch --no-tags --prune origin ${pullRequestBase}`,
|
|
259
|
+
)
|
|
260
|
+
await execCommandInProjectDirectory(
|
|
261
|
+
`git reset --hard origin/${pullRequestBase}`,
|
|
262
|
+
)
|
|
265
263
|
beforeMergeInfo = await collectInfo({
|
|
266
|
-
cancellationToken,
|
|
267
264
|
beforeMerge: true,
|
|
268
265
|
execCommandInProjectDirectory,
|
|
269
266
|
})
|
|
@@ -273,7 +270,10 @@ const commentPrImpact = async ({
|
|
|
273
270
|
} catch (error) {
|
|
274
271
|
logger.error(error.stack)
|
|
275
272
|
const comment = await patchOrPostComment(
|
|
276
|
-
createCommentForBeforeMergeError(error, {
|
|
273
|
+
createCommentForBeforeMergeError(error, {
|
|
274
|
+
pullRequestHead,
|
|
275
|
+
pullRequestBase,
|
|
276
|
+
}),
|
|
277
277
|
)
|
|
278
278
|
if (catchError) {
|
|
279
279
|
return { error, comment }
|
|
@@ -285,11 +285,15 @@ const commentPrImpact = async ({
|
|
|
285
285
|
try {
|
|
286
286
|
// buildCommand might generate files that could conflict when doing the merge
|
|
287
287
|
// reset to avoid potential merge conflicts
|
|
288
|
-
await execCommandInProjectDirectory(
|
|
288
|
+
await execCommandInProjectDirectory(
|
|
289
|
+
`git reset --hard origin/${pullRequestBase}`,
|
|
290
|
+
)
|
|
289
291
|
// Avoid "The following untracked working tree files would be overwritten by merge" error
|
|
290
292
|
await execCommandInProjectDirectory(`git clean -d -f .`)
|
|
291
293
|
// cannot use depth=1 arg otherwise git merge might have merge conflicts
|
|
292
|
-
await execCommandInProjectDirectory(
|
|
294
|
+
await execCommandInProjectDirectory(
|
|
295
|
+
`git fetch --no-tags --prune origin ${headRef}`,
|
|
296
|
+
)
|
|
293
297
|
// ensure there is user.email + user.name required to perform git merge command
|
|
294
298
|
// without them git would complain that it does not know who we are
|
|
295
299
|
|
|
@@ -301,11 +305,12 @@ const commentPrImpact = async ({
|
|
|
301
305
|
valueIfMissing: "Your Name",
|
|
302
306
|
execCommandInProjectDirectory,
|
|
303
307
|
})
|
|
304
|
-
await execCommandInProjectDirectory(
|
|
308
|
+
await execCommandInProjectDirectory(
|
|
309
|
+
`git merge FETCH_HEAD --allow-unrelated-histories`,
|
|
310
|
+
)
|
|
305
311
|
await restoreGitUserEmail()
|
|
306
312
|
await restoreGitUserName()
|
|
307
313
|
afterMergeInfo = await collectInfo({
|
|
308
|
-
cancellationToken,
|
|
309
314
|
afterMerge: true,
|
|
310
315
|
execCommandInProjectDirectory,
|
|
311
316
|
})
|
|
@@ -315,7 +320,10 @@ const commentPrImpact = async ({
|
|
|
315
320
|
} catch (error) {
|
|
316
321
|
logger.error(error.stack)
|
|
317
322
|
const gitHubComment = await patchOrPostComment(
|
|
318
|
-
createCommentForAfterMergeError(error, {
|
|
323
|
+
createCommentForAfterMergeError(error, {
|
|
324
|
+
pullRequestHead,
|
|
325
|
+
pullRequestBase,
|
|
326
|
+
}),
|
|
319
327
|
)
|
|
320
328
|
if (catchError) {
|
|
321
329
|
return { error, gitHubComment }
|
|
@@ -336,7 +344,6 @@ const commentPrImpact = async ({
|
|
|
336
344
|
}
|
|
337
345
|
|
|
338
346
|
const commentForComparison = await createCommentForComparison({
|
|
339
|
-
cancellationToken,
|
|
340
347
|
logger,
|
|
341
348
|
|
|
342
349
|
pullRequestBase,
|
|
@@ -350,12 +357,17 @@ const commentPrImpact = async ({
|
|
|
350
357
|
return { gitHubComment }
|
|
351
358
|
}
|
|
352
359
|
|
|
353
|
-
const ensureGitConfig = async (
|
|
360
|
+
const ensureGitConfig = async (
|
|
361
|
+
name,
|
|
362
|
+
{ execCommandInProjectDirectory, valueIfMissing },
|
|
363
|
+
) => {
|
|
354
364
|
try {
|
|
355
365
|
await execCommandInProjectDirectory(`git config ${name}`)
|
|
356
366
|
return () => {}
|
|
357
367
|
} catch (e) {
|
|
358
|
-
await execCommandInProjectDirectory(
|
|
368
|
+
await execCommandInProjectDirectory(
|
|
369
|
+
`git config ${name} "${valueIfMissing}"`,
|
|
370
|
+
)
|
|
359
371
|
return async () => {
|
|
360
372
|
await execCommandInProjectDirectory(`git config --unset ${name}`)
|
|
361
373
|
}
|
|
@@ -391,7 +403,10 @@ To fix this, change "pull_request" for "pull_request_target" in your workflow fi
|
|
|
391
403
|
See https://docs.github.com/en/actions/reference/events-that-trigger-workflows#pull_request_target`
|
|
392
404
|
}
|
|
393
405
|
|
|
394
|
-
const jsenvCreateBeforeMergeErrorComment = (
|
|
406
|
+
const jsenvCreateBeforeMergeErrorComment = (
|
|
407
|
+
error,
|
|
408
|
+
{ pullRequestBase, pullRequestHead },
|
|
409
|
+
) => {
|
|
395
410
|
return `---
|
|
396
411
|
|
|
397
412
|
**Error:** Error while trying to collect info before merging ${pullRequestHead} into ${pullRequestBase}.
|
|
@@ -401,7 +416,10 @@ const jsenvCreateBeforeMergeErrorComment = (error, { pullRequestBase, pullReques
|
|
|
401
416
|
---`
|
|
402
417
|
}
|
|
403
418
|
|
|
404
|
-
const jsenvCreateCommentForAfterMergeError = (
|
|
419
|
+
const jsenvCreateCommentForAfterMergeError = (
|
|
420
|
+
error,
|
|
421
|
+
{ pullRequestBase, pullRequestHead },
|
|
422
|
+
) => {
|
|
405
423
|
return `---
|
|
406
424
|
|
|
407
425
|
**Error:** Error while trying to collect info after merging ${pullRequestHead} into ${pullRequestBase}.
|
|
@@ -411,7 +429,10 @@ const jsenvCreateCommentForAfterMergeError = (error, { pullRequestBase, pullRequ
|
|
|
411
429
|
---`
|
|
412
430
|
}
|
|
413
431
|
|
|
414
|
-
const jsenvCreateCommentForVersionMismatch = ({
|
|
432
|
+
const jsenvCreateCommentForVersionMismatch = ({
|
|
433
|
+
beforeMergeVersion,
|
|
434
|
+
afterMergeversion,
|
|
435
|
+
}) => {
|
|
415
436
|
return `---
|
|
416
437
|
|
|
417
438
|
**Error:** Cannot compare before and after merge data because the version are different.
|
|
@@ -423,7 +444,10 @@ After merge data version: ${afterMergeversion}
|
|
|
423
444
|
---`
|
|
424
445
|
}
|
|
425
446
|
|
|
426
|
-
const jsenvCreateCommentForComparison = ({
|
|
447
|
+
const jsenvCreateCommentForComparison = ({
|
|
448
|
+
beforeMergeInfo,
|
|
449
|
+
afterMergeInfo,
|
|
450
|
+
}) => {
|
|
427
451
|
return `--- before merge ---
|
|
428
452
|
${JSON.stringify(beforeMergeInfo, null, " ")}
|
|
429
453
|
--- after merge ---
|
package/src/internal/exec.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
import { exec as nodeExec } from "child_process"
|
|
1
|
+
import { exec as nodeExec } from "node:child_process"
|
|
2
2
|
|
|
3
|
-
export const exec = (
|
|
3
|
+
export const exec = (
|
|
4
|
+
command,
|
|
5
|
+
{ cwd, onLog = () => {}, onErrorLog = () => {} } = {},
|
|
6
|
+
) => {
|
|
4
7
|
return new Promise((resolve, reject) => {
|
|
5
8
|
const commandProcess = nodeExec(
|
|
6
9
|
command,
|
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
import
|
|
1
|
+
import nodeFetch from "node-fetch"
|
|
2
2
|
|
|
3
|
-
export const GET = async (url,
|
|
4
|
-
return sendHttpRequest(
|
|
5
|
-
|
|
3
|
+
export const GET = async ({ url, githubToken, headers }) => {
|
|
4
|
+
return sendHttpRequest({
|
|
5
|
+
url,
|
|
6
6
|
method: "GET",
|
|
7
|
-
headers:
|
|
8
|
-
|
|
7
|
+
headers: {
|
|
8
|
+
...tokenToHeaders(githubToken),
|
|
9
|
+
headers,
|
|
10
|
+
},
|
|
11
|
+
responseStatusHandlers: {
|
|
9
12
|
200: async (response) => {
|
|
10
13
|
const json = await response.json()
|
|
11
14
|
return json
|
|
@@ -15,13 +18,16 @@ export const GET = async (url, { githubToken, cancellationToken } = {}) => {
|
|
|
15
18
|
})
|
|
16
19
|
}
|
|
17
20
|
|
|
18
|
-
export const POST = (url, body,
|
|
19
|
-
return sendHttpRequest(
|
|
20
|
-
|
|
21
|
+
export const POST = ({ url, body, githubToken, headers }) => {
|
|
22
|
+
return sendHttpRequest({
|
|
23
|
+
url,
|
|
21
24
|
method: "POST",
|
|
22
|
-
headers:
|
|
25
|
+
headers: {
|
|
26
|
+
...tokenToHeaders(githubToken),
|
|
27
|
+
headers,
|
|
28
|
+
},
|
|
23
29
|
body: JSON.stringify(body),
|
|
24
|
-
|
|
30
|
+
responseStatusHandlers: {
|
|
25
31
|
201: async (response) => {
|
|
26
32
|
const json = await response.json()
|
|
27
33
|
return json
|
|
@@ -30,13 +36,16 @@ export const POST = (url, body, { cancellationToken, githubToken } = {}) => {
|
|
|
30
36
|
})
|
|
31
37
|
}
|
|
32
38
|
|
|
33
|
-
export const PATCH = async (url, body,
|
|
34
|
-
return sendHttpRequest(
|
|
35
|
-
|
|
39
|
+
export const PATCH = async ({ url, body, githubToken, headers }) => {
|
|
40
|
+
return sendHttpRequest({
|
|
41
|
+
url,
|
|
36
42
|
method: "PATCH",
|
|
37
|
-
headers:
|
|
43
|
+
headers: {
|
|
44
|
+
...tokenToHeaders(githubToken),
|
|
45
|
+
headers,
|
|
46
|
+
},
|
|
38
47
|
body: JSON.stringify(body),
|
|
39
|
-
|
|
48
|
+
responseStatusHandlers: {
|
|
40
49
|
200: async (response) => {
|
|
41
50
|
const json = await response.json()
|
|
42
51
|
return json
|
|
@@ -54,17 +63,21 @@ const tokenToHeaders = (token) => {
|
|
|
54
63
|
}
|
|
55
64
|
}
|
|
56
65
|
|
|
57
|
-
const sendHttpRequest = async (
|
|
66
|
+
const sendHttpRequest = async ({
|
|
58
67
|
url,
|
|
59
|
-
|
|
60
|
-
|
|
68
|
+
method,
|
|
69
|
+
headers,
|
|
70
|
+
body,
|
|
71
|
+
responseStatusHandlers = {},
|
|
72
|
+
}) => {
|
|
61
73
|
let response
|
|
62
74
|
try {
|
|
63
|
-
response = await
|
|
64
|
-
cancellationToken,
|
|
75
|
+
response = await nodeFetch(url, {
|
|
65
76
|
method,
|
|
66
77
|
headers: {
|
|
67
|
-
...(typeof body === "undefined"
|
|
78
|
+
...(typeof body === "undefined"
|
|
79
|
+
? {}
|
|
80
|
+
: { "content-length": Buffer.byteLength(body) }),
|
|
68
81
|
...headers,
|
|
69
82
|
},
|
|
70
83
|
body,
|
|
@@ -80,16 +93,16 @@ ${error.stack}`)
|
|
|
80
93
|
}
|
|
81
94
|
|
|
82
95
|
const { status } = response
|
|
83
|
-
|
|
84
|
-
|
|
96
|
+
const responseStatusHandler = responseStatusHandlers[status]
|
|
97
|
+
if (responseStatusHandler) {
|
|
98
|
+
return responseStatusHandler(response)
|
|
85
99
|
}
|
|
86
|
-
|
|
87
100
|
const responseBodyAsJson = await response.json()
|
|
88
101
|
const error = new Error(`unexpected response status.
|
|
89
102
|
--- response status ---
|
|
90
103
|
${response.status}
|
|
91
104
|
--- expected response status ---
|
|
92
|
-
${Object.keys(
|
|
105
|
+
${Object.keys(responseStatusHandlers).join(", ")}
|
|
93
106
|
--- request method ---
|
|
94
107
|
${method}
|
|
95
108
|
--- request url ---
|
|
@@ -1,28 +1,25 @@
|
|
|
1
|
-
import { readFileSync } from "fs"
|
|
1
|
+
import { readFileSync } from "node:fs"
|
|
2
2
|
|
|
3
3
|
export const readGitHubWorkflowEnv = () => {
|
|
4
4
|
const eventName = process.env.GITHUB_EVENT_NAME
|
|
5
5
|
if (!eventName) {
|
|
6
|
-
throw new Error(
|
|
6
|
+
throw new Error(
|
|
7
|
+
`missing process.env.GITHUB_EVENT_NAME, we are not in a github workflow`,
|
|
8
|
+
)
|
|
7
9
|
}
|
|
8
10
|
if (eventName !== "pull_request" && eventName !== "pull_request_target") {
|
|
9
11
|
throw new Error(`must be called only in a pull request`)
|
|
10
12
|
}
|
|
11
|
-
|
|
12
13
|
const githubToken = process.env.GITHUB_TOKEN
|
|
13
|
-
|
|
14
14
|
if (!githubToken) {
|
|
15
15
|
throw new Error(`missing githubToken`)
|
|
16
16
|
}
|
|
17
|
-
|
|
18
17
|
const githubRepository = process.env.GITHUB_REPOSITORY
|
|
19
18
|
if (!githubRepository) {
|
|
20
19
|
throw new Error(`missing process.env.GITHUB_REPOSITORY`)
|
|
21
20
|
}
|
|
22
|
-
|
|
23
21
|
const [repositoryOwner, repositoryName] = githubRepository.split("/")
|
|
24
22
|
const pullRequestNumber = readPullRequestNumber()
|
|
25
|
-
|
|
26
23
|
const runId = process.env.GITHUB_RUN_ID
|
|
27
24
|
const runLink = runId
|
|
28
25
|
? {
|
|
@@ -30,7 +27,6 @@ export const readGitHubWorkflowEnv = () => {
|
|
|
30
27
|
text: `${process.env.GITHUB_WORKFLOW || "workflow"}#${runId}`,
|
|
31
28
|
}
|
|
32
29
|
: undefined
|
|
33
|
-
|
|
34
30
|
return {
|
|
35
31
|
projectDirectoryUrl: process.env.GITHUB_WORKSPACE,
|
|
36
32
|
githubToken,
|
|
@@ -46,10 +42,8 @@ const readPullRequestNumber = () => {
|
|
|
46
42
|
if (!githubRef) {
|
|
47
43
|
throw new Error(`missing process.env.GITHUB_REF`)
|
|
48
44
|
}
|
|
49
|
-
|
|
50
45
|
const pullRequestNumber = githubRefToPullRequestNumber(githubRef)
|
|
51
46
|
if (pullRequestNumber) return pullRequestNumber
|
|
52
|
-
|
|
53
47
|
// https://github.com/actions/checkout/issues/58#issuecomment-589447479
|
|
54
48
|
const githubEventFilePath = process.env.GITHUB_EVENT_PATH
|
|
55
49
|
if (githubEventFilePath) {
|
|
@@ -67,7 +61,6 @@ ${githubEventFilePath}
|
|
|
67
61
|
return pullRequestNumber
|
|
68
62
|
}
|
|
69
63
|
}
|
|
70
|
-
|
|
71
64
|
throw new Error(`cannot get pull request number from process.env.GITHUB_REF
|
|
72
65
|
--- process.env.GITHUB_REF ---
|
|
73
66
|
${githubRef}`)
|
|
@@ -77,7 +70,9 @@ const githubRefToPullRequestNumber = (githubRef) => {
|
|
|
77
70
|
const pullPrefix = "refs/pull/"
|
|
78
71
|
const pullRequestNumberStartIndex = githubRef.indexOf(pullPrefix)
|
|
79
72
|
if (pullRequestNumberStartIndex === -1) return undefined
|
|
80
|
-
const afterPull = githubRef.slice(
|
|
73
|
+
const afterPull = githubRef.slice(
|
|
74
|
+
pullRequestNumberStartIndex + pullPrefix.length,
|
|
75
|
+
)
|
|
81
76
|
const slashAfterPullIndex = afterPull.indexOf("/")
|
|
82
77
|
if (slashAfterPullIndex === -1) return undefined
|
|
83
78
|
const pullRequestNumberString = afterPull.slice(0, slashAfterPullIndex)
|