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

Feature comment target #1228

Merged
merged 30 commits into from
Dec 15, 2022
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
9603e66
Allow creation of issue comments in cml (#1202)
tasdomas Oct 14, 2022
48a3258
Merge remote-tracking branch 'origin/master' into feature-comment-target
tasdomas Oct 15, 2022
edbf168
Update src/drivers/bitbucket_cloud.js
tasdomas Oct 18, 2022
5c5be0a
Update src/drivers/gitlab.js
tasdomas Oct 18, 2022
e862cfa
Update src/drivers/github.js
tasdomas Oct 18, 2022
6a1759b
Fix lint issues.
tasdomas Oct 18, 2022
6520007
Merge remote-tracking branch 'origin/master' into feature-comment-target
tasdomas Oct 24, 2022
994a2d4
Merge remote-tracking branch 'origin/master' into feature-comment-target
tasdomas Oct 27, 2022
9d4a6f7
Merge remote-tracking branch 'origin/master' into feature-comment-target
tasdomas Oct 28, 2022
2618c2f
Merge remote-tracking branch 'origin/master' into feature-comment-target
tasdomas Nov 4, 2022
5e26f7b
Merge branch 'master' into feature-comment-target
tasdomas Nov 9, 2022
dd911b1
Add comment target flag and parsing (#1241)
tasdomas Nov 9, 2022
cc42c79
Merge branch 'master' into feature-comment-target
tasdomas Nov 14, 2022
ad314b4
Merge branch 'master' into feature-comment-target
tasdomas Nov 18, 2022
d3f4b36
Remove duplicate warn methods.
tasdomas Nov 18, 2022
60885a7
Merge remote-tracking branch 'origin/master' into feature-comment-target
tasdomas Nov 30, 2022
e77898c
Make comment targets case-insensitive. (#1262)
tasdomas Dec 1, 2022
c396f54
Merge branch 'master' into feature-comment-target
tasdomas Dec 5, 2022
7541fb5
Merge branch 'master' into feature-comment-target
tasdomas Dec 5, 2022
2cfc4b6
Merge branch 'master' into feature-comment-target
tasdomas Dec 7, 2022
c630827
Apply suggestions from code review
tasdomas Dec 7, 2022
368ed05
Update snapshots.
tasdomas Dec 7, 2022
175c6df
Issue comments require an issue id.
tasdomas Dec 7, 2022
522d2a1
Replace comment target separator '#' with '/'. (#1279)
tasdomas Dec 9, 2022
8a8259a
Merge branch 'master' into feature-comment-target
tasdomas Dec 9, 2022
27353c8
Update warnings.
tasdomas Dec 12, 2022
3e96996
Add debug logging in comment target parsing.
tasdomas Dec 13, 2022
e78ba74
Fix comment target unit test.
tasdomas Dec 15, 2022
e39357f
Merge branch 'master' into feature-comment-target
tasdomas Dec 15, 2022
6ad756a
Merge branch 'master' into feature-comment-target
tasdomas Dec 15, 2022
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 .github/workflows/test-deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,15 @@ jobs:
TEST_GITHUB_TOKEN: ${{ secrets.TEST_GITHUB_TOKEN }}
TEST_GITHUB_REPO: https://github.com/iterative/cml_qa_tests_dummy
TEST_GITHUB_SHA: 0cd16da26e35f8e5d57b2549a97e22618abf08f6
TEST_GITHUB_ISSUE: 1
TEST_GITLAB_TOKEN: ${{ secrets.TEST_GITLAB_TOKEN }}
TEST_GITLAB_REPO: https://gitlab.com/iterative.ai/cml_qa_tests_dummy
TEST_GITLAB_SHA: f8b8b49a253243830ef59a7f090eb887157b2b67
TEST_GITLAB_ISSUE: 1
TEST_BBCLOUD_TOKEN: ${{ secrets.TEST_BBCLOUD_TOKEN }}
TEST_BBCLOUD_REPO: https://bitbucket.org/iterative-ai/cml-qa-tests-dummy
TEST_BBCLOUD_SHA: b511535a89f76d3d311b1c15e3e712b15c0b94e3
TEST_BBCLOUD_ISSUE: 1
test-os:
needs: authorize
name: test-${{ matrix.system }}
Expand Down
8 changes: 7 additions & 1 deletion bin/cml/comment/create.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,13 @@ exports.options = kebabcaseKeys({
pr: {
type: 'boolean',
description:
'Post to an existing PR/MR associated with the specified commit'
'Post to an existing PR/MR associated with the specified commit',
conflicts: ['issue']
},
issue: {
type: 'number',
description: 'Post to the given issue number',
conflicts: ['pr']
},
commitSha: {
type: 'string',
Expand Down
1 change: 1 addition & 0 deletions bin/cml/comment/create.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ describe('Comment integration tests', () => {
Options:
--pr Post to an existing PR/MR associated with the
specified commit [boolean]
--issue Post to the given issue number [number]
--commit-sha, --head-sha Commit SHA linked to this comment
[string] [default: \\"HEAD\\"]
--watch Watch for changes and automatically update the
Expand Down
18 changes: 18 additions & 0 deletions src/cml.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ class CML {
const triggerSha = await this.triggerSha();
const {
commitSha: inCommitSha = triggerSha,
issue: issueId,
rmWatermark,
update,
pr,
Expand Down Expand Up @@ -267,6 +268,23 @@ class CML {
return body.includes('watermark.svg');
});
};
// Create or update an issue comment.
if (issueId) {
if (update) {
comment = updatableComment(await drv.issueComments({ issueId }));

if (comment)
return await drv.issueCommentUpdate({
report,
id: comment.id,
issueId
});
}
return await drv.issueCommentCreate({
report,
issueId
});
}

const isBB = this.driver === BB;
if (pr || isBB) {
Expand Down
13 changes: 11 additions & 2 deletions src/drivers/bitbucket_cloud.e2e.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ const BitbucketCloud = require('./bitbucket_cloud');
const {
TEST_BBCLOUD_TOKEN: TOKEN,
TEST_BBCLOUD_REPO: REPO,
TEST_BBCLOUD_SHA: SHA
TEST_BBCLOUD_SHA: SHA,
TEST_BBCLOUD_ISSUE: ISSUE = 1
} = process.env;

describe('Non Enviromental tests', () => {
Expand All @@ -13,12 +14,20 @@ describe('Non Enviromental tests', () => {
expect(client.token).toBe(TOKEN);
});

test('Issue comment', async () => {
const report = '## Test comment';
const issueId = ISSUE;
const url = await client.issueCommentCreate({ report, issueId });

expect(url.startsWith('https://')).toBe(true);
});

test('Comment', async () => {
const report = '## Test comment';
const commitSha = SHA;
const url = await client.commentCreate({ report, commitSha });

expect(url.startsWith('https://')).toBe(true);
expect(url.startsWith(REPO)).toBe(true);
});

test('Check', async () => {
Expand Down
39 changes: 39 additions & 0 deletions src/drivers/bitbucket_cloud.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,45 @@ class BitbucketCloud {
}
}

async issueCommentCreate(opts = {}) {
const { projectPath } = this;
const { issueId, report } = opts;
const endpoint = `/repositories/${projectPath}/issues/${issueId}/comments/`;
return (
await this.request({
endpoint,
method: 'POST',
body: JSON.stringify({ content: { raw: report } })
})
).links.html.href;
}

async issueCommentUpdate(opts = {}) {
const { projectPath } = this;
const { issueId, id, report } = opts;

const endpoint = `/repositories/${projectPath}/issues/${issueId}/comments/${id}`;
return (
await this.request({
endpoint,
method: 'PUT',
body: JSON.stringify({ content: { raw: report } })
})
).links.html.href;
}
tasdomas marked this conversation as resolved.
Show resolved Hide resolved

async issueComments(opts = {}) {
const { projectPath } = this;
const { issueId } = opts;

const endpoint = `/repositories/${projectPath}/issues/${issueId}/comments/`;
return (await this.paginatedRequest({ endpoint, method: 'GET' })).map(
({ id, content: { raw: body = '' } = {} }) => {
return { id, body };
}
);
}

async commentCreate(opts = {}) {
const { projectPath } = this;
const { commitSha, report } = opts;
Expand Down
13 changes: 11 additions & 2 deletions src/drivers/github.e2e.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ const GithubClient = require('./github');
const {
TEST_GITHUB_TOKEN: TOKEN,
TEST_GITHUB_REPO: REPO,
TEST_GITHUB_SHA: SHA
TEST_GITHUB_SHA: SHA,
TEST_GITHUB_ISSUE: ISSUE = 1
} = process.env;

describe('Non Enviromental tests', () => {
Expand All @@ -19,12 +20,20 @@ describe('Non Enviromental tests', () => {
expect(repo).toBe(parts[parts.length - 1]);
});

test('Issue comment', async () => {
const report = '## Test comment';
const issueId = ISSUE;
const url = await client.issueCommentCreate({ issueId, report });

expect(url.startsWith(REPO)).toBe(true);
});

test('Comment', async () => {
const report = '## Test comment';
const commitSha = SHA;
const url = await client.commentCreate({ report, commitSha });

expect(url.startsWith('https://')).toBe(true);
expect(url.startsWith(REPO)).toBe(true);
});

test('Publish', async () => {
Expand Down
50 changes: 50 additions & 0 deletions src/drivers/github.js
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,56 @@ class Github {
}
}

async issueCommentCreate(opts = {}) {
const { issueId, report } = opts;
const { owner, repo } = ownerRepo({ uri: this.repo });
const { issues } = octokit(this.token, this.repo);

const {
data: { html_url: htmlUrl }
} = await issues.createComment({
owner,
repo,
body: report,
issue_number: issueId
});

return htmlUrl;
}

async issueCommentUpdate(opts = {}) {
const { id, report } = opts;
tasdomas marked this conversation as resolved.
Show resolved Hide resolved
const { owner, repo } = ownerRepo({ uri: this.repo });
const { issues } = octokit(this.token, this.repo);

const {
data: { html_url: htmlUrl }
} = await issues.updateComment({
owner,
repo,
body: report,
comment_id: id
});

return htmlUrl;
}

async issueComments(opts = {}) {
const { issueId } = opts;
const { owner, repo } = ownerRepo({ uri: this.repo });
const { issues } = octokit(this.token, this.repo);

const { data: comments } = await issues.listComments({
owner,
repo,
issue_number: issueId
});

return comments.map(({ id, body }) => {
return { id, body };
});
}

async prCommentCreate(opts = {}) {
const { report: body, prNumber } = opts;
const { owner, repo } = ownerRepo({ uri: this.repo });
Expand Down
11 changes: 10 additions & 1 deletion src/drivers/gitlab.e2e.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ const GitlabClient = require('./gitlab');
const {
TEST_GITLAB_TOKEN: TOKEN,
TEST_GITLAB_REPO: REPO,
TEST_GITLAB_SHA: SHA
TEST_GITLAB_SHA: SHA,
TEST_GITLAB_ISSUE: ISSUE = 1
} = process.env;

describe('Non Enviromental tests', () => {
Expand All @@ -14,6 +15,14 @@ describe('Non Enviromental tests', () => {
expect(client.token).toBe(TOKEN);
});

test('Issue comment', async () => {
const report = '## Test comment';
const issueId = ISSUE;
const url = await client.issueCommentCreate({ issueId, report });

expect(url.startsWith(REPO)).toBe(true);
});

test('Comment', async () => {
const report = '## Test comment';
const commitSha = SHA;
Expand Down
50 changes: 50 additions & 0 deletions src/drivers/gitlab.js
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,56 @@ class Gitlab {
}
}

async issueCommentCreate(opts = {}) {
const projectPath = await this.projectPath();
const { issueId, report } = opts;

const endpoint = `/projects/${projectPath}/issues/${issueId}/notes`;
const body = new URLSearchParams();
body.append('body', report);

const { id } = await this.request({
endpoint,
method: 'POST',
body
});

return `${this.repo}/-/issues/${issueId}#note_${id}`;
}

async issueCommentUpdate(opts = {}) {
const projectPath = await this.projectPath();
const { issueId, id: commentId, report } = opts;

const endpoint = `/projects/${projectPath}/issues/${issueId}/notes/${commentId}`;
const body = new URLSearchParams();
body.append('body', report);

const { id } = await this.request({
endpoint,
method: 'PUT',
body
});

return `${this.repo}/-/issues/${issueId}#note_${id}`;
}
tasdomas marked this conversation as resolved.
Show resolved Hide resolved

async issueComments(opts = {}) {
const projectPath = await this.projectPath();
const { issueId } = opts;

const endpoint = `/projects/${projectPath}/issues/${issueId}/notes`;

const comments = await this.request({
endpoint,
method: 'GET'
});

return comments.map(({ id, body }) => {
return { id, body };
});
}

async prCommentCreate(opts = {}) {
const projectPath = await this.projectPath();
const { report, prNumber } = opts;
Expand Down