Skip to content

Commit 32204f0

Browse files
authored
Merge pull request #25 from saschanaz/owner-close
Support closing PR
2 parents cde6dba + 8ef0306 commit 32204f0

File tree

1 file changed

+88
-57
lines changed

1 file changed

+88
-57
lines changed

index.js

Lines changed: 88 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,14 @@ async function run() {
1616

1717
// Merge if they say they have access
1818
if (context.eventName === "issue_comment" || context.eventName === "pull_request_review") {
19-
mergeIfLGTMAndHasAccess()
19+
const bodyLower = getPayloadBody().toLowerCase();
20+
if (bodyLower.includes("lgtm")) {
21+
new Actor().mergeIfHasAccess();
22+
} else if (bodyLower.includes("@github-actions close")) {
23+
new Actor().closeIfHasAccess();
24+
} else {
25+
console.log("Doing nothing because the body does not include a command")
26+
}
2027
}
2128
}
2229

@@ -104,77 +111,101 @@ function pathListToMarkdown(files) {
104111
return files.map(i => `* [\`${i}\`](https://github.com/${context.repo.owner}/${context.repo.repo}/tree/HEAD${i})`).join("\n");
105112
}
106113

107-
async function mergeIfLGTMAndHasAccess() {
114+
function getPayloadBody() {
108115
const body = context.payload.comment ? context.payload.comment.body : context.payload.review.body
109-
if (!body) {
110-
// For debugging #8
111-
console.log(JSON.stringify(context))
116+
if (body == null) {
117+
throw new Error(`No body found, ${JSON.stringify(context)}`)
112118
}
119+
return body;
120+
}
113121

114-
if (!body || !body.toLowerCase().includes("lgtm")) {
115-
console.log("Comment does not include LGTM ('looks good to me') so not merging")
116-
process.exit(0)
122+
class Actor {
123+
constructor() {
124+
this.cwd = core.getInput('cwd') || process.cwd()
125+
this.octokit = getOctokit(process.env.GITHUB_TOKEN)
126+
this.thisRepo = { owner: context.repo.owner, repo: context.repo.repo }
127+
this.issue = context.payload.issue || context.payload.pull_request
128+
this.sender = context.payload.sender.login
117129
}
118130

119-
// Setup
120-
const cwd = core.getInput('cwd') || process.cwd()
121-
const octokit = getOctokit(process.env.GITHUB_TOKEN)
122-
const thisRepo = { owner: context.repo.owner, repo: context.repo.repo }
123-
const issue = context.payload.issue || context.payload.pull_request
124-
const sender = context.payload.sender.login
131+
async getTargetPRIfHasAccess() {
132+
const { octokit, thisRepo, sender, issue, cwd } = this;
133+
core.info(`\n\nLooking at the ${context.eventName} from ${sender} in '${issue.title}' to see if we can proceed`)
125134

126-
core.info(`\n\nLooking at the ${context.eventName} from ${sender} in '${issue.title}' to see if we can merge`)
135+
const changedFiles = await getPRChangedFiles(octokit, thisRepo, issue.number)
136+
core.info(`Changed files: \n - ${changedFiles.join("\n - ")}`)
127137

128-
const changedFiles = await getPRChangedFiles(octokit, thisRepo, issue.number)
129-
core.info(`Changed files: \n - ${changedFiles.join("\n - ")}`)
138+
const filesWhichArentOwned = getFilesNotOwnedByCodeOwner("@" + sender, changedFiles, cwd)
139+
if (filesWhichArentOwned.length !== 0) {
140+
console.log(`@${sender} does not have access to \n - ${filesWhichArentOwned.join("\n - ")}\n`)
141+
listFilesWithOwners(changedFiles, cwd)
142+
await octokit.issues.createComment({ ...thisRepo, issue_number: issue.number, body: `Sorry @${sender}, you don't have access to these files: ${pathListToMarkdown(filesWhichArentOwned)}.` })
143+
return
144+
}
130145

131-
const filesWhichArentOwned = getFilesNotOwnedByCodeOwner("@" + sender, changedFiles, cwd)
132-
if (filesWhichArentOwned.length !== 0) {
133-
console.log(`@${sender} does not have access to merge \n - ${filesWhichArentOwned.join("\n - ")}\n`)
134-
listFilesWithOwners(changedFiles, cwd)
135-
await octokit.issues.createComment({ ...thisRepo, issue_number: issue.number, body: `Sorry @${sender}, you don't have access to merge:\n${pathListToMarkdown(filesWhichArentOwned)}` });
136-
return
146+
const prInfo = await octokit.pulls.get({ ...thisRepo, pull_number: issue.number })
147+
if (prInfo.data.state.toLowerCase() !== "open") {
148+
await octokit.issues.createComment({ ...thisRepo, issue_number: issue.number, body: `Sorry @${sender}, this PR isn't open.` });
149+
return
150+
}
151+
return prInfo
137152
}
138153

139-
// Don't try merge unmergable stuff
140-
const prInfo = await octokit.pulls.get({ ...thisRepo, pull_number: issue.number })
141-
if (!prInfo.data.mergeable) {
142-
await octokit.issues.createComment({ ...thisRepo, issue_number: issue.number, body: `Sorry @${sender}, this PR has merge conflicts. They'll need to be fixed before this can be merged.` });
143-
return
144-
}
154+
async mergeIfHasAccess() {
155+
const prInfo = await this.getTargetPRIfHasAccess()
156+
if (!prInfo) {
157+
return
158+
}
145159

146-
if (prInfo.data.state.toLowerCase() !== "open") {
147-
await octokit.issues.createComment({ ...thisRepo, issue_number: issue.number, body: `Sorry @${sender}, this PR isn't open.` });
148-
return
149-
}
160+
const { octokit, thisRepo, issue, sender } = this;
161+
162+
// Don't try merge unmergable stuff
163+
if (!prInfo.data.mergeable) {
164+
await octokit.issues.createComment({ ...thisRepo, issue_number: issue.number, body: `Sorry @${sender}, this PR has merge conflicts. They'll need to be fixed before this can be merged.` });
165+
return
166+
}
167+
168+
// Don't merge red PRs
169+
const statusInfo = await octokit.repos.listCommitStatusesForRef({ ...thisRepo, ref: prInfo.data.head.sha })
170+
const failedStatus = statusInfo.data
171+
// Check only the most recent for a set of duplicated statuses
172+
.filter(
173+
(thing, index, self) =>
174+
index === self.findIndex((t) => t.target_url === thing.target_url)
175+
)
176+
.find(s => s.state !== "success")
177+
178+
if (failedStatus) {
179+
await octokit.issues.createComment({ ...thisRepo, issue_number: issue.number, body: `Sorry @${sender}, this PR could not be merged because it wasn't green. Blocked by [${failedStatus.context}](${failedStatus.target_url}): '${failedStatus.description}'.` });
180+
return
181+
}
150182

151-
// Don't merge red PRs
152-
const statusInfo = await octokit.repos.listCommitStatusesForRef({ ...thisRepo, ref: prInfo.data.head.sha })
153-
const failedStatus = statusInfo.data
154-
// Check only the most recent for a set of duplicated statuses
155-
.filter(
156-
(thing, index, self) =>
157-
index === self.findIndex((t) => t.target_url === thing.target_url)
158-
)
159-
.find(s => s.state !== "success")
160-
161-
if (failedStatus) {
162-
await octokit.issues.createComment({ ...thisRepo, issue_number: issue.number, body: `Sorry @${sender}, this PR could not be merged because it wasn't green. Blocked by [${failedStatus.context}](${failedStatus.target_url}): '${failedStatus.description}'.` });
163-
return
183+
core.info(`Creating comments and merging`)
184+
try {
185+
// @ts-ignore
186+
await octokit.pulls.merge({ ...thisRepo, pull_number: issue.number, merge_method: core.getInput('merge_method') || 'merge' });
187+
await octokit.issues.createComment({ ...thisRepo, issue_number: issue.number, body: `Merging because @${sender} is a code-owner of all the changes - thanks!` });
188+
} catch (error) {
189+
core.info(`Merging (or commenting) failed:`)
190+
core.error(error)
191+
core.setFailed("Failed to merge")
192+
193+
const linkToCI = `https://github.com/${thisRepo.owner}/${thisRepo.repo}/runs/${process.env.GITHUB_RUN_ID}?check_suite_focus=true`
194+
await octokit.issues.createComment({ ...thisRepo, issue_number: issue.number, body: `There was an issue merging, maybe try again ${sender}. <a href="${linkToCI}">Details</a>` });
195+
}
164196
}
165197

166-
core.info(`Creating comments and merging`)
167-
try {
168-
// @ts-ignore
169-
await octokit.pulls.merge({ ...thisRepo, pull_number: issue.number, merge_method: core.getInput('merge_method') || 'merge' });
170-
await octokit.issues.createComment({ ...thisRepo, issue_number: issue.number, body: `Merging because @${sender} is a code-owner of all the changes - thanks!` });
171-
} catch (error) {
172-
core.info(`Merging (or commenting) failed:`)
173-
core.error(error)
174-
core.setFailed("Failed to merge")
198+
async closeIfHasAccess() {
199+
const prInfo = await this.getTargetPRIfHasAccess()
200+
if (!prInfo) {
201+
return
202+
}
203+
204+
const { octokit, thisRepo, issue, sender } = this;
175205

176-
const linkToCI = `https://github.com/${thisRepo.owner}/${thisRepo.repo}/runs/${process.env.GITHUB_RUN_ID}?check_suite_focus=true`
177-
await octokit.issues.createComment({ ...thisRepo, issue_number: issue.number, body: `There was an issue merging, maybe try again ${sender}. <a href="${linkToCI}">Details</a>` });
206+
core.info(`Creating comments and closing`)
207+
await octokit.pulls.update({ ...thisRepo, pull_number: issue.number, state: "closed" });
208+
await octokit.issues.createComment({ ...thisRepo, issue_number: issue.number, body: `Closing because @${sender} is a code-owner of all the changes.` });
178209
}
179210
}
180211

0 commit comments

Comments
 (0)