Skip to content

Commit

Permalink
Add support for workflow_run events (#156)
Browse files Browse the repository at this point in the history
Resolves #155

This adds support for `workflow_run` triggered auth-merges. Because
[this event is similar to
`check_suite`](https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#workflow_run)
I was able to reuse the existing handle check logic.
  • Loading branch information
apexskier authored May 26, 2021
1 parent 4d2ac8c commit 1f4896c
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 62 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ Automerge can be configured to run for these events:
* `schedule`
* `status`
* `workflow_dispatch`
* `workflow_run`

For more information on when these occur, see the Github documentation on [events that trigger workflows](https://docs.github.com/en/actions/reference/events-that-trigger-workflows) and [their payloads](https://docs.github.com/en/developers/webhooks-and-events/webhook-events-and-payloads).

Expand Down
66 changes: 35 additions & 31 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ async function executeGitHubAction(context, eventName, eventData) {
await handleStatusUpdate(context, eventName, eventData);
} else if (["pull_request", "pull_request_target"].includes(eventName)) {
await handlePullRequestUpdate(context, eventName, eventData);
} else if (["check_suite", "check_run"].includes(eventName)) {
await handleCheckUpdate(context, eventName, eventData);
} else if (["check_suite", "check_run", "workflow_run"].includes(eventName)) {
await handleCheckOrWorkflowUpdate(context, eventName, eventData);
} else if (["pull_request_review"].includes(eventName)) {
await handlePullRequestReviewUpdate(context, eventName, eventData);
} else if (["schedule", "repository_dispatch"].includes(eventName)) {
Expand Down Expand Up @@ -136,39 +136,43 @@ async function handleArbitraryPullRequestUpdate(context, eventData) {
}
}

async function handleCheckUpdate(context, eventName, event) {
async function handleCheckOrWorkflowUpdate(context, eventName, event) {
const { action } = event;
const eventType = eventName === "workflow_run" ? "workflow" : "status check";
if (action !== "completed") {
logger.info("A status check is not yet complete:", eventName);
} else {
const payload =
eventName === "check_suite" ? event.check_suite : event.check_run;
if (payload.conclusion === "success") {
logger.info("Status check completed successfully");
const checkPullRequest = payload.pull_requests[0];
if (checkPullRequest != null) {
const { octokit } = context;
const { data: pullRequest } = await octokit.request(
checkPullRequest.url
);
logger.trace("PR:", pullRequest);
logger.info(`A ${eventType} is not yet complete:`, eventName);
return;
}

await update(context, pullRequest);
await merge(context, pullRequest);
} else {
const branchName = payload.head_branch;
if (branchName != null) {
await checkPullRequestsForBranches(context, event, branchName);
} else {
await checkPullRequestsForHeadSha(
context,
event.repository,
payload.head_sha
);
}
}
const payload = event[eventName];
if (!payload) {
throw new Error(`failed to find payload for event type: ${eventName}`);
}
if (payload.conclusion !== "success") {
logger.info(`A ${eventType} completed unsuccessfully:`, eventName);
return;
}

logger.info(`${eventType} completed successfully`);

const eventPullRequest = payload.pull_requests[0];
if (eventPullRequest != null) {
const { octokit } = context;
const { data: pullRequest } = await octokit.request(eventPullRequest.url);
logger.trace("PR:", pullRequest);

await update(context, pullRequest);
await merge(context, pullRequest);
} else {
const branchName = payload.head_branch;
if (branchName != null) {
await checkPullRequestsForBranches(context, event, branchName);
} else {
logger.info("A status check completed unsuccessfully:", eventName);
await checkPullRequestsForHeadSha(
context,
event.repository,
payload.head_sha
);
}
}
}
Expand Down
66 changes: 35 additions & 31 deletions lib/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ async function executeGitHubAction(context, eventName, eventData) {
await handleStatusUpdate(context, eventName, eventData);
} else if (["pull_request", "pull_request_target"].includes(eventName)) {
await handlePullRequestUpdate(context, eventName, eventData);
} else if (["check_suite", "check_run"].includes(eventName)) {
await handleCheckUpdate(context, eventName, eventData);
} else if (["check_suite", "check_run", "workflow_run"].includes(eventName)) {
await handleCheckOrWorkflowUpdate(context, eventName, eventData);
} else if (["pull_request_review"].includes(eventName)) {
await handlePullRequestReviewUpdate(context, eventName, eventData);
} else if (["schedule", "repository_dispatch"].includes(eventName)) {
Expand Down Expand Up @@ -129,39 +129,43 @@ async function handleArbitraryPullRequestUpdate(context, eventData) {
}
}

async function handleCheckUpdate(context, eventName, event) {
async function handleCheckOrWorkflowUpdate(context, eventName, event) {
const { action } = event;
const eventType = eventName === "workflow_run" ? "workflow" : "status check";
if (action !== "completed") {
logger.info("A status check is not yet complete:", eventName);
logger.info(`A ${eventType} is not yet complete:`, eventName);
return;
}

const payload = event[eventName];
if (!payload) {
throw new Error(`failed to find payload for event type: ${eventName}`);
}
if (payload.conclusion !== "success") {
logger.info(`A ${eventType} completed unsuccessfully:`, eventName);
return;
}

logger.info(`${eventType} completed successfully`);

const eventPullRequest = payload.pull_requests[0];
if (eventPullRequest != null) {
const { octokit } = context;
const { data: pullRequest } = await octokit.request(eventPullRequest.url);
logger.trace("PR:", pullRequest);

await update(context, pullRequest);
await merge(context, pullRequest);
} else {
const payload =
eventName === "check_suite" ? event.check_suite : event.check_run;
if (payload.conclusion === "success") {
logger.info("Status check completed successfully");
const checkPullRequest = payload.pull_requests[0];
if (checkPullRequest != null) {
const { octokit } = context;
const { data: pullRequest } = await octokit.request(
checkPullRequest.url
);
logger.trace("PR:", pullRequest);

await update(context, pullRequest);
await merge(context, pullRequest);
} else {
const branchName = payload.head_branch;
if (branchName != null) {
await checkPullRequestsForBranches(context, event, branchName);
} else {
await checkPullRequestsForHeadSha(
context,
event.repository,
payload.head_sha
);
}
}
const branchName = payload.head_branch;
if (branchName != null) {
await checkPullRequestsForBranches(context, event, branchName);
} else {
logger.info("A status check completed unsuccessfully:", eventName);
await checkPullRequestsForHeadSha(
context,
event.repository,
payload.head_sha
);
}
}
}
Expand Down

0 comments on commit 1f4896c

Please sign in to comment.