Repository: pulumi/actions
Pull request #148 (2021-03-29 23:49:13)

Edit previous PR comment instead of posting new one
Resolves: https://github.com/pulumi/actions/issues/31 "Github Bot should edit previous comment instead of posting new one."


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7056f94..e1d3551 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,7 +2,8 @@
 
 ## HEAD (Unreleased)
 
-_(none)_
+- Edit previous PR comment instead of posting new one
+  [#128](https://github.com/pulumi/actions/pull/148)
 
 ---
 
diff --git a/README.md b/README.md
index 3bb5f2a..8e2ec0d 100644
--- a/README.md
+++ b/README.md
@@ -73,6 +73,9 @@ The action can be configured with the following arguments:
 - `expect-no-changes` - (optional) Return an error if any changes occur during
   this update
 
+- `edit-pr-comment` - (optional) Edit previous PR comment instead of posting new
+  one
+
 - `diff` - (optional) Display operation as a rich diff showing the overall
   change
 
diff --git a/package.json b/package.json
index 3ed3c35..c87e552 100644
--- a/package.json
+++ b/package.json
@@ -23,7 +23,7 @@
   "devDependencies": {
     "@types/faker": "^5.1.7",
     "@types/jest": "~26.0.22",
-    "@types/node": "~14.14.36",
+    "@types/node": "~14.14.35",
     "@typescript-eslint/eslint-plugin": "~4.19.0",
     "@typescript-eslint/parser": "~4.19.0",
     "@vercel/ncc": "^0.27.0",
diff --git a/src/config.ts b/src/config.ts
index 181fa1e..80f83e0 100644
--- a/src/config.ts
+++ b/src/config.ts
@@ -20,6 +20,7 @@ export const options = rt.Partial({
   replace: rt.Array(rt.String),
   target: rt.Array(rt.String),
   targetDependents: rt.Boolean,
+  editCommentOnPr: rt.Boolean,
 });
 
 export const config = rt
@@ -61,6 +62,7 @@ export async function makeConfig(): Promise<Config> {
       replace: parseArray(getInput('replace')),
       target: parseArray(getInput('target')),
       targetDependents: parseBoolean(getInput('target-dependents')),
+      editCommentOnPr: parseBoolean(getInput('edit-pr-comment')),
     },
   });
 }
diff --git a/src/libs/pr.ts b/src/libs/pr.ts
index 677db82..caa02ef 100644
--- a/src/libs/pr.ts
+++ b/src/libs/pr.ts
@@ -1,17 +1,35 @@
 import { context, getOctokit } from '@actions/github';
 import { invariant } from './utils';
 
-export async function addPullRequestMessage(
+
+export async function handlePullRequestMessage(
   body: string,
   githubToken: string,
+  editCommentOnPr?: boolean,
 ): Promise<void> {
   const { payload, repo } = context;
   invariant(payload.pull_request, 'Missing pull request event data.');
-
+  const text = `#### :tropical_drink: `
   const octokit = getOctokit(githubToken);
-  await octokit.issues.createComment({
+  const { data: comments} = await octokit.issues.listComments({
     ...repo,
-    issue_number: payload.pull_request.number,
-    body,
-  });
+    issue_number: payload.pull_request.number
+  })
+  const comment = comments.find(comment => comment.body.startsWith(text));
+
+  if (body && githubToken) {
+    if (comment && editCommentOnPr) {
+      await octokit.issues.updateComment({
+        ...repo,
+        comment_id: comment.id,
+        body,
+      });
+    } else {
+      await octokit.issues.createComment({
+        ...repo,
+        issue_number: payload.pull_request.number,
+        body,
+      });
+    }
+  }
 }
diff --git a/src/main.ts b/src/main.ts
index 81582cd..c3373c2 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -3,7 +3,7 @@ import * as core from '@actions/core';
 import { LocalProgramArgs, LocalWorkspace } from '@pulumi/pulumi/x/automation';
 import { Commands, makeConfig } from './config';
 import { environmentVariables } from './libs/envs';
-import { addPullRequestMessage } from './libs/pr';
+import { handlePullRequestMessage } from './libs/pr';
 import * as pulumiCli from './libs/pulumi-cli';
 import { invariant } from './libs/utils';
 
@@ -84,12 +84,13 @@ const main = async () => {
   if (config.commentOnPr) {
     core.debug(`Commenting on pull request`);
     invariant(config.githubToken, 'github-token is missing.');
-    addPullRequestMessage(
+    handlePullRequestMessage(
       `#### :tropical_drink: \`${config.command}\`
 \`\`\`
 ${output}
 \`\`\``,
       config.githubToken,
+      config.options.editCommentOnPr
     );
   }
 
diff --git a/yarn.lock b/yarn.lock
index 8bec9d9..b9041fd 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -830,10 +830,10 @@
   resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.1.tgz#459c65fa1867dafe6a8f322c4c51695663cc55e9"
   integrity sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==
 
-"@types/node@*", "@types/node@>= 8", "@types/node@>=12.12.47", "@types/node@~14.14.36":
-  version "14.14.36"
-  resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.36.tgz#5637905dbb15c30a33a3c65b9ef7c20e3c85ebad"
-  integrity sha512-kjivUwDJfIjngzbhooRnOLhGYz6oRFi+L+EpMjxroDYXwDw9lHrJJ43E+dJ6KAd3V3WxWAJ/qZE9XKYHhjPOFQ==
+"@types/node@*", "@types/node@>= 8", "@types/node@>=12.12.47", "@types/node@~14.14.35":
+  version "14.14.35"
+  resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.35.tgz#42c953a4e2b18ab931f72477e7012172f4ffa313"
+  integrity sha512-Lt+wj8NVPx0zUmUwumiVXapmaLUcAk3yPuHCFVXras9k5VT9TdhJqKqGVUQCD60OTMCl0qxJ57OiTL0Mic3Iag==
 
 "@types/node@^13.7.0":
   version "13.13.40"


Test patch:
diff --git a/src/__tests__/config.test.ts b/src/__tests__/config.test.ts
index 5d906d0..f15b4ac 100644
--- a/src/__tests__/config.test.ts
+++ b/src/__tests__/config.test.ts
@@ -41,6 +41,7 @@ describe('config.ts', () => {
         replace: undefined,
         target: undefined,
         targetDependents: undefined,
+        editCommentOnPr: undefined,
       },
     });
   });
@@ -89,6 +90,7 @@ describe('config.ts', () => {
         replace: undefined,
         target: undefined,
         targetDependents: undefined,
+        editCommentOnPr: undefined,
       },
     });
   });
diff --git a/src/libs/__tests__/pr.test.ts b/src/libs/__tests__/pr.test.ts
index edf38fe..97b926b 100644
--- a/src/libs/__tests__/pr.test.ts
+++ b/src/libs/__tests__/pr.test.ts
@@ -1,12 +1,16 @@
 import * as gh from '@actions/github';
-import { addPullRequestMessage } from '../pr';
+import { handlePullRequestMessage } from '../pr';
 
+const comments = [{id: 2, body: 'test',}];
+const resp = {data: comments};
 const createComment = jest.fn();
+const listComments = jest.fn(() => resp);
 jest.mock('@actions/github', () => ({
   context: {},
   getOctokit: jest.fn(() => ({
     issues: {
       createComment,
+      listComments,
     },
   })),
 }));
@@ -27,14 +31,16 @@ describe('pr.ts', () => {
 
     process.env.GITHUB_REPOSITORY = 'pulumi/actions';
 
-    await addPullRequestMessage('test', 'test');
+    await handlePullRequestMessage('test', 'test');
+    expect(listComments).toHaveBeenCalled();
     expect(createComment).toHaveBeenCalled();
   });
+
   it('should fail if no pull request data', async () => {
     process.env.GITHUB_REPOSITORY = 'pulumi/actions';
     // @ts-ignore
     gh.context = { payload: {} };
-    await expect(addPullRequestMessage('test', 'test')).rejects.toThrowError(
+    await expect(handlePullRequestMessage('test', 'test')).rejects.toThrowError(
       'Missing pull request event data',
     );
   });