Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
52 changes: 44 additions & 8 deletions common/__tests__/main.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,36 @@ import * as fs from 'fs'
import * as path from 'path'
import * as os from 'os'

test('test passed coverage output', () => {
test('test passed coverage output using diff', () => {
const result = getCoverageStats(
getCoverageFromSarif('__tests__/data/some.sarif.json')
getCoverageFromSarif('__tests__/data/some.sarif.json'),
true
)
expect(result).toEqual(passedCoverageFixture())
expect(result).toEqual(passedCoverageFixtureDiff())
})

test('test failed coverage output', () => {
test('test failed coverage output using diff', () => {
const result = getCoverageStats(
getCoverageFromSarif('__tests__/data/empty.sarif.json')
getCoverageFromSarif('__tests__/data/empty.sarif.json'),
true
)
expect(result).toEqual(failedCoverageFixture())
expect(result).toEqual(failedCoverageFixtureDiff())
})

test('test passed coverage output using spam', () => {
const result = getCoverageStats(
getCoverageFromSarif('__tests__/data/some.sarif.json'),
false
)
expect(result).toEqual(passedCoverageFixtureSpam())
})

test('test failed coverage output using spam', () => {
const result = getCoverageStats(
getCoverageFromSarif('__tests__/data/empty.sarif.json'),
false
)
expect(result).toEqual(failedCoverageFixtureSpam())
})

describe('getReportURL', () => {
Expand Down Expand Up @@ -90,7 +108,25 @@ describe('getReportURL', () => {
})
})

function passedCoverageFixture(): string {
function passedCoverageFixtureSpam(): string {
return `@@ Code coverage @@
<span style="background-color: #e6f4e6; color: green;">45% total lines covered</span>
124 lines analyzed, 56 lines covered
<span style="background-color: #e6f4e6; color: green;">33% fresh lines covered</span>
9 lines analyzed, 3 lines covered
# Calculated according to the filters of your coverage tool`
}

function failedCoverageFixtureSpam(): string {
return `@@ Code coverage @@
<span style="background-color: #ffe6e6; color: red;">0% total lines covered</span>
100 lines analyzed, 0 lines covered
<span style="background-color: #ffe6e6; color: red;">0% fresh lines covered</span>
100 lines analyzed, 0 lines covered
# Calculated according to the filters of your coverage tool`
}

function passedCoverageFixtureDiff(): string {
return `\`\`\`diff
@@ Code coverage @@
+ 45% total lines covered
Expand All @@ -101,7 +137,7 @@ function passedCoverageFixture(): string {
\`\`\``
}

function failedCoverageFixture(): string {
function failedCoverageFixtureDiff(): string {
return `\`\`\`diff
@@ Code coverage @@
- 0% total lines covered
Expand Down
30 changes: 16 additions & 14 deletions common/output.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,41 +99,43 @@ ${message}

function makeConclusion(
conclusion: string,
failedByThreshold: boolean
failedByThreshold: boolean,
useDiffBlock: boolean,
): string {
if (failedByThreshold) {
return `- ${conclusion}`
if (useDiffBlock) {
return failedByThreshold ? `- ${conclusion}` : `+ ${conclusion}`
} else {
return `+ ${conclusion}`
return failedByThreshold
? `<span style="background-color: #ffe6e6; color: red;">${conclusion}</span>`
: `<span style="background-color: #e6f4e6; color: green;">${conclusion}</span>`
}
}

export function getCoverageStats(c: Coverage): string {
export function getCoverageStats(c: Coverage, useDiffBlock: boolean): string {
if (c.totalLines === 0 && c.totalCoveredLines === 0) {
return ''
}

let stats = ''
if (c.totalLines !== 0) {
const conclusion = `${c.totalCoverage}% total lines covered`
stats += `${makeConclusion(conclusion, c.totalCoverage < c.totalCoverageThreshold)}
stats += `${makeConclusion(conclusion, c.totalCoverage < c.totalCoverageThreshold, useDiffBlock)}
${c.totalLines} lines analyzed, ${c.totalCoveredLines} lines covered`
}

if (c.freshLines !== 0) {
const conclusion = `${c.freshCoverage}% fresh lines covered`
stats += `
${makeConclusion(conclusion, c.freshCoverage < c.freshCoverageThreshold)}
${makeConclusion(conclusion, c.freshCoverage < c.freshCoverageThreshold, useDiffBlock)}
${c.freshLines} lines analyzed, ${c.freshCoveredLines} lines covered`
}

return wrapToDiffBlock(
[
`@@ Code coverage @@`,
`${stats}`,
`# Calculated according to the filters of your coverage tool`
].join('\n')
)
const coverageBlock = [
`@@ Code coverage @@`,
`${stats}`,
`# Calculated according to the filters of your coverage tool`
].join('\n')
return useDiffBlock ? wrapToDiffBlock(coverageBlock) : coverageBlock
}

export function getLicenseInfo(
Expand Down
29 changes: 14 additions & 15 deletions scan/dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -137016,36 +137016,35 @@ function wrapToDiffBlock(message) {
${message}
\`\`\``;
}
function makeConclusion(conclusion, failedByThreshold) {
if (failedByThreshold) {
return `- ${conclusion}`;
function makeConclusion(conclusion, failedByThreshold, useDiffBlock) {
if (useDiffBlock) {
return failedByThreshold ? `- ${conclusion}` : `+ ${conclusion}`;
} else {
return `+ ${conclusion}`;
return failedByThreshold ? `<span style="background-color: #ffe6e6; color: red;">${conclusion}</span>` : `<span style="background-color: #e6f4e6; color: green;">${conclusion}</span>`;
}
}
function getCoverageStats(c) {
function getCoverageStats(c, useDiffBlock) {
if (c.totalLines === 0 && c.totalCoveredLines === 0) {
return "";
}
let stats = "";
if (c.totalLines !== 0) {
const conclusion = `${c.totalCoverage}% total lines covered`;
stats += `${makeConclusion(conclusion, c.totalCoverage < c.totalCoverageThreshold)}
stats += `${makeConclusion(conclusion, c.totalCoverage < c.totalCoverageThreshold, useDiffBlock)}
${c.totalLines} lines analyzed, ${c.totalCoveredLines} lines covered`;
}
if (c.freshLines !== 0) {
const conclusion = `${c.freshCoverage}% fresh lines covered`;
stats += `
${makeConclusion(conclusion, c.freshCoverage < c.freshCoverageThreshold)}
${makeConclusion(conclusion, c.freshCoverage < c.freshCoverageThreshold, useDiffBlock)}
${c.freshLines} lines analyzed, ${c.freshCoveredLines} lines covered`;
}
return wrapToDiffBlock(
[
`@@ Code coverage @@`,
`${stats}`,
`# Calculated according to the filters of your coverage tool`
].join("\n")
);
const coverageBlock = [
`@@ Code coverage @@`,
`${stats}`,
`# Calculated according to the filters of your coverage tool`
].join("\n");
return useDiffBlock ? wrapToDiffBlock(coverageBlock) : coverageBlock;
}
function getLicenseInfo(resultsDir) {
let licensesInfo = "";
Expand Down Expand Up @@ -137558,7 +137557,7 @@ so that the action will upload the files as the job artifacts:
try {
const problems = (0, annotations_1.parseSarif)(`${resultsDir}/${qodana_12.QODANA_SARIF_NAME}`);
const reportUrl = (0, output_12.getReportURL)(resultsDir);
const coverageInfo = (0, output_12.getCoverageStats)((0, qodana_12.getCoverageFromSarif)(`${resultsDir}/${qodana_12.QODANA_SHORT_SARIF_NAME}`));
const coverageInfo = (0, output_12.getCoverageStats)((0, qodana_12.getCoverageFromSarif)(`${resultsDir}/${qodana_12.QODANA_SHORT_SARIF_NAME}`), true);
const licensesInfo = (0, output_12.getLicenseInfo)(resultsDir);
const problemsDescriptions = annotationsToProblemDescriptors(problems.annotations);
const toolName = (_a = problems.title.split("found by ")[1]) !== null && _a !== void 0 ? _a : output_12.QODANA_CHECK_NAME;
Expand Down
3 changes: 2 additions & 1 deletion scan/src/output.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,8 @@ export async function publishOutput(
const problems = parseSarif(`${resultsDir}/${QODANA_SARIF_NAME}`)
const reportUrl = getReportURL(resultsDir)
const coverageInfo = getCoverageStats(
getCoverageFromSarif(`${resultsDir}/${QODANA_SHORT_SARIF_NAME}`)
getCoverageFromSarif(`${resultsDir}/${QODANA_SHORT_SARIF_NAME}`),
true
)

const licensesInfo: LicenseInfo = getLicenseInfo(resultsDir)
Expand Down
45 changes: 20 additions & 25 deletions vsts/QodanaScan/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16877,36 +16877,35 @@ function wrapToDiffBlock(message) {
${message}
\`\`\``;
}
function makeConclusion(conclusion, failedByThreshold) {
if (failedByThreshold) {
return `- ${conclusion}`;
function makeConclusion(conclusion, failedByThreshold, useDiffBlock) {
if (useDiffBlock) {
return failedByThreshold ? `- ${conclusion}` : `+ ${conclusion}`;
} else {
return `+ ${conclusion}`;
return failedByThreshold ? `<span style="background-color: #ffe6e6; color: red;">${conclusion}</span>` : `<span style="background-color: #e6f4e6; color: green;">${conclusion}</span>`;
}
}
function getCoverageStats(c) {
function getCoverageStats(c, useDiffBlock) {
if (c.totalLines === 0 && c.totalCoveredLines === 0) {
return "";
}
let stats = "";
if (c.totalLines !== 0) {
const conclusion = `${c.totalCoverage}% total lines covered`;
stats += `${makeConclusion(conclusion, c.totalCoverage < c.totalCoverageThreshold)}
stats += `${makeConclusion(conclusion, c.totalCoverage < c.totalCoverageThreshold, useDiffBlock)}
${c.totalLines} lines analyzed, ${c.totalCoveredLines} lines covered`;
}
if (c.freshLines !== 0) {
const conclusion = `${c.freshCoverage}% fresh lines covered`;
stats += `
${makeConclusion(conclusion, c.freshCoverage < c.freshCoverageThreshold)}
${makeConclusion(conclusion, c.freshCoverage < c.freshCoverageThreshold, useDiffBlock)}
${c.freshLines} lines analyzed, ${c.freshCoveredLines} lines covered`;
}
return wrapToDiffBlock(
[
`@@ Code coverage @@`,
`${stats}`,
`# Calculated according to the filters of your coverage tool`
].join("\n")
);
const coverageBlock = [
`@@ Code coverage @@`,
`${stats}`,
`# Calculated according to the filters of your coverage tool`
].join("\n");
return useDiffBlock ? wrapToDiffBlock(coverageBlock) : coverageBlock;
}
function getLicenseInfo(resultsDir) {
let licensesInfo = "";
Expand Down Expand Up @@ -79048,7 +79047,7 @@ so that the action will upload the files as the job artifacts:
try {
const problems = (0, utils_12.parseSarif)(`${resultsDir}/${qodana_12.QODANA_SARIF_NAME}`);
const reportUrl = (0, output_12.getReportURL)(resultsDir);
const coverageInfo = (0, output_12.getCoverageStats)((0, qodana_12.getCoverageFromSarif)(`${resultsDir}/${qodana_12.QODANA_SHORT_SARIF_NAME}`));
const coverageInfo = (0, output_12.getCoverageStats)((0, qodana_12.getCoverageFromSarif)(`${resultsDir}/${qodana_12.QODANA_SHORT_SARIF_NAME}`), false);
const licensesInfo = (0, output_12.getLicenseInfo)(resultsDir);
const problemsDescriptions = (_a = problems.problemDescriptions) !== null && _a !== void 0 ? _a : [];
const toolName = (_b = problems.title.split("found by ")[1]) !== null && _b !== void 0 ? _b : output_12.QODANA_CHECK_NAME;
Expand Down Expand Up @@ -79185,10 +79184,10 @@ var require_utils4 = __commonJS({
uploadSarif: tl2.getBoolInput("uploadSarif", false),
artifactName: tl2.getInput("artifactName", false) || "qodana-report",
useNightly: tl2.getBoolInput("useNightly", false),
prMode: tl2.getBoolInput("prMode", true),
prMode: tl2.getBoolInput("prMode", false),
postComment: tl2.getBoolInput("postPrComment", false),
pushFixes: tl2.getInput("pushFixes", false) || "none",
commitMessage: tl2.getInput("commitMessage", false) || "\u{1F916} Apply quick-fixes by Qodana",
commitMessage: tl2.getInput("commitMessage", false) || "\u{1F916} Apply quick-fixes by Qodana \n\n[skip ci]",
// Not used by the Azure task
additionalCacheKey: "",
primaryCacheKey: "",
Expand Down Expand Up @@ -79466,11 +79465,9 @@ ${comment_tag_pattern}`;
return;
}
if (mode === qodana_12.BRANCH) {
if (pullRequest) {
const commitToCherryPick = (yield gitOutput(["rev-parse", "HEAD"])).stdout.trim();
yield git(["checkout", currentBranch]);
yield git(["cherry-pick", commitToCherryPick]);
}
const commitToCherryPick = (yield gitOutput(["rev-parse", "HEAD"])).stdout.trim();
yield git(["checkout", currentBranch]);
yield git(["cherry-pick", commitToCherryPick]);
yield gitPush(currentBranch);
} else if (mode === qodana_12.PULL_REQUEST) {
const newBranch = `qodana/quick-fixes-${currentCommit.slice(0, 7)}`;
Expand All @@ -79488,9 +79485,7 @@ ${comment_tag_pattern}`;
const output = yield gitOutput(["push", "origin", branch], {
ignoreReturnCode: true
});
if (output.exitCode == 1) {
tl2.warning(`Branch ${branch} already exists. Push of quick-fixes was skipped.`);
} else if (output.exitCode !== 0) {
if (output.exitCode !== 0) {
tl2.warning(`Failed to push branch ${branch}: ${output.stderr}`);
}
});
Expand Down
26 changes: 25 additions & 1 deletion vsts/QodanaScan/task.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,33 @@
"name": "prMode",
"type": "boolean",
"label": "PR Mode",
"defaultValue": false,
"defaultValue": true,
"required": false,
"helpMarkDown": "Whether the PR analysis gets executed in the pull request mode."
},
{
"name": "postPrComment",
"type": "boolean",
"label": "Post PR comment",
"defaultValue": true,
"required": false,
"helpMarkDown": "Post a comment with the Qodana results summary to the pull request."
},
{
"name": "pushFixes",
"type": "string",
"label": "Push quick-fixes",
"defaultValue": "none",
"required": false,
"helpMarkDown": "Push Qodana fixes to the repository, can be `none`, `branch` to the current branch, or `pull-request`."
},
{
"name": "commitMessage",
"type": "string",
"label": "Commit Message",
"defaultValue": "\uD83E\uDD16 Apply quick-fixes by Qodana\n\n[skip ci]",
"required": false,
"helpMarkDown": "Message used when quick-fixes are pushed"
}
],
"execution": {
Expand Down
2 changes: 1 addition & 1 deletion vsts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ to
- or `branch`: push fixes to the original branch
3. Set the correct permissions for the job. Go to `Repositories` → `Manage repositories` → `Security`. Choose `Qodana for Azure Pipelines Build Service` user. Allow:
- `Contribute`
- `Bypass policies when pushing`. Without this, the analysis will be performed twice
- `Bypass policies when pushing` if they may fail the push of quick-fixes
- `Create branch` if you use `pull-request` value

Also, set `persistCredentials` property to `true`. This is needed for pushing changes to the repository
Expand Down
3 changes: 2 additions & 1 deletion vsts/src/output.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ export async function publishOutput(
const problems = parseSarif(`${resultsDir}/${QODANA_SARIF_NAME}`)
const reportUrl = getReportURL(resultsDir)
const coverageInfo = getCoverageStats(
getCoverageFromSarif(`${resultsDir}/${QODANA_SHORT_SARIF_NAME}`)
getCoverageFromSarif(`${resultsDir}/${QODANA_SHORT_SARIF_NAME}`),
false
)

const licensesInfo = getLicenseInfo(resultsDir)
Expand Down
Loading
Loading