From aeaf4aa7e036a3dd76d0638b180d3508fa83ccf1 Mon Sep 17 00:00:00 2001 From: Andrei Iurko Date: Wed, 13 Nov 2024 17:23:57 +0300 Subject: [PATCH] :bug: Make GHA respect coverage thresholds (QD-10150) --- common/qodana.ts | 17 +++++++++++++++-- scan/__tests__/data/some.sarif.json | 10 ++++++++-- scan/__tests__/main.test.ts | 10 ++++------ scan/dist/index.js | 14 +++++++++----- scan/src/output.ts | 8 +++----- vsts/QodanaScan/index.js | 9 +++++++-- 6 files changed, 46 insertions(+), 22 deletions(-) diff --git a/common/qodana.ts b/common/qodana.ts index 4751280c..0f5c028d 100644 --- a/common/qodana.ts +++ b/common/qodana.ts @@ -225,6 +225,8 @@ export interface Coverage { freshCoverage: number freshLines: number freshCoveredLines: number + totalCoverageThreshold: number + freshCoverageThreshold: number } /** @@ -250,7 +252,16 @@ export function getCoverageFromSarif(sarifPath: string): Coverage { freshLines: sarifContents.runs[0].properties['coverage']['freshLines'] || 0, freshCoveredLines: - sarifContents.runs[0].properties['coverage']['freshCoveredLines'] || 0 + sarifContents.runs[0].properties['coverage']['freshCoveredLines'] || + 0, + totalCoverageThreshold: + sarifContents.runs[0].properties['qodanaFailureConditions']?.[ + 'testCoverageThresholds' + ]?.['totalCoverage'] || COVERAGE_THRESHOLD, + freshCoverageThreshold: + sarifContents.runs[0].properties['qodanaFailureConditions']?.[ + 'testCoverageThresholds' + ]?.['freshCoverage'] || COVERAGE_THRESHOLD } } else { return { @@ -259,7 +270,9 @@ export function getCoverageFromSarif(sarifPath: string): Coverage { totalCoveredLines: 0, freshCoverage: 0, freshLines: 0, - freshCoveredLines: 0 + freshCoveredLines: 0, + totalCoverageThreshold: COVERAGE_THRESHOLD, + freshCoverageThreshold: COVERAGE_THRESHOLD } } } diff --git a/scan/__tests__/data/some.sarif.json b/scan/__tests__/data/some.sarif.json index 38233785..296000c6 100644 --- a/scan/__tests__/data/some.sarif.json +++ b/scan/__tests__/data/some.sarif.json @@ -8258,10 +8258,16 @@ "\n" ], "properties": { + "qodanaFailureConditions": { + "testCoverageThresholds": { + "totalCoverage": 40, + "freshCoverage": 40 + } + }, "coverage": { - "totalCoverage": 70.0, + "totalCoverage": 45.0, "totalLines": 124.0, - "totalCoveredLines": 87.0 + "totalCoveredLines": 56.0 } } } diff --git a/scan/__tests__/main.test.ts b/scan/__tests__/main.test.ts index 599fe17e..3af13e4e 100644 --- a/scan/__tests__/main.test.ts +++ b/scan/__tests__/main.test.ts @@ -101,16 +101,14 @@ test('test empty summary output', () => { test('test passed coverage output', () => { const result = getCoverageStats( - getCoverageFromSarif('__tests__/data/some.sarif.json'), - 50 + getCoverageFromSarif('__tests__/data/some.sarif.json') ) expect(result).toEqual(passedCoverageFixture()) }) test('test failed coverage output', () => { const result = getCoverageStats( - getCoverageFromSarif('__tests__/data/empty.sarif.json'), - 50 + getCoverageFromSarif('__tests__/data/empty.sarif.json') ) expect(result).toEqual(failedCoverageFixture()) }) @@ -353,8 +351,8 @@ Contact us at [qodana-support@jetbrains.com](mailto:qodana-support@jetbrains.com function passedCoverageFixture(): string { return `\`\`\`diff @@ Code coverage @@ -+ 70% total lines covered -124 lines analyzed, 87 lines covered ++ 45% total lines covered +124 lines analyzed, 56 lines covered # Calculated according to the filters of your coverage tool \`\`\`` } diff --git a/scan/dist/index.js b/scan/dist/index.js index 3995b641..f6c8e0d0 100644 --- a/scan/dist/index.js +++ b/scan/dist/index.js @@ -34337,7 +34337,9 @@ function getCoverageFromSarif(sarifPath) { totalCoveredLines: sarifContents.runs[0].properties["coverage"]["totalCoveredLines"] || 0, freshCoverage: sarifContents.runs[0].properties["coverage"]["freshCoverage"] || 0, freshLines: sarifContents.runs[0].properties["coverage"]["freshLines"] || 0, - freshCoveredLines: sarifContents.runs[0].properties["coverage"]["freshCoveredLines"] || 0 + freshCoveredLines: sarifContents.runs[0].properties["coverage"]["freshCoveredLines"] || 0, + totalCoverageThreshold: sarifContents.runs[0].properties["qodanaFailureConditions"]?.["testCoverageThresholds"]?.["totalCoverage"] || COVERAGE_THRESHOLD, + freshCoverageThreshold: sarifContents.runs[0].properties["qodanaFailureConditions"]?.["testCoverageThresholds"]?.["freshCoverage"] || COVERAGE_THRESHOLD }; } else { return { @@ -34346,7 +34348,9 @@ function getCoverageFromSarif(sarifPath) { totalCoveredLines: 0, freshCoverage: 0, freshLines: 0, - freshCoveredLines: 0 + freshCoveredLines: 0, + totalCoverageThreshold: COVERAGE_THRESHOLD, + freshCoverageThreshold: COVERAGE_THRESHOLD }; } } @@ -134644,14 +134648,14 @@ ${message} \`\`\``; } __name(wrapToDiffBlock, "wrapToDiffBlock"); - function getCoverageStats(c, threshold) { + function getCoverageStats(c) { if (c.totalLines === 0 && c.totalCoveredLines === 0) { return ""; } let stats = ""; if (c.totalLines !== 0) { let conclusion = `${c.totalCoverage}% total lines covered`; - if (c.totalCoverage < threshold) { + if (c.totalCoverage < c.totalCoverageThreshold) { conclusion = `- ${conclusion}`; } else { conclusion = `+ ${conclusion}`; @@ -134698,7 +134702,7 @@ ${c.freshLines} lines analyzed, ${c.freshCoveredLines} lines covered`; try { const problems = (0, annotations_1.parseSarif)(`${resultsDir}/${qodana_12.QODANA_SARIF_NAME}`); const reportUrl = getReportURL(resultsDir); - const coverageInfo = getCoverageStats((0, qodana_12.getCoverageFromSarif)(`${resultsDir}/${qodana_12.QODANA_SHORT_SARIF_NAME}`), qodana_12.COVERAGE_THRESHOLD); + const coverageInfo = getCoverageStats((0, qodana_12.getCoverageFromSarif)(`${resultsDir}/${qodana_12.QODANA_SHORT_SARIF_NAME}`)); let licensesInfo = ""; let packages = 0; const licensesJson = `${resultsDir}/projectStructure/${qodana_12.QODANA_LICENSES_JSON}`; diff --git a/scan/src/output.ts b/scan/src/output.ts index a42db1fb..eb9006f5 100644 --- a/scan/src/output.ts +++ b/scan/src/output.ts @@ -19,7 +19,6 @@ import * as core from '@actions/core' import * as fs from 'fs' import { Coverage, - COVERAGE_THRESHOLD, getCoverageFromSarif, QODANA_LICENSES_JSON, QODANA_LICENSES_MD, @@ -77,7 +76,7 @@ ${message} \`\`\`` } -export function getCoverageStats(c: Coverage, threshold: number): string { +export function getCoverageStats(c: Coverage): string { if (c.totalLines === 0 && c.totalCoveredLines === 0) { return '' } @@ -85,7 +84,7 @@ export function getCoverageStats(c: Coverage, threshold: number): string { let stats = '' if (c.totalLines !== 0) { let conclusion = `${c.totalCoverage}% total lines covered` - if (c.totalCoverage < threshold) { + if (c.totalCoverage < c.totalCoverageThreshold) { conclusion = `- ${conclusion}` } else { conclusion = `+ ${conclusion}` @@ -153,8 +152,7 @@ export async function publishOutput( const problems = parseSarif(`${resultsDir}/${QODANA_SARIF_NAME}`) const reportUrl = getReportURL(resultsDir) const coverageInfo = getCoverageStats( - getCoverageFromSarif(`${resultsDir}/${QODANA_SHORT_SARIF_NAME}`), - COVERAGE_THRESHOLD + getCoverageFromSarif(`${resultsDir}/${QODANA_SHORT_SARIF_NAME}`) ) let licensesInfo = '' let packages = 0 diff --git a/vsts/QodanaScan/index.js b/vsts/QodanaScan/index.js index 12b0930b..0d3fb080 100644 --- a/vsts/QodanaScan/index.js +++ b/vsts/QodanaScan/index.js @@ -9899,6 +9899,7 @@ function getQodanaScanArgs(args, resultsDir, cacheDir) { return cliArgs; } function getCoverageFromSarif(sarifPath) { + var _a, _b, _c, _d; if (fs.existsSync(sarifPath)) { const sarifContents = JSON.parse( fs.readFileSync(sarifPath, { encoding: "utf8" }) @@ -9910,7 +9911,9 @@ function getCoverageFromSarif(sarifPath) { totalCoveredLines: sarifContents.runs[0].properties["coverage"]["totalCoveredLines"] || 0, freshCoverage: sarifContents.runs[0].properties["coverage"]["freshCoverage"] || 0, freshLines: sarifContents.runs[0].properties["coverage"]["freshLines"] || 0, - freshCoveredLines: sarifContents.runs[0].properties["coverage"]["freshCoveredLines"] || 0 + freshCoveredLines: sarifContents.runs[0].properties["coverage"]["freshCoveredLines"] || 0, + totalCoverageThreshold: ((_b = (_a = sarifContents.runs[0].properties["qodanaFailureConditions"]) == null ? void 0 : _a["testCoverageThresholds"]) == null ? void 0 : _b["totalCoverage"]) || COVERAGE_THRESHOLD, + freshCoverageThreshold: ((_d = (_c = sarifContents.runs[0].properties["qodanaFailureConditions"]) == null ? void 0 : _c["testCoverageThresholds"]) == null ? void 0 : _d["freshCoverage"]) || COVERAGE_THRESHOLD }; } else { return { @@ -9919,7 +9922,9 @@ function getCoverageFromSarif(sarifPath) { totalCoveredLines: 0, freshCoverage: 0, freshLines: 0, - freshCoveredLines: 0 + freshCoveredLines: 0, + totalCoverageThreshold: COVERAGE_THRESHOLD, + freshCoverageThreshold: COVERAGE_THRESHOLD }; } }