Skip to content

Commit 48136c0

Browse files
author
Anuraag Puri
authored
Feature: Use same comment. Also don't pick removed files for delta validation (anuraag016#30)
* Feature: Use same comment, delta for removed files * Add commit SHA to comment * Fix delta comment update
1 parent fe1fd4b commit 48136c0

File tree

4 files changed

+159
-24
lines changed

4 files changed

+159
-24
lines changed

action.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ inputs:
1717
delta:
1818
description: 'Difference between the old and final test coverage'
1919
default: 100
20+
useSameComment:
21+
description: 'While commenting on the PR update the exisiting comment'
22+
default: false
2023
branding:
2124
color: red
2225
icon: git-pull-request

dist/index.js

Lines changed: 56 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2027,6 +2027,7 @@ function run() {
20272027
try {
20282028
const repoName = github.context.repo.repo;
20292029
const repoOwner = github.context.repo.owner;
2030+
const commitSha = github.context.sha;
20302031
const githubToken = core.getInput('accessToken');
20312032
const fullCoverage = JSON.parse(core.getInput('fullCoverageDiff'));
20322033
const commandToRun = core.getInput('runCommand');
@@ -2036,6 +2037,10 @@ function run() {
20362037
const prNumber = github.context.issue.number;
20372038
const branchNameBase = (_a = github.context.payload.pull_request) === null || _a === void 0 ? void 0 : _a.base.ref;
20382039
const branchNameHead = (_b = github.context.payload.pull_request) === null || _b === void 0 ? void 0 : _b.head.ref;
2040+
const useSameComment = JSON.parse(core.getInput('useSameComment'));
2041+
const commentIdentifier = `<!-- codeCoverageDiffComment -->`;
2042+
const deltaCommentIdentifier = `<!-- codeCoverageDeltaComment -->`;
2043+
let commentId = null;
20392044
child_process_1.execSync(commandToRun);
20402045
const codeCoverageNew = (JSON.parse(fs_1.default.readFileSync('coverage-summary.json').toString()));
20412046
child_process_1.execSync('/usr/bin/git fetch');
@@ -2062,21 +2067,19 @@ function run() {
20622067
'Status | File | % Stmts | % Branch | % Funcs | % Lines \n -----|-----|---------|----------|---------|------ \n';
20632068
messageToPost += coverageDetails.join('\n');
20642069
}
2065-
yield githubClient.issues.createComment({
2066-
repo: repoName,
2067-
owner: repoOwner,
2068-
body: messageToPost,
2069-
issue_number: prNumber
2070-
});
2070+
messageToPost = `${commentIdentifier}\nCommit SHA:${commitSha}\n${messageToPost}`;
2071+
if (useSameComment) {
2072+
commentId = yield findComment(githubClient, repoName, repoOwner, prNumber, commentIdentifier);
2073+
}
2074+
yield createOrUpdateComment(commentId, githubClient, repoOwner, repoName, messageToPost, prNumber);
20712075
// check if the test coverage is falling below delta/tolerance.
20722076
if (diffChecker.checkIfTestCoverageFallsBelowDelta(delta)) {
2077+
if (useSameComment) {
2078+
commentId = yield findComment(githubClient, repoName, repoOwner, prNumber, deltaCommentIdentifier);
2079+
}
20732080
messageToPost = `Current PR reduces the test coverage percentage by ${delta} for some tests`;
2074-
yield githubClient.issues.createComment({
2075-
repo: repoName,
2076-
owner: repoOwner,
2077-
body: messageToPost,
2078-
issue_number: prNumber
2079-
});
2081+
messageToPost = `${deltaCommentIdentifier}\nCommit SHA:${commitSha}\n${messageToPost}`;
2082+
yield createOrUpdateComment(commentId, githubClient, repoOwner, repoName, messageToPost, prNumber);
20802083
throw Error(messageToPost);
20812084
}
20822085
}
@@ -2085,6 +2088,41 @@ function run() {
20852088
}
20862089
});
20872090
}
2091+
function createOrUpdateComment(commentId, githubClient, repoOwner, repoName, messageToPost, prNumber) {
2092+
return __awaiter(this, void 0, void 0, function* () {
2093+
if (commentId) {
2094+
yield githubClient.issues.updateComment({
2095+
owner: repoOwner,
2096+
repo: repoName,
2097+
comment_id: commentId,
2098+
body: messageToPost
2099+
});
2100+
}
2101+
else {
2102+
yield githubClient.issues.createComment({
2103+
repo: repoName,
2104+
owner: repoOwner,
2105+
body: messageToPost,
2106+
issue_number: prNumber
2107+
});
2108+
}
2109+
});
2110+
}
2111+
function findComment(githubClient, repoName, repoOwner, prNumber, identifier) {
2112+
return __awaiter(this, void 0, void 0, function* () {
2113+
const comments = yield githubClient.issues.listComments({
2114+
owner: repoOwner,
2115+
repo: repoName,
2116+
issue_number: prNumber
2117+
});
2118+
for (const comment of comments.data) {
2119+
if (comment.body.startsWith(identifier)) {
2120+
return comment.id;
2121+
}
2122+
}
2123+
return 0;
2124+
});
2125+
}
20882126
run();
20892127

20902128

@@ -6733,6 +6771,12 @@ class DiffChecker {
67336771
for (const key of keys) {
67346772
const diffCoverageData = this.diffCoverageReport[key];
67356773
const keys = Object.keys(diffCoverageData);
6774+
// No new coverage found so that means we deleted a file coverage
6775+
const fileRemovedCoverage = Object.values(diffCoverageData).every(coverageData => coverageData.newPct === 0);
6776+
if (fileRemovedCoverage) {
6777+
// since the file is deleted don't include in delta calculation
6778+
continue;
6779+
}
67366780
for (const key of keys) {
67376781
if (diffCoverageData[key].oldPct !== diffCoverageData[key].newPct) {
67386782
if (-this.getPercentageDiff(diffCoverageData[key]) > delta) {

src/DiffChecker.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,14 @@ export class DiffChecker {
7474
const keys: ('lines' | 'statements' | 'branches' | 'functions')[] = <
7575
('lines' | 'statements' | 'branches' | 'functions')[]
7676
>Object.keys(diffCoverageData)
77+
// No new coverage found so that means we deleted a file coverage
78+
const fileRemovedCoverage = Object.values(diffCoverageData).every(
79+
coverageData => coverageData.newPct === 0
80+
)
81+
if (fileRemovedCoverage) {
82+
// since the file is deleted don't include in delta calculation
83+
continue
84+
}
7785
for (const key of keys) {
7886
if (diffCoverageData[key].oldPct !== diffCoverageData[key].newPct) {
7987
if (-this.getPercentageDiff(diffCoverageData[key]) > delta) {

src/main.ts

Lines changed: 92 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,15 @@ import {execSync} from 'child_process'
44
import fs from 'fs'
55
import {CoverageReport} from './Model/CoverageReport'
66
import {DiffChecker} from './DiffChecker'
7+
import {Octokit} from '@octokit/core'
8+
import {PaginateInterface} from '@octokit/plugin-paginate-rest'
9+
import {RestEndpointMethods} from '@octokit/plugin-rest-endpoint-methods/dist-types/generated/method-types'
710

811
async function run(): Promise<void> {
912
try {
1013
const repoName = github.context.repo.repo
1114
const repoOwner = github.context.repo.owner
15+
const commitSha = github.context.sha
1216
const githubToken = core.getInput('accessToken')
1317
const fullCoverage = JSON.parse(core.getInput('fullCoverageDiff'))
1418
const commandToRun = core.getInput('runCommand')
@@ -18,6 +22,10 @@ async function run(): Promise<void> {
1822
const prNumber = github.context.issue.number
1923
const branchNameBase = github.context.payload.pull_request?.base.ref
2024
const branchNameHead = github.context.payload.pull_request?.head.ref
25+
const useSameComment = JSON.parse(core.getInput('useSameComment'))
26+
const commentIdentifier = `<!-- codeCoverageDiffComment -->`
27+
const deltaCommentIdentifier = `<!-- codeCoverageDeltaComment -->`
28+
let commentId = null
2129
execSync(commandToRun)
2230
const codeCoverageNew = <CoverageReport>(
2331
JSON.parse(fs.readFileSync('coverage-summary.json').toString())
@@ -53,27 +61,99 @@ async function run(): Promise<void> {
5361
'Status | File | % Stmts | % Branch | % Funcs | % Lines \n -----|-----|---------|----------|---------|------ \n'
5462
messageToPost += coverageDetails.join('\n')
5563
}
56-
await githubClient.issues.createComment({
57-
repo: repoName,
58-
owner: repoOwner,
59-
body: messageToPost,
60-
issue_number: prNumber
61-
})
64+
messageToPost = `${commentIdentifier}\nCommit SHA:${commitSha}\n${messageToPost}`
65+
if (useSameComment) {
66+
commentId = await findComment(
67+
githubClient,
68+
repoName,
69+
repoOwner,
70+
prNumber,
71+
commentIdentifier
72+
)
73+
}
74+
await createOrUpdateComment(
75+
commentId,
76+
githubClient,
77+
repoOwner,
78+
repoName,
79+
messageToPost,
80+
prNumber
81+
)
6282

6383
// check if the test coverage is falling below delta/tolerance.
6484
if (diffChecker.checkIfTestCoverageFallsBelowDelta(delta)) {
85+
if (useSameComment) {
86+
commentId = await findComment(
87+
githubClient,
88+
repoName,
89+
repoOwner,
90+
prNumber,
91+
deltaCommentIdentifier
92+
)
93+
}
6594
messageToPost = `Current PR reduces the test coverage percentage by ${delta} for some tests`
66-
await githubClient.issues.createComment({
67-
repo: repoName,
68-
owner: repoOwner,
69-
body: messageToPost,
70-
issue_number: prNumber
71-
})
95+
messageToPost = `${deltaCommentIdentifier}\nCommit SHA:${commitSha}\n${messageToPost}`
96+
await createOrUpdateComment(
97+
commentId,
98+
githubClient,
99+
repoOwner,
100+
repoName,
101+
messageToPost,
102+
prNumber
103+
)
72104
throw Error(messageToPost)
73105
}
74106
} catch (error) {
75107
core.setFailed(error)
76108
}
77109
}
78110

111+
async function createOrUpdateComment(
112+
commentId: number | null,
113+
githubClient: {[x: string]: any} & {[x: string]: any} & Octokit &
114+
RestEndpointMethods & {paginate: PaginateInterface},
115+
repoOwner: string,
116+
repoName: string,
117+
messageToPost: string,
118+
prNumber: number
119+
) {
120+
if (commentId) {
121+
await githubClient.issues.updateComment({
122+
owner: repoOwner,
123+
repo: repoName,
124+
comment_id: commentId,
125+
body: messageToPost
126+
})
127+
} else {
128+
await githubClient.issues.createComment({
129+
repo: repoName,
130+
owner: repoOwner,
131+
body: messageToPost,
132+
issue_number: prNumber
133+
})
134+
}
135+
}
136+
137+
async function findComment(
138+
githubClient: {[x: string]: any} & {[x: string]: any} & Octokit &
139+
RestEndpointMethods & {paginate: PaginateInterface},
140+
repoName: string,
141+
repoOwner: string,
142+
prNumber: number,
143+
identifier: string
144+
): Promise<number> {
145+
const comments = await githubClient.issues.listComments({
146+
owner: repoOwner,
147+
repo: repoName,
148+
issue_number: prNumber
149+
})
150+
151+
for (const comment of comments.data) {
152+
if (comment.body.startsWith(identifier)) {
153+
return comment.id
154+
}
155+
}
156+
return 0
157+
}
158+
79159
run()

0 commit comments

Comments
 (0)