From bb381256784cb1bc10e1c401176754dfe89ea720 Mon Sep 17 00:00:00 2001 From: Christopher Viel Date: Sat, 18 Jun 2022 08:25:21 -0400 Subject: [PATCH] Add an option to update comments (#17) --- __tests__/action_single.test.js | 99 +++++++++++++++++++++++---------- action.yml | 4 ++ src/action.js | 38 +++++++++++-- src/render.js | 1 + 4 files changed, 107 insertions(+), 35 deletions(-) diff --git a/__tests__/action_single.test.js b/__tests__/action_single.test.js index e5dee26..550f4d2 100644 --- a/__tests__/action_single.test.js +++ b/__tests__/action_single.test.js @@ -6,8 +6,47 @@ jest.mock("@actions/core"); jest.mock("@actions/github"); describe("Single report", function () { - const comment = jest.fn(); - const output = jest.fn(); + let createComment; + let listComments; + let updateComment; + let output; + + function getInput(key) { + switch (key) { + case "paths": + return "./__tests__/__fixtures__/report.xml"; + case "min-coverage-overall": + return 45; + case `min-coverage-changed-files`: + return 60; + } + } + + beforeEach(() => { + createComment = jest.fn(); + listComments = jest.fn(); + updateComment = jest.fn(); + output = jest.fn(); + + core.getInput = jest.fn(getInput); + github.getOctokit = jest.fn(() => { + return { + repos: { + compareCommits: jest.fn(() => { + return compareCommitsResponse; + }), + }, + issues: { + createComment: createComment, + listComments: listComments, + updateComment: updateComment, + }, + }; + }); + core.setFailed = jest.fn((c) => { + fail(c); + }); + }) const compareCommitsResponse = { data: { @@ -26,32 +65,6 @@ describe("Single report", function () { }, }; - core.getInput = jest.fn((c) => { - switch (c) { - case "paths": - return "./__tests__/__fixtures__/report.xml"; - case "min-coverage-overall": - return 45; - case `min-coverage-changed-files`: - return 60; - } - }); - github.getOctokit = jest.fn(() => { - return { - repos: { - compareCommits: jest.fn(() => { - return compareCommitsResponse; - }), - }, - issues: { - createComment: comment, - }, - }; - }); - core.setFailed = jest.fn((c) => { - fail(c); - }); - describe("Pull Request event", function () { const context = { eventName: "pull_request", @@ -75,7 +88,7 @@ describe("Single report", function () { await action.action(); - expect(comment.mock.calls[0][0].body) + expect(createComment.mock.calls[0][0].body) .toEqual(`|File|Coverage [63.64%]|:green_apple:| |:-|:-:|:-:| |[StringOp.java](https://github.com/thsaravana/jacoco-playground/blob/77b14eb61efcd211ee93a7d8bac80cf292d207cc/src/main/java/com/madrapps/jacoco/operation/StringOp.java)|100%|:green_apple:| @@ -85,6 +98,34 @@ describe("Single report", function () { |:-|:-:|:-:|`); }); + it("updates a previous comment", async () => { + github.context = context; + + const title = 'JaCoCo Report' + core.getInput = jest.fn((c) => { + switch (c) { + case "title": + return title; + case "update-comment": + return "true"; + default: + return getInput(c) + } + }); + + listComments.mockReturnValue({ + data: [ + {id: 1, body: "some comment"}, + {id: 2, body: `### ${title}\n to update`}, + ] + }) + + await action.action(); + + expect(updateComment.mock.calls[0][0].comment_id).toEqual(2); + expect(createComment).toHaveBeenCalledTimes(0); + }); + it("set overall coverage output", async () => { github.context = context; core.setOutput = output; diff --git a/action.yml b/action.yml index 2e73b49..c7db929 100644 --- a/action.yml +++ b/action.yml @@ -18,6 +18,10 @@ inputs: title: description: "Optional title for the Pull Request comment" required: false + update-comment: + description: "Update the coverage report comment instead of creating new ones. Requires title to works properly." + required: false + default: "false" debug-mode: description: "Run the action in debug mode and get debug logs printed in console" required: false diff --git a/src/action.js b/src/action.js index 4fa63f9..5a38d96 100644 --- a/src/action.js +++ b/src/action.js @@ -17,6 +17,7 @@ async function action() { core.getInput("min-coverage-changed-files") ); const title = core.getInput("title"); + const updateComment = parseBooleans(core.getInput("update-comment")); const debugMode = parseBooleans(core.getInput("debug-mode")); const event = github.context.eventName; core.info(`Event is ${event}`); @@ -71,6 +72,8 @@ async function action() { if (prNumber != null) { await addComment( prNumber, + updateComment, + render.getTitle(title), render.getPRComment( overallCoverage.project, filesCoverage, @@ -118,12 +121,35 @@ async function getChangedFiles(base, head, client) { return changedFiles; } -async function addComment(prNumber, comment, client) { - await client.issues.createComment({ - issue_number: prNumber, - body: comment, - ...github.context.repo, - }); +async function addComment(prNumber, update, title, body, client) { + let commentUpdated = false; + + if (update && title) { + const comments = await client.issues.listComments({ + issue_number: prNumber, + ...github.context.repo, + }); + const comment = comments.data.find((comment) => + comment.body.startsWith(title), + ); + + if (comment) { + await client.issues.updateComment({ + comment_id: comment.id, + body: body, + ...github.context.repo, + }); + commentUpdated = true; + } + } + + if (!commentUpdated) { + await client.issues.createComment({ + issue_number: prNumber, + body: body, + ...github.context.repo, + }); + } } module.exports = { diff --git a/src/render.js b/src/render.js index 6434e4a..af7c021 100644 --- a/src/render.js +++ b/src/render.js @@ -75,4 +75,5 @@ function formatCoverage(coverage) { module.exports = { getPRComment, + getTitle, };