This repository was archived by the owner on Oct 9, 2024. It is now read-only.
forked from parkerbxyz/suggest-changes
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.js
More file actions
98 lines (82 loc) · 3.2 KB
/
Copy pathindex.js
File metadata and controls
98 lines (82 loc) · 3.2 KB
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
// @ts-check
import { debug, getInput } from '@actions/core'
import { getExecOutput } from '@actions/exec'
import { Octokit } from '@octokit/action'
import { readFileSync } from 'node:fs'
import { env } from 'node:process'
import parseGitDiff from 'parse-git-diff'
const octokit = new Octokit({
userAgent: 'suggest-changes',
})
const [owner, repo] = String(env.GITHUB_REPOSITORY).split('/')
/** @type {import("@octokit/webhooks-types").PullRequestEvent} */
const eventPayload = JSON.parse(
readFileSync(String(env.GITHUB_EVENT_PATH), 'utf8')
)
const pull_number = Number(eventPayload.pull_request.number)
const pullRequestFiles = (
await octokit.pulls.listFiles({ owner, repo, pull_number })
).data.map((file) => file.filename)
// Get the diff between the head branch and the base branch (limit to the files in the pull request)
const diff = await getExecOutput('git', ['diff', '--unified=0', '--', ...pullRequestFiles], {
silent: true,
})
debug(`Diff output: ${diff.stdout}`)
// Create an array of changes from the diff output based on patches
const parsedDiff = parseGitDiff(diff.stdout)
// Get changed files from parsedDiff (changed files have type 'ChangedFile')
const changedFiles = parsedDiff.files.filter(
(/** @type {{ type: string; }} */ file) => file.type === 'ChangedFile'
)
const generateSuggestionBody = (changes) => {
const suggestionBody = changes
.filter(({ type }) => type === 'AddedLine' || type === 'UnchangedLine')
.map(({ content }) => content)
.join('\n')
// Quadruple backticks allow for triple backticks in a fenced code block in the suggestion body
// https://docs.github.com/get-started/writing-on-github/working-with-advanced-formatting/creating-and-highlighting-code-blocks#fenced-code-blocks
return `\`\`\`\`suggestion\n${suggestionBody}\n\`\`\`\``
}
function createSingleLineComment(path, fromFileRange, changes) {
return {
path,
line: fromFileRange.start,
body: generateSuggestionBody(changes),
}
}
function createMultiLineComment(path, fromFileRange, changes) {
return {
path,
start_line: fromFileRange.start,
// The last line of the chunk is the start line plus the number of lines in the chunk
// minus 1 to account for the start line being included in fromFileRange.lines
line: fromFileRange.start + fromFileRange.lines - 1,
start_side: 'RIGHT',
side: 'RIGHT',
body: generateSuggestionBody(changes),
}
}
// Create an array of comments with suggested changes for each chunk of each changed file
const comments = changedFiles.flatMap(({ path, chunks }) =>
chunks.map(({ fromFileRange, changes }) => {
debug(`Starting line: ${fromFileRange.start}`)
debug(`Number of lines: ${fromFileRange.lines}`)
debug(`Changes: ${JSON.stringify(changes)}`)
if (fromFileRange.start === fromFileRange.lines && changes.length === 2) {
return createSingleLineComment(path, fromFileRange, changes)
} else {
return createMultiLineComment(path, fromFileRange, changes)
}
})
)
// Create a review with the suggested changes if there are any
if (comments.length > 0) {
await octokit.pulls.createReview({
owner,
repo,
pull_number,
event: 'REQUEST_CHANGES',
body: getInput('comment'),
comments,
})
}