UNPKG

@zooshdigital/bitbucket-v8-coverage-report

Version:

Command-line tool to upload coverage reports to Bitbucket

151 lines (148 loc) 7.7 kB
#!/usr/bin/env node "use strict"; 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();