Skip to content

Commit

Permalink
feat: add automerge fail label (gr2m#70)
Browse files Browse the repository at this point in the history
  • Loading branch information
ruisaraiva19 authored Jun 22, 2022
1 parent 5035d7c commit b0929e3
Show file tree
Hide file tree
Showing 9 changed files with 256 additions and 106 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ jobs:
# Require all pull request statuses to be successful before
# merging. Default is `false`.
require_statuses_success: 'true'
# Label to apply to the pull request if the merge fails. Default is
# `automerge-fail`.
automerge_fail_label: 'merge-schedule-failed'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
```
Expand Down
6 changes: 6 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,9 @@ inputs:
merging. Default is `false`.
required: false
default: 'false'
automerge_fail_label:
description: |-
Label to apply to the pull request if the merge fails. Default is
`automerge-fail`.
required: false
default: 'automerge-fail'
21 changes: 16 additions & 5 deletions lib/comment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,14 @@ type Octokit = InstanceType<typeof GitHub>;

const commentHeader = "**Merge Schedule**";
const commentFooter = "<!-- Merge Schedule Pull Request Comment -->";
const commentFailFooter = "<!-- Merge Schedule Pull Request Comment Fail -->";

type CommentVariant = "default" | "fail";

export async function getPreviousComment(
octokit: Octokit,
pullRequestNumber: number
pullRequestNumber: number,
variant: CommentVariant = "default"
) {
const prComments = await octokit.paginate(
octokit.rest.issues.listComments,
Expand All @@ -18,7 +22,9 @@ export async function getPreviousComment(
},
(response) => {
return response.data.filter((comment) =>
comment.body?.includes(commentFooter)
comment.body?.includes(
variant === "fail" ? commentFailFooter : commentFooter
)
);
}
);
Expand All @@ -35,13 +41,18 @@ const statePrefix: Record<State, string> = {
pending: ":hourglass:",
};

export function generateBody(body: string, state: State) {
export function generateBody(
body: string,
state: State,
variant: CommentVariant = "default"
) {
let newBody = body;
if (!body.startsWith(commentHeader)) {
newBody = `${commentHeader}\n${newBody}`;
}
if (!body.endsWith(commentFooter)) {
newBody = `${newBody}\n${commentFooter}`;
const footer = variant === "fail" ? commentFailFooter : commentFooter;
if (!body.endsWith(footer)) {
newBody = `${newBody}\n${footer}`;
}
return `${statePrefix[state]} ${newBody}`;
}
Expand Down
1 change: 1 addition & 0 deletions lib/environment.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ declare global {
INPUT_MERGE_METHOD: string;
INPUT_TIME_ZONE: string;
INPUT_REQUIRE_STATUSES_SUCCESS: string;
INPUT_AUTOMERGE_FAIL_LABEL: string;
}
}
}
Expand Down
10 changes: 5 additions & 5 deletions lib/handle-pull-request.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ describe("handlePullRequest", () => {
],
[`Schedule date found: "bad-date"\n`],
[
`Comment created: https://github.com/gr2m/merge-schedule-action/issues/2#issuecomment-2\n`,
`Comment created: https://github.com/gr2m/merge-schedule-action/issues/2#issuecomment-22\n`,
],
]);
expect(createComment.mock.calls).toHaveLength(1);
Expand All @@ -125,7 +125,7 @@ describe("handlePullRequest", () => {
],
[`Schedule date found: "2022-06-08"\n`],
[
`Comment created: https://github.com/gr2m/merge-schedule-action/issues/2#issuecomment-2\n`,
`Comment created: https://github.com/gr2m/merge-schedule-action/issues/2#issuecomment-22\n`,
],
]);
expect(createComment.mock.calls).toHaveLength(1);
Expand Down Expand Up @@ -153,7 +153,7 @@ describe("handlePullRequest", () => {
],
[`Schedule date found: "2022-06-08"\n`],
[
`Comment created: https://github.com/gr2m/merge-schedule-action/issues/2#issuecomment-2\n`,
`Comment created: https://github.com/gr2m/merge-schedule-action/issues/2#issuecomment-22\n`,
],
]);
expect(createComment.mock.calls).toHaveLength(1);
Expand All @@ -180,7 +180,7 @@ describe("handlePullRequest", () => {
],
[`Schedule date found: "2022-06-12"\n`],
[
`Comment created: https://github.com/gr2m/merge-schedule-action/issues/2#issuecomment-2\n`,
`Comment created: https://github.com/gr2m/merge-schedule-action/issues/2#issuecomment-22\n`,
],
]);
expect(createComment.mock.calls).toHaveLength(1);
Expand Down Expand Up @@ -208,7 +208,7 @@ describe("handlePullRequest", () => {
],
[`Schedule date found: "2022-06-12"\n`],
[
`Comment updated: https://github.com/gr2m/merge-schedule-action/issues/2#issuecomment-1\n`,
`Comment updated: https://github.com/gr2m/merge-schedule-action/issues/3#issuecomment-31\n`,
],
]);
expect(updateComment.mock.calls).toHaveLength(1);
Expand Down
50 changes: 37 additions & 13 deletions lib/handle-schedule.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,19 +33,24 @@ describe("handleSchedule", () => {

expect(mockStdout.mock.calls).toEqual([
[`Loading open pull requests\n`],
[`4 scheduled pull requests found\n`],
[`3 due pull requests found\n`],
[`5 scheduled pull requests found\n`],
[`4 due pull requests found\n`],
[`https://github.com/gr2m/merge-schedule-action/pull/2 merged\n`],
[
`Comment created: https://github.com/gr2m/merge-schedule-action/issues/2#issuecomment-2\n`,
`Comment created: https://github.com/gr2m/merge-schedule-action/issues/2#issuecomment-22\n`,
],
[`https://github.com/gr2m/merge-schedule-action/pull/3 merged\n`],
[
`Comment updated: https://github.com/gr2m/merge-schedule-action/issues/2#issuecomment-1\n`,
`Comment updated: https://github.com/gr2m/merge-schedule-action/issues/3#issuecomment-31\n`,
],
[
`Comment created: https://github.com/gr2m/merge-schedule-action/issues/13#issuecomment-2\n`,
`Comment created: https://github.com/gr2m/merge-schedule-action/issues/13#issuecomment-132\n`,
],
[`Label added: "automerge-fail"\n`],
[
`Comment updated: https://github.com/gr2m/merge-schedule-action/issues/6#issuecomment-61\n`,
],
[`Label added: "automerge-fail"\n`],
]);
expect(createComment.mock.calls).toHaveLength(2);
expect(createComment.mock.calls[0][2]).toMatchInlineSnapshot(`
Expand All @@ -56,14 +61,21 @@ describe("handleSchedule", () => {
expect(createComment.mock.calls[1][2]).toMatchInlineSnapshot(`
":x: **Merge Schedule**
Scheduled merge failed: Pull Request is not mergeable
<!-- Merge Schedule Pull Request Comment -->"
In order to let the automerge-automation try again, the label \\"automerge-fail\\" should be removed.
<!-- Merge Schedule Pull Request Comment Fail -->"
`);
expect(updateComment.mock.calls).toHaveLength(1);
expect(updateComment.mock.calls).toHaveLength(2);
expect(updateComment.mock.calls[0][2]).toMatchInlineSnapshot(`
":white_check_mark: **Merge Schedule**
Scheduled on 2022-06-09 (UTC) successfully merged
<!-- Merge Schedule Pull Request Comment -->"
`);
expect(updateComment.mock.calls[1][2]).toMatchInlineSnapshot(`
":x: **Merge Schedule**
Scheduled merge failed: Pull Request is not mergeable
In order to let the automerge-automation try again, the label \\"automerge-fail\\" should be removed.
<!-- Merge Schedule Pull Request Comment Fail -->"
`);
});

test("due pull requests with require_statuses_success = true", async () => {
Expand All @@ -76,18 +88,23 @@ describe("handleSchedule", () => {

expect(mockStdout.mock.calls).toEqual([
[`Loading open pull requests\n`],
[`4 scheduled pull requests found\n`],
[`3 due pull requests found\n`],
[`5 scheduled pull requests found\n`],
[`4 due pull requests found\n`],
[`https://github.com/gr2m/merge-schedule-action/pull/2 merged\n`],
[
`Comment created: https://github.com/gr2m/merge-schedule-action/issues/2#issuecomment-2\n`,
`Comment created: https://github.com/gr2m/merge-schedule-action/issues/2#issuecomment-22\n`,
],
[
`https://github.com/gr2m/merge-schedule-action/pull/3 is not ready to be merged yet because all checks are not completed or statuses are not success\n`,
],
[
`Comment created: https://github.com/gr2m/merge-schedule-action/issues/13#issuecomment-2\n`,
`Comment created: https://github.com/gr2m/merge-schedule-action/issues/13#issuecomment-132\n`,
],
[`Label added: "automerge-fail"\n`],
[
`Comment updated: https://github.com/gr2m/merge-schedule-action/issues/6#issuecomment-61\n`,
],
[`Label added: "automerge-fail"\n`],
]);
expect(createComment.mock.calls).toHaveLength(2);
expect(createComment.mock.calls[0][2]).toMatchInlineSnapshot(`
Expand All @@ -98,8 +115,15 @@ describe("handleSchedule", () => {
expect(createComment.mock.calls[1][2]).toMatchInlineSnapshot(`
":x: **Merge Schedule**
Scheduled merge failed: Pull Request is not mergeable
<!-- Merge Schedule Pull Request Comment -->"
In order to let the automerge-automation try again, the label \\"automerge-fail\\" should be removed.
<!-- Merge Schedule Pull Request Comment Fail -->"
`);
expect(updateComment.mock.calls).toHaveLength(1);
expect(updateComment.mock.calls[0][2]).toMatchInlineSnapshot(`
":x: **Merge Schedule**
Scheduled merge failed: Pull Request is not mergeable
In order to let the automerge-automation try again, the label \\"automerge-fail\\" should be removed.
<!-- Merge Schedule Pull Request Comment Fail -->"
`);
expect(updateComment.mock.calls).toHaveLength(0);
});
});
40 changes: 34 additions & 6 deletions lib/handle-schedule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export default async function handleSchedule(): Promise<void> {
const mergeMethod = process.env.INPUT_MERGE_METHOD;
const requireStatusesSuccess =
process.env.INPUT_REQUIRE_STATUSES_SUCCESS === "true";
const automergeFailLabel = process.env.INPUT_AUTOMERGE_FAIL_LABEL;
if (!isValidMergeMethod(mergeMethod)) {
core.setFailed(`merge_method "${mergeMethod}" is invalid`);
return;
Expand All @@ -46,6 +47,9 @@ export default async function handleSchedule(): Promise<void> {
return response.data
.filter((pullRequest) => !isFork(pullRequest as SimplePullRequest))
.filter((pullRequest) => hasScheduleCommand(pullRequest.body))
.filter((pullRequest) =>
pullRequest.labels.every((label) => label.name !== automergeFailLabel)
)
.map((pullRequest) => {
return {
number: pullRequest.number,
Expand Down Expand Up @@ -95,15 +99,39 @@ export default async function handleSchedule(): Promise<void> {
});
core.info(`${pullRequest.html_url} merged`);
} catch (error) {
const { data } = await createComment(
const previousComment = await getPreviousComment(
octokit,
pullRequest.number,
generateBody(
`Scheduled merge failed: ${(error as Error).message}`,
"error"
)
"fail"
);
core.info(`Comment created: ${data.html_url}`);
const commentBody = generateBody(
`Scheduled merge failed: ${
(error as Error).message
}\nIn order to let the automerge-automation try again, the label "${automergeFailLabel}" should be removed.`,
"error",
"fail"
);
if (previousComment) {
const { data } = await updateComment(
octokit,
previousComment.id,
commentBody
);
core.info(`Comment updated: ${data.html_url}`);
} else {
const { data } = await createComment(
octokit,
pullRequest.number,
commentBody
);
core.info(`Comment created: ${data.html_url}`);
}
await octokit.rest.issues.addLabels({
...github.context.repo,
issue_number: pullRequest.number,
labels: [automergeFailLabel],
});
core.info(`Label added: "${automergeFailLabel}"`);
continue;
}

Expand Down
Loading

0 comments on commit b0929e3

Please sign in to comment.