Skip to content

Commit 66b2581

Browse files
author
Andrei Iurko
committed
🐛 QD-10984 Azure task fixes
Fixes: Quick-fixes push if both branch mode AND pr-mode are specified. Coverage highlighting for any markdown (not only GitHub). Ability to change args through UI
1 parent daefe06 commit 66b2581

File tree

10 files changed

+134
-81
lines changed

10 files changed

+134
-81
lines changed

common/__tests__/main.test.ts

Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,18 +24,36 @@ import * as fs from 'fs'
2424
import * as path from 'path'
2525
import * as os from 'os'
2626

27-
test('test passed coverage output', () => {
27+
test('test passed coverage output using diff', () => {
2828
const result = getCoverageStats(
29-
getCoverageFromSarif('__tests__/data/some.sarif.json')
29+
getCoverageFromSarif('__tests__/data/some.sarif.json'),
30+
true
3031
)
31-
expect(result).toEqual(passedCoverageFixture())
32+
expect(result).toEqual(passedCoverageFixtureDiff())
3233
})
3334

34-
test('test failed coverage output', () => {
35+
test('test failed coverage output using diff', () => {
3536
const result = getCoverageStats(
36-
getCoverageFromSarif('__tests__/data/empty.sarif.json')
37+
getCoverageFromSarif('__tests__/data/empty.sarif.json'),
38+
true
3739
)
38-
expect(result).toEqual(failedCoverageFixture())
40+
expect(result).toEqual(failedCoverageFixtureDiff())
41+
})
42+
43+
test('test passed coverage output using spam', () => {
44+
const result = getCoverageStats(
45+
getCoverageFromSarif('__tests__/data/some.sarif.json'),
46+
false
47+
)
48+
expect(result).toEqual(passedCoverageFixtureSpam())
49+
})
50+
51+
test('test failed coverage output using spam', () => {
52+
const result = getCoverageStats(
53+
getCoverageFromSarif('__tests__/data/empty.sarif.json'),
54+
false
55+
)
56+
expect(result).toEqual(failedCoverageFixtureSpam())
3957
})
4058

4159
describe('getReportURL', () => {
@@ -90,7 +108,25 @@ describe('getReportURL', () => {
90108
})
91109
})
92110

93-
function passedCoverageFixture(): string {
111+
function passedCoverageFixtureSpam(): string {
112+
return `@@ Code coverage @@
113+
<span style="background-color: #e6f4e6; color: green;">45% total lines covered</span>
114+
124 lines analyzed, 56 lines covered
115+
<span style="background-color: #e6f4e6; color: green;">33% fresh lines covered</span>
116+
9 lines analyzed, 3 lines covered
117+
# Calculated according to the filters of your coverage tool`
118+
}
119+
120+
function failedCoverageFixtureSpam(): string {
121+
return `@@ Code coverage @@
122+
<span style="background-color: #ffe6e6; color: red;">0% total lines covered</span>
123+
100 lines analyzed, 0 lines covered
124+
<span style="background-color: #ffe6e6; color: red;">0% fresh lines covered</span>
125+
100 lines analyzed, 0 lines covered
126+
# Calculated according to the filters of your coverage tool`
127+
}
128+
129+
function passedCoverageFixtureDiff(): string {
94130
return `\`\`\`diff
95131
@@ Code coverage @@
96132
+ 45% total lines covered
@@ -101,7 +137,7 @@ function passedCoverageFixture(): string {
101137
\`\`\``
102138
}
103139

104-
function failedCoverageFixture(): string {
140+
function failedCoverageFixtureDiff(): string {
105141
return `\`\`\`diff
106142
@@ Code coverage @@
107143
- 0% total lines covered

common/output.ts

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -99,41 +99,43 @@ ${message}
9999

100100
function makeConclusion(
101101
conclusion: string,
102-
failedByThreshold: boolean
102+
failedByThreshold: boolean,
103+
useDiffBlock: boolean,
103104
): string {
104-
if (failedByThreshold) {
105-
return `- ${conclusion}`
105+
if (useDiffBlock) {
106+
return failedByThreshold ? `- ${conclusion}` : `+ ${conclusion}`
106107
} else {
107-
return `+ ${conclusion}`
108+
return failedByThreshold
109+
? `<span style="background-color: #ffe6e6; color: red;">${conclusion}</span>`
110+
: `<span style="background-color: #e6f4e6; color: green;">${conclusion}</span>`
108111
}
109112
}
110113

111-
export function getCoverageStats(c: Coverage): string {
114+
export function getCoverageStats(c: Coverage, useDiffBlock: boolean): string {
112115
if (c.totalLines === 0 && c.totalCoveredLines === 0) {
113116
return ''
114117
}
115118

116119
let stats = ''
117120
if (c.totalLines !== 0) {
118121
const conclusion = `${c.totalCoverage}% total lines covered`
119-
stats += `${makeConclusion(conclusion, c.totalCoverage < c.totalCoverageThreshold)}
122+
stats += `${makeConclusion(conclusion, c.totalCoverage < c.totalCoverageThreshold, useDiffBlock)}
120123
${c.totalLines} lines analyzed, ${c.totalCoveredLines} lines covered`
121124
}
122125

123126
if (c.freshLines !== 0) {
124127
const conclusion = `${c.freshCoverage}% fresh lines covered`
125128
stats += `
126-
${makeConclusion(conclusion, c.freshCoverage < c.freshCoverageThreshold)}
129+
${makeConclusion(conclusion, c.freshCoverage < c.freshCoverageThreshold, useDiffBlock)}
127130
${c.freshLines} lines analyzed, ${c.freshCoveredLines} lines covered`
128131
}
129132

130-
return wrapToDiffBlock(
131-
[
132-
`@@ Code coverage @@`,
133-
`${stats}`,
134-
`# Calculated according to the filters of your coverage tool`
135-
].join('\n')
136-
)
133+
const coverageBlock = [
134+
`@@ Code coverage @@`,
135+
`${stats}`,
136+
`# Calculated according to the filters of your coverage tool`
137+
].join('\n')
138+
return useDiffBlock ? wrapToDiffBlock(coverageBlock) : coverageBlock
137139
}
138140

139141
export function getLicenseInfo(

scan/dist/index.js

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -137016,36 +137016,35 @@ function wrapToDiffBlock(message) {
137016137016
${message}
137017137017
\`\`\``;
137018137018
}
137019-
function makeConclusion(conclusion, failedByThreshold) {
137020-
if (failedByThreshold) {
137021-
return `- ${conclusion}`;
137019+
function makeConclusion(conclusion, failedByThreshold, useDiffBlock) {
137020+
if (useDiffBlock) {
137021+
return failedByThreshold ? `- ${conclusion}` : `+ ${conclusion}`;
137022137022
} else {
137023-
return `+ ${conclusion}`;
137023+
return failedByThreshold ? `<span style="background-color: #ffe6e6; color: red;">${conclusion}</span>` : `<span style="background-color: #e6f4e6; color: green;">${conclusion}</span>`;
137024137024
}
137025137025
}
137026-
function getCoverageStats(c) {
137026+
function getCoverageStats(c, useDiffBlock) {
137027137027
if (c.totalLines === 0 && c.totalCoveredLines === 0) {
137028137028
return "";
137029137029
}
137030137030
let stats = "";
137031137031
if (c.totalLines !== 0) {
137032137032
const conclusion = `${c.totalCoverage}% total lines covered`;
137033-
stats += `${makeConclusion(conclusion, c.totalCoverage < c.totalCoverageThreshold)}
137033+
stats += `${makeConclusion(conclusion, c.totalCoverage < c.totalCoverageThreshold, useDiffBlock)}
137034137034
${c.totalLines} lines analyzed, ${c.totalCoveredLines} lines covered`;
137035137035
}
137036137036
if (c.freshLines !== 0) {
137037137037
const conclusion = `${c.freshCoverage}% fresh lines covered`;
137038137038
stats += `
137039-
${makeConclusion(conclusion, c.freshCoverage < c.freshCoverageThreshold)}
137039+
${makeConclusion(conclusion, c.freshCoverage < c.freshCoverageThreshold, useDiffBlock)}
137040137040
${c.freshLines} lines analyzed, ${c.freshCoveredLines} lines covered`;
137041137041
}
137042-
return wrapToDiffBlock(
137043-
[
137044-
`@@ Code coverage @@`,
137045-
`${stats}`,
137046-
`# Calculated according to the filters of your coverage tool`
137047-
].join("\n")
137048-
);
137042+
const coverageBlock = [
137043+
`@@ Code coverage @@`,
137044+
`${stats}`,
137045+
`# Calculated according to the filters of your coverage tool`
137046+
].join("\n");
137047+
return useDiffBlock ? wrapToDiffBlock(coverageBlock) : coverageBlock;
137049137048
}
137050137049
function getLicenseInfo(resultsDir) {
137051137050
let licensesInfo = "";
@@ -137558,7 +137557,7 @@ so that the action will upload the files as the job artifacts:
137558137557
try {
137559137558
const problems = (0, annotations_1.parseSarif)(`${resultsDir}/${qodana_12.QODANA_SARIF_NAME}`);
137560137559
const reportUrl = (0, output_12.getReportURL)(resultsDir);
137561-
const coverageInfo = (0, output_12.getCoverageStats)((0, qodana_12.getCoverageFromSarif)(`${resultsDir}/${qodana_12.QODANA_SHORT_SARIF_NAME}`));
137560+
const coverageInfo = (0, output_12.getCoverageStats)((0, qodana_12.getCoverageFromSarif)(`${resultsDir}/${qodana_12.QODANA_SHORT_SARIF_NAME}`), true);
137562137561
const licensesInfo = (0, output_12.getLicenseInfo)(resultsDir);
137563137562
const problemsDescriptions = annotationsToProblemDescriptors(problems.annotations);
137564137563
const toolName = (_a = problems.title.split("found by ")[1]) !== null && _a !== void 0 ? _a : output_12.QODANA_CHECK_NAME;

scan/src/output.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,8 @@ export async function publishOutput(
9393
const problems = parseSarif(`${resultsDir}/${QODANA_SARIF_NAME}`)
9494
const reportUrl = getReportURL(resultsDir)
9595
const coverageInfo = getCoverageStats(
96-
getCoverageFromSarif(`${resultsDir}/${QODANA_SHORT_SARIF_NAME}`)
96+
getCoverageFromSarif(`${resultsDir}/${QODANA_SHORT_SARIF_NAME}`),
97+
true
9798
)
9899

99100
const licensesInfo: LicenseInfo = getLicenseInfo(resultsDir)

vsts/QodanaScan/index.js

Lines changed: 20 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -16877,36 +16877,35 @@ function wrapToDiffBlock(message) {
1687716877
${message}
1687816878
\`\`\``;
1687916879
}
16880-
function makeConclusion(conclusion, failedByThreshold) {
16881-
if (failedByThreshold) {
16882-
return `- ${conclusion}`;
16880+
function makeConclusion(conclusion, failedByThreshold, useDiffBlock) {
16881+
if (useDiffBlock) {
16882+
return failedByThreshold ? `- ${conclusion}` : `+ ${conclusion}`;
1688316883
} else {
16884-
return `+ ${conclusion}`;
16884+
return failedByThreshold ? `<span style="background-color: #ffe6e6; color: red;">${conclusion}</span>` : `<span style="background-color: #e6f4e6; color: green;">${conclusion}</span>`;
1688516885
}
1688616886
}
16887-
function getCoverageStats(c) {
16887+
function getCoverageStats(c, useDiffBlock) {
1688816888
if (c.totalLines === 0 && c.totalCoveredLines === 0) {
1688916889
return "";
1689016890
}
1689116891
let stats = "";
1689216892
if (c.totalLines !== 0) {
1689316893
const conclusion = `${c.totalCoverage}% total lines covered`;
16894-
stats += `${makeConclusion(conclusion, c.totalCoverage < c.totalCoverageThreshold)}
16894+
stats += `${makeConclusion(conclusion, c.totalCoverage < c.totalCoverageThreshold, useDiffBlock)}
1689516895
${c.totalLines} lines analyzed, ${c.totalCoveredLines} lines covered`;
1689616896
}
1689716897
if (c.freshLines !== 0) {
1689816898
const conclusion = `${c.freshCoverage}% fresh lines covered`;
1689916899
stats += `
16900-
${makeConclusion(conclusion, c.freshCoverage < c.freshCoverageThreshold)}
16900+
${makeConclusion(conclusion, c.freshCoverage < c.freshCoverageThreshold, useDiffBlock)}
1690116901
${c.freshLines} lines analyzed, ${c.freshCoveredLines} lines covered`;
1690216902
}
16903-
return wrapToDiffBlock(
16904-
[
16905-
`@@ Code coverage @@`,
16906-
`${stats}`,
16907-
`# Calculated according to the filters of your coverage tool`
16908-
].join("\n")
16909-
);
16903+
const coverageBlock = [
16904+
`@@ Code coverage @@`,
16905+
`${stats}`,
16906+
`# Calculated according to the filters of your coverage tool`
16907+
].join("\n");
16908+
return useDiffBlock ? wrapToDiffBlock(coverageBlock) : coverageBlock;
1691016909
}
1691116910
function getLicenseInfo(resultsDir) {
1691216911
let licensesInfo = "";
@@ -79048,7 +79047,7 @@ so that the action will upload the files as the job artifacts:
7904879047
try {
7904979048
const problems = (0, utils_12.parseSarif)(`${resultsDir}/${qodana_12.QODANA_SARIF_NAME}`);
7905079049
const reportUrl = (0, output_12.getReportURL)(resultsDir);
79051-
const coverageInfo = (0, output_12.getCoverageStats)((0, qodana_12.getCoverageFromSarif)(`${resultsDir}/${qodana_12.QODANA_SHORT_SARIF_NAME}`));
79050+
const coverageInfo = (0, output_12.getCoverageStats)((0, qodana_12.getCoverageFromSarif)(`${resultsDir}/${qodana_12.QODANA_SHORT_SARIF_NAME}`), false);
7905279051
const licensesInfo = (0, output_12.getLicenseInfo)(resultsDir);
7905379052
const problemsDescriptions = (_a = problems.problemDescriptions) !== null && _a !== void 0 ? _a : [];
7905479053
const toolName = (_b = problems.title.split("found by ")[1]) !== null && _b !== void 0 ? _b : output_12.QODANA_CHECK_NAME;
@@ -79185,10 +79184,10 @@ var require_utils4 = __commonJS({
7918579184
uploadSarif: tl2.getBoolInput("uploadSarif", false),
7918679185
artifactName: tl2.getInput("artifactName", false) || "qodana-report",
7918779186
useNightly: tl2.getBoolInput("useNightly", false),
79188-
prMode: tl2.getBoolInput("prMode", true),
79187+
prMode: tl2.getBoolInput("prMode", false),
7918979188
postComment: tl2.getBoolInput("postPrComment", false),
7919079189
pushFixes: tl2.getInput("pushFixes", false) || "none",
79191-
commitMessage: tl2.getInput("commitMessage", false) || "\u{1F916} Apply quick-fixes by Qodana",
79190+
commitMessage: tl2.getInput("commitMessage", false) || "\u{1F916} Apply quick-fixes by Qodana \n\n[skip ci]",
7919279191
// Not used by the Azure task
7919379192
additionalCacheKey: "",
7919479193
primaryCacheKey: "",
@@ -79466,11 +79465,9 @@ ${comment_tag_pattern}`;
7946679465
return;
7946779466
}
7946879467
if (mode === qodana_12.BRANCH) {
79469-
if (pullRequest) {
79470-
const commitToCherryPick = (yield gitOutput(["rev-parse", "HEAD"])).stdout.trim();
79471-
yield git(["checkout", currentBranch]);
79472-
yield git(["cherry-pick", commitToCherryPick]);
79473-
}
79468+
const commitToCherryPick = (yield gitOutput(["rev-parse", "HEAD"])).stdout.trim();
79469+
yield git(["checkout", currentBranch]);
79470+
yield git(["cherry-pick", commitToCherryPick]);
7947479471
yield gitPush(currentBranch);
7947579472
} else if (mode === qodana_12.PULL_REQUEST) {
7947679473
const newBranch = `qodana/quick-fixes-${currentCommit.slice(0, 7)}`;
@@ -79488,9 +79485,7 @@ ${comment_tag_pattern}`;
7948879485
const output = yield gitOutput(["push", "origin", branch], {
7948979486
ignoreReturnCode: true
7949079487
});
79491-
if (output.exitCode == 1) {
79492-
tl2.warning(`Branch ${branch} already exists. Push of quick-fixes was skipped.`);
79493-
} else if (output.exitCode !== 0) {
79488+
if (output.exitCode !== 0) {
7949479489
tl2.warning(`Failed to push branch ${branch}: ${output.stderr}`);
7949579490
}
7949679491
});

vsts/QodanaScan/task.json

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,33 @@
7474
"name": "prMode",
7575
"type": "boolean",
7676
"label": "PR Mode",
77-
"defaultValue": false,
77+
"defaultValue": true,
7878
"required": false,
7979
"helpMarkDown": "Whether the PR analysis gets executed in the pull request mode."
80+
},
81+
{
82+
"name": "postPrComment",
83+
"type": "boolean",
84+
"label": "Post PR comment",
85+
"defaultValue": true,
86+
"required": false,
87+
"helpMarkDown": "Post a comment with the Qodana results summary to the pull request."
88+
},
89+
{
90+
"name": "pushFixes",
91+
"type": "string",
92+
"label": "Push quick-fixes",
93+
"defaultValue": "none",
94+
"required": false,
95+
"helpMarkDown": "Push Qodana fixes to the repository, can be `none`, `branch` to the current branch, or `pull-request`."
96+
},
97+
{
98+
"name": "commitMessage",
99+
"type": "string",
100+
"label": "Commit Message",
101+
"defaultValue": "\uD83E\uDD16 Apply quick-fixes by Qodana\n\n[skip ci]",
102+
"required": false,
103+
"helpMarkDown": "Message used when quick-fixes are pushed"
80104
}
81105
],
82106
"execution": {

vsts/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ to
6868
- or `branch`: push fixes to the original branch
6969
3. Set the correct permissions for the job. Go to `Repositories` → `Manage repositories` → `Security`. Choose `Qodana for Azure Pipelines Build Service` user. Allow:
7070
- `Contribute`
71-
- `Bypass policies when pushing`. Without this, the analysis will be performed twice
71+
- `Bypass policies when pushing` if they may fail the push of quick-fixes
7272
- `Create branch` if you use `pull-request` value
7373

7474
Also, set `persistCredentials` property to `true`. This is needed for pushing changes to the repository

vsts/src/output.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ export async function publishOutput(
6969
const problems = parseSarif(`${resultsDir}/${QODANA_SARIF_NAME}`)
7070
const reportUrl = getReportURL(resultsDir)
7171
const coverageInfo = getCoverageStats(
72-
getCoverageFromSarif(`${resultsDir}/${QODANA_SHORT_SARIF_NAME}`)
72+
getCoverageFromSarif(`${resultsDir}/${QODANA_SHORT_SARIF_NAME}`),
73+
false
7374
)
7475

7576
const licensesInfo = getLicenseInfo(resultsDir)

0 commit comments

Comments
 (0)