Skip to content

Commit

Permalink
feat(gcf-utils): add addOrUpdateIssueComment (#1118)
Browse files Browse the repository at this point in the history
fixes #1114
  • Loading branch information
Takashi Matsuo committed Nov 13, 2020
1 parent 7a9ac98 commit 448243f
Show file tree
Hide file tree
Showing 6 changed files with 361 additions and 0 deletions.
7 changes: 7 additions & 0 deletions packages/gcf-utils/__snapshots__/gcf-utils.js
@@ -0,0 +1,7 @@
exports['gcf-utils addOrUpdateIssueComment creates a comment 1'] = {
body: '<!-- probot comment [11359653]-->\ntest comment',
};

exports['gcf-utils addOrUpdateIssueComment updates a comment 1'] = {
body: '<!-- probot comment [11359653]-->\ntest comment',
};
1 change: 1 addition & 0 deletions packages/gcf-utils/package.json
Expand Up @@ -61,6 +61,7 @@
"mocha": "^8.0.0",
"nock": "^13.0.0",
"sinon": "^9.0.0",
"snap-shot-it": "^7.8.0",
"sonic-boom": "1.3.0",
"stream-mock": "^2.0.5",
"typescript": "^3.8.3"
Expand Down
39 changes: 39 additions & 0 deletions packages/gcf-utils/src/gcf-utils.ts
Expand Up @@ -18,6 +18,7 @@ import {
ApplicationFunction,
Options,
Application,
Context,
} from 'probot';

import getStream from 'get-stream';
Expand Down Expand Up @@ -94,6 +95,44 @@ export enum TriggerType {
UNKNOWN = 'Unknown',
}

export const addOrUpdateIssueComment = async (
context: Context,
owner: string,
repo: string,
issueNumber: number,
commentBody: string
) => {
const installationId = context.payload.installation.id;
const commentMark = `<!-- probot comment [${installationId}]-->`;
const listCommentsResponse = await context.github.issues.listComments({
owner: owner,
repo: repo,
per_page: 50, // I think 50 is enough, but I may be wrong.
issue_number: issueNumber,
});
let found = false;
for (const comment of listCommentsResponse.data) {
if (comment.body.includes(commentMark)) {
// We found the existing comment, so updating it
await context.github.issues.updateComment({
owner: owner,
repo: repo,
comment_id: comment.id,
body: `${commentMark}\n${commentBody}`,
});
found = true;
}
}
if (!found) {
await context.github.issues.createComment({
owner: owner,
repo: repo,
issue_number: issueNumber,
body: `${commentMark}\n${commentBody}`,
});
}
};

export class GCFBootstrapper {
probot?: Probot;

Expand Down
177 changes: 177 additions & 0 deletions packages/gcf-utils/test/fixtures/issue_event.json
@@ -0,0 +1,177 @@
{
"action": "opened",
"issue": {
"url": "https://api.github.com/repos/tmatsuo/python-docs-samples/issues/10",
"repository_url": "https://api.github.com/repos/tmatsuo/python-docs-samples",
"labels_url": "https://api.github.com/repos/tmatsuo/python-docs-samples/issues/10/labels{/name}",
"comments_url": "https://api.github.com/repos/tmatsuo/python-docs-samples/issues/10/comments",
"events_url": "https://api.github.com/repos/tmatsuo/python-docs-samples/issues/10/events",
"html_url": "https://github.com/tmatsuo/python-docs-samples/issues/10",
"id": 683701062,
"node_id": "MDU6SXNzdWU2ODM3MDEwNjI=",
"number": 10,
"title": "chore: snippet-bot full scan",
"user": {
"login": "tmatsuo",
"id": 41815,
"node_id": "MDQ6VXNlcjQxODE1",
"avatar_url": "https://avatars2.githubusercontent.com/u/41815?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/tmatsuo",
"html_url": "https://github.com/tmatsuo",
"followers_url": "https://api.github.com/users/tmatsuo/followers",
"following_url": "https://api.github.com/users/tmatsuo/following{/other_user}",
"gists_url": "https://api.github.com/users/tmatsuo/gists{/gist_id}",
"starred_url": "https://api.github.com/users/tmatsuo/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/tmatsuo/subscriptions",
"organizations_url": "https://api.github.com/users/tmatsuo/orgs",
"repos_url": "https://api.github.com/users/tmatsuo/repos",
"events_url": "https://api.github.com/users/tmatsuo/events{/privacy}",
"received_events_url": "https://api.github.com/users/tmatsuo/received_events",
"type": "User",
"site_admin": false
},
"labels": [

],
"state": "open",
"locked": false,
"assignee": null,
"assignees": [

],
"milestone": null,
"comments": 0,
"created_at": "2020-08-21T17:16:43Z",
"updated_at": "2020-08-21T17:16:43Z",
"closed_at": null,
"author_association": "OWNER",
"active_lock_reason": null,
"body": "<!-- probot comment [11359653]-->",
"performed_via_github_app": null
},
"repository": {
"id": 63117616,
"node_id": "MDEwOlJlcG9zaXRvcnk2MzExNzYxNg==",
"name": "python-docs-samples",
"full_name": "tmatsuo/python-docs-samples",
"private": false,
"owner": {
"login": "tmatsuo",
"id": 41815,
"node_id": "MDQ6VXNlcjQxODE1",
"avatar_url": "https://avatars2.githubusercontent.com/u/41815?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/tmatsuo",
"html_url": "https://github.com/tmatsuo",
"followers_url": "https://api.github.com/users/tmatsuo/followers",
"following_url": "https://api.github.com/users/tmatsuo/following{/other_user}",
"gists_url": "https://api.github.com/users/tmatsuo/gists{/gist_id}",
"starred_url": "https://api.github.com/users/tmatsuo/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/tmatsuo/subscriptions",
"organizations_url": "https://api.github.com/users/tmatsuo/orgs",
"repos_url": "https://api.github.com/users/tmatsuo/repos",
"events_url": "https://api.github.com/users/tmatsuo/events{/privacy}",
"received_events_url": "https://api.github.com/users/tmatsuo/received_events",
"type": "User",
"site_admin": false
},
"html_url": "https://github.com/tmatsuo/python-docs-samples",
"description": "Code samples used on cloud.google.com",
"fork": true,
"url": "https://api.github.com/repos/tmatsuo/python-docs-samples",
"forks_url": "https://api.github.com/repos/tmatsuo/python-docs-samples/forks",
"keys_url": "https://api.github.com/repos/tmatsuo/python-docs-samples/keys{/key_id}",
"collaborators_url": "https://api.github.com/repos/tmatsuo/python-docs-samples/collaborators{/collaborator}",
"teams_url": "https://api.github.com/repos/tmatsuo/python-docs-samples/teams",
"hooks_url": "https://api.github.com/repos/tmatsuo/python-docs-samples/hooks",
"issue_events_url": "https://api.github.com/repos/tmatsuo/python-docs-samples/issues/events{/number}",
"events_url": "https://api.github.com/repos/tmatsuo/python-docs-samples/events",
"assignees_url": "https://api.github.com/repos/tmatsuo/python-docs-samples/assignees{/user}",
"branches_url": "https://api.github.com/repos/tmatsuo/python-docs-samples/branches{/branch}",
"tags_url": "https://api.github.com/repos/tmatsuo/python-docs-samples/tags",
"blobs_url": "https://api.github.com/repos/tmatsuo/python-docs-samples/git/blobs{/sha}",
"git_tags_url": "https://api.github.com/repos/tmatsuo/python-docs-samples/git/tags{/sha}",
"git_refs_url": "https://api.github.com/repos/tmatsuo/python-docs-samples/git/refs{/sha}",
"trees_url": "https://api.github.com/repos/tmatsuo/python-docs-samples/git/trees{/sha}",
"statuses_url": "https://api.github.com/repos/tmatsuo/python-docs-samples/statuses/{sha}",
"languages_url": "https://api.github.com/repos/tmatsuo/python-docs-samples/languages",
"stargazers_url": "https://api.github.com/repos/tmatsuo/python-docs-samples/stargazers",
"contributors_url": "https://api.github.com/repos/tmatsuo/python-docs-samples/contributors",
"subscribers_url": "https://api.github.com/repos/tmatsuo/python-docs-samples/subscribers",
"subscription_url": "https://api.github.com/repos/tmatsuo/python-docs-samples/subscription",
"commits_url": "https://api.github.com/repos/tmatsuo/python-docs-samples/commits{/sha}",
"git_commits_url": "https://api.github.com/repos/tmatsuo/python-docs-samples/git/commits{/sha}",
"comments_url": "https://api.github.com/repos/tmatsuo/python-docs-samples/comments{/number}",
"issue_comment_url": "https://api.github.com/repos/tmatsuo/python-docs-samples/issues/comments{/number}",
"contents_url": "https://api.github.com/repos/tmatsuo/python-docs-samples/contents/{+path}",
"compare_url": "https://api.github.com/repos/tmatsuo/python-docs-samples/compare/{base}...{head}",
"merges_url": "https://api.github.com/repos/tmatsuo/python-docs-samples/merges",
"archive_url": "https://api.github.com/repos/tmatsuo/python-docs-samples/{archive_format}{/ref}",
"downloads_url": "https://api.github.com/repos/tmatsuo/python-docs-samples/downloads",
"issues_url": "https://api.github.com/repos/tmatsuo/python-docs-samples/issues{/number}",
"pulls_url": "https://api.github.com/repos/tmatsuo/python-docs-samples/pulls{/number}",
"milestones_url": "https://api.github.com/repos/tmatsuo/python-docs-samples/milestones{/number}",
"notifications_url": "https://api.github.com/repos/tmatsuo/python-docs-samples/notifications{?since,all,participating}",
"labels_url": "https://api.github.com/repos/tmatsuo/python-docs-samples/labels{/name}",
"releases_url": "https://api.github.com/repos/tmatsuo/python-docs-samples/releases{/id}",
"deployments_url": "https://api.github.com/repos/tmatsuo/python-docs-samples/deployments",
"created_at": "2016-07-12T02:10:56Z",
"updated_at": "2020-08-20T21:42:10Z",
"pushed_at": "2020-08-21T16:42:49Z",
"git_url": "git://github.com/tmatsuo/python-docs-samples.git",
"ssh_url": "git@github.com:tmatsuo/python-docs-samples.git",
"clone_url": "https://github.com/tmatsuo/python-docs-samples.git",
"svn_url": "https://github.com/tmatsuo/python-docs-samples",
"homepage": "",
"size": 48198,
"stargazers_count": 0,
"watchers_count": 0,
"language": "Python",
"has_issues": true,
"has_projects": true,
"has_downloads": true,
"has_wiki": true,
"has_pages": false,
"forks_count": 0,
"mirror_url": null,
"archived": false,
"disabled": false,
"open_issues_count": 4,
"license": {
"key": "apache-2.0",
"name": "Apache License 2.0",
"spdx_id": "Apache-2.0",
"url": "https://api.github.com/licenses/apache-2.0",
"node_id": "MDc6TGljZW5zZTI="
},
"forks": 0,
"open_issues": 4,
"watchers": 0,
"default_branch": "master"
},
"sender": {
"login": "tmatsuo",
"id": 41815,
"node_id": "MDQ6VXNlcjQxODE1",
"avatar_url": "https://avatars2.githubusercontent.com/u/41815?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/tmatsuo",
"html_url": "https://github.com/tmatsuo",
"followers_url": "https://api.github.com/users/tmatsuo/followers",
"following_url": "https://api.github.com/users/tmatsuo/following{/other_user}",
"gists_url": "https://api.github.com/users/tmatsuo/gists{/gist_id}",
"starred_url": "https://api.github.com/users/tmatsuo/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/tmatsuo/subscriptions",
"organizations_url": "https://api.github.com/users/tmatsuo/orgs",
"repos_url": "https://api.github.com/users/tmatsuo/repos",
"events_url": "https://api.github.com/users/tmatsuo/events{/privacy}",
"received_events_url": "https://api.github.com/users/tmatsuo/received_events",
"type": "User",
"site_admin": false
},
"installation": {
"id": 11359653,
"node_id": "MDIzOkludGVncmF0aW9uSW5zdGFsbGF0aW9uMTEzNTk2NTM="
}
}
31 changes: 31 additions & 0 deletions packages/gcf-utils/test/fixtures/list_issue_comments.json
@@ -0,0 +1,31 @@
[
{
"id": 1,
"node_id": "MDEyOklzc3VlQ29tbWVudDE=",
"url": "https://api.github.com/repos/octocat/Hello-World/issues/comments/1",
"html_url": "https://github.com/octocat/Hello-World/issues/1347#issuecomment-1",
"body": "<!-- probot comment [11359653]-->\ntest comment",
"user": {
"login": "octocat",
"id": 1,
"node_id": "MDQ6VXNlcjE=",
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
"gravatar_id": "",
"url": "https://api.github.com/users/octocat",
"html_url": "https://github.com/octocat",
"followers_url": "https://api.github.com/users/octocat/followers",
"following_url": "https://api.github.com/users/octocat/following{/other_user}",
"gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
"starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
"organizations_url": "https://api.github.com/users/octocat/orgs",
"repos_url": "https://api.github.com/users/octocat/repos",
"events_url": "https://api.github.com/users/octocat/events{/privacy}",
"received_events_url": "https://api.github.com/users/octocat/received_events",
"type": "User",
"site_admin": false
},
"created_at": "2011-04-14T16:00:49Z",
"updated_at": "2011-04-14T16:00:49Z"
}
]
106 changes: 106 additions & 0 deletions packages/gcf-utils/test/gcf-utils.ts
@@ -0,0 +1,106 @@
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/* eslint-disable @typescript-eslint/no-var-requires */

import {addOrUpdateIssueComment} from '../src/gcf-utils';

import {resolve} from 'path';
import snapshot from 'snap-shot-it';
import {Application, Probot, ProbotOctokit} from 'probot';
import {describe, beforeEach, afterEach, it} from 'mocha';
import nock from 'nock';

nock.disableNetConnect();

const fixturesPath = resolve(__dirname, '../../test/fixtures');

// Test app
const app = (app: Application) => {
app.on('issues.opened', async context => {
await addOrUpdateIssueComment(
context,
context.payload.repository.owner.login,
context.payload.repository.name,
context.payload.issue.number,
'test comment'
);
});
};

describe('gcf-utils', () => {
describe('addOrUpdateIssueComment', () => {
let probot: Probot;
beforeEach(() => {
probot = new Probot({
id: 1,
githubToken: 'test',
Octokit: ProbotOctokit.defaults({
retry: {enabled: false},
throttle: {enabled: false},
}),
});
probot.load(app);
});

afterEach(() => {
nock.cleanAll();
});

it('creates a comment', async () => {
const payload = require(resolve(fixturesPath, './issue_event'));
const requests = nock('https://api.github.com')
.get(
'/repos/tmatsuo/python-docs-samples/issues/10/comments?per_page=50'
)
.reply(200, [])
.post('/repos/tmatsuo/python-docs-samples/issues/10/comments', body => {
snapshot(body);
return true;
})
.reply(200);

await probot.receive({
name: 'issues.opened',
payload,
id: 'test',
});
requests.done();
});
it('updates a comment', async () => {
const payload = require(resolve(fixturesPath, './issue_event'));
const listCommentsResponse = require(resolve(
fixturesPath,
'./list_issue_comments'
));
const requests = nock('https://api.github.com')
.get(
'/repos/tmatsuo/python-docs-samples/issues/10/comments?per_page=50'
)
.reply(200, listCommentsResponse)
.patch('/repos/tmatsuo/python-docs-samples/issues/comments/1', body => {
snapshot(body);
return true;
})
.reply(200);

await probot.receive({
name: 'issues.opened',
payload,
id: 'test',
});
requests.done();
});
});
});

0 comments on commit 448243f

Please sign in to comment.