@zooshdigital/bitbucket-v8-coverage-report
Version:
Command-line tool to upload coverage reports to Bitbucket
151 lines (148 loc) • 7.7 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const promises_1 = __importDefault(require("fs/promises"));
const command_line_args_1 = __importDefault(require("command-line-args"));
const junit2json_1 = require("junit2json");
const bitbucket_code_insights_1 = require("@zooshdigital/bitbucket-code-insights");
const logger_1 = require("./utils/logger");
const optionDefinitions = [
{ name: 'name', alias: 'n', type: String },
{ name: 'path', alias: 'p', type: String },
{ name: 'min-coverage', alias: 'c', type: Number },
{ name: 'min-lines-coverage', alias: 'l', type: Number },
{ name: 'min-statements-coverage', alias: 's', type: Number },
{ name: 'min-functions-coverage', alias: 'f', type: Number },
{ name: 'min-branches-coverage', alias: 'b', type: Number },
{ name: 'add-build', alias: 'a', type: Boolean },
{ name: 'junit-path', alias: 'j', type: String },
{ name: 'failed-test-comment', alias: 't', type: Boolean },
];
const args = (0, command_line_args_1.default)(optionDefinitions);
const logger = (0, logger_1.createLogger)('Zoosh Bitbucket v8 Coverage Report');
function getReportResult(coverageResult, minCoverage, averageCoverage, minAverageCoverage) {
const failedThreshold = Object.keys(minCoverage).some((key) => {
var _a;
const coverageType = key;
return coverageResult[coverageType] < ((_a = minCoverage[coverageType]) !== null && _a !== void 0 ? _a : 0);
});
if (failedThreshold) {
return false;
}
if (averageCoverage < (minAverageCoverage !== null && minAverageCoverage !== void 0 ? minAverageCoverage : 0)) {
return false;
}
return true;
}
const getTestFailureText = (testCase) => {
var _a, _b;
return (_b = (_a = testCase.failure) === null || _a === void 0 ? void 0 : _a.map((failure) => `\`\`\`
${failure.inner}
\`\`\`
`).join('\n')) !== null && _b !== void 0 ? _b : '';
};
const getTestCaseText = (testCase) => `## ${testCase.name}
${getTestFailureText(testCase)}`;
const getTestCasesText = (testCases) => `# ${testCases.length} test case(s) failed!
${testCases.map(getTestCaseText).join('\n\n')}`;
function uploadReport() {
var _a, _b;
return __awaiter(this, void 0, void 0, function* () {
try {
const { name, path: reportPath, 'min-coverage': minAverageCoverage, 'min-lines-coverage': minLinesCoverage, 'min-statements-coverage': minStatementsCoverage, 'min-functions-coverage': minFunctionsCoverage, 'min-branches-coverage': minBranchesCoverage, 'add-build': addBuild, 'junit-path': junitPath, 'failed-test-comment': failedTestComment, } = args;
if (!name || !reportPath) {
throw new Error('Bitbucket v8 Coverage Report - Usage: bitbucket-v8-coverage-report -n <report-name> -p <report-path>');
}
const coverageResults = JSON.parse(yield promises_1.default.readFile(reportPath, 'utf8'));
const coverageResultPercentage = {
statements: coverageResults.total.statements.pct,
lines: coverageResults.total.lines.pct,
functions: coverageResults.total.functions.pct,
branches: coverageResults.total.branches.pct,
};
const coverageValues = Object.values(coverageResultPercentage);
const averageCoverage = coverageValues.length
? Math.round(coverageValues.reduce((acc, val) => acc + val, 0) / coverageValues.length)
: 0;
const passed = getReportResult(coverageResultPercentage, {
statements: minStatementsCoverage,
lines: minLinesCoverage,
functions: minFunctionsCoverage,
branches: minBranchesCoverage,
}, averageCoverage, minAverageCoverage);
const body = {
title: `${name} (average ${averageCoverage}%)`,
report_type: 'COVERAGE',
details: `${name} report`,
result: passed ? 'PASSED' : 'FAILED',
data: [
{
title: 'Lines',
type: 'PERCENTAGE',
value: coverageResultPercentage.lines,
},
{
title: 'Statements',
type: 'PERCENTAGE',
value: coverageResultPercentage.statements,
},
{
title: 'Functions',
type: 'PERCENTAGE',
value: coverageResultPercentage.functions,
},
{
title: 'Branches',
type: 'PERCENTAGE',
value: coverageResultPercentage.branches,
},
],
};
yield (0, bitbucket_code_insights_1.uploadReportToBitbucket)(name, body);
if (addBuild) {
const url = process.env.BITBUCKET_PR_ID
? `https://bitbucket.org/${process.env.BITBUCKET_REPO_FULL_NAME}/pull-requests/${process.env.BITBUCKET_PR_ID}/overview`
: `https://bitbucket.org/${process.env.BITBUCKET_REPO_FULL_NAME}/commit/${process.env.BITBUCKET_COMMIT}`;
yield (0, bitbucket_code_insights_1.createBuildOnBitbucket)({
key: name,
state: passed ? 'SUCCESSFUL' : 'FAILED',
name,
description: `Average: ${averageCoverage}%`,
url,
});
}
if (failedTestComment && junitPath) {
const jUnitResult = (yield (0, junit2json_1.parse)(yield promises_1.default.readFile(junitPath, 'utf8')));
if (jUnitResult) {
const failedTestCases = (_b = (_a = jUnitResult.testsuite) === null || _a === void 0 ? void 0 : _a.flatMap((testSuite) => { var _a, _b; return (_b = (_a = testSuite.testcase) === null || _a === void 0 ? void 0 : _a.filter((testCase) => !!testCase.failure)) !== null && _b !== void 0 ? _b : []; })) !== null && _b !== void 0 ? _b : [];
if (failedTestCases.length) {
const comment = getTestCasesText(failedTestCases);
yield (0, bitbucket_code_insights_1.createCommentOnBitbucket)({
content: {
raw: comment,
},
});
}
}
}
logger.log('Report uploaded successfully', name);
}
catch (error) {
logger.log(`Error uploading report: ${error}`);
process.exit(1);
}
});
}
uploadReport();