Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add automerge fail label #70

Merged
merged 1 commit into from
Jun 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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