Skip to main content
Glama

jenkins_get_coverage_report

Retrieve code coverage reports from Jenkins builds to analyze test effectiveness and identify untested code areas for specific applications, packages, or classes.

Instructions

Obtener reporte de cobertura de código de un build

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
appYesNombre de la aplicación
buildNumberYesNúmero del build
packageNameNoNombre del paquete específico
classNameNoNombre de la clase específica
branchNoRama de Git (por defecto: main)

Implementation Reference

  • index.ts:253-303 (registration)
    Registration of the 'jenkins_get_coverage_report' MCP tool, including input schema (Zod), description, and the handler function that delegates to JenkinsService.getCoverageReport and formats the output.
    server.tool( "jenkins_get_coverage_report", "Obtener reporte de cobertura de código de un build", { app: z.string().describe("Nombre de la aplicación"), buildNumber: z.number().describe("Número del build"), packageName: z.string().optional().describe("Nombre del paquete específico"), className: z.string().optional().describe("Nombre de la clase específica"), branch: z.string().optional().describe("Rama de Git (por defecto: main)") }, async (args) => { try { const result = await getJenkinsService().getCoverageReport( args.app, args.buildNumber, args.packageName, args.className, args.branch || 'main' ); let coverageText: string; if ('instructionCoverage' in result) { // Es un CoverageReport (backend) coverageText = `📊 **Reporte de Cobertura - Build #${args.buildNumber}**\n\n` + `**Instrucciones:** ${result.instructionCoverage?.percentage || 0}% (${result.instructionCoverage?.covered || 0}/${result.instructionCoverage?.total || 0})\n` + `**Ramas:** ${result.branchCoverage?.percentage || 0}% (${result.branchCoverage?.covered || 0}/${result.branchCoverage?.total || 0})\n` + `**Líneas:** ${result.lineCoverage?.percentage || 0}% (${result.lineCoverage?.covered || 0}/${result.lineCoverage?.total || 0})`; } else { // Es un CoverageSummary (frontend) const summary = result as CoverageSummary; const stmtPercent = summary.statements > 0 ? ((summary.statements - summary.uncoveredStatements) / summary.statements * 100).toFixed(2) : 0; const funcPercent = summary.functions > 0 ? ((summary.functions - summary.uncoveredFunctions) / summary.functions * 100).toFixed(2) : 0; const branchPercent = summary.branches > 0 ? ((summary.branches - summary.uncoveredBranches) / summary.branches * 100).toFixed(2) : 0; coverageText = `📊 **Resumen de Cobertura - Build #${args.buildNumber}**\n\n` + `**Declaraciones:** ${stmtPercent}% (${summary.statements - summary.uncoveredStatements}/${summary.statements})\n` + `**Funciones:** ${funcPercent}% (${summary.functions - summary.uncoveredFunctions}/${summary.functions})\n` + `**Ramas:** ${branchPercent}% (${summary.branches - summary.uncoveredBranches}/${summary.branches})`; } return { content: [{ type: "text", text: coverageText }], }; } catch (error: any) { return { content: [{ type: "text", text: `❌ **Error:** ${error.message}` }], }; } } );
  • Core implementation of coverage report fetching in JenkinsService: attempts JaCoCo backend first, falls back to frontend coverage report, computes summaries based on parameters.
    async getCoverageReport(app: string, buildNumber: number, packageName?: string, className?: string, branch: string = 'main'): Promise<CoverageReport | CoverageSummary> { if (!validateAppName(app)) { throw new Error('Invalid app name.'); } // Primero intentar con backend (jacoco) try { const backendUrl = `${buildJobBuildUrl('', app, buildNumber, branch)}/jacoco/jacoco.exec`; await this.client.get(backendUrl); // Si existe, procesar reporte backend return await this.getCoverageReportBackend(app, buildNumber, branch); } catch (error: any) { // Si falla, intentar con frontend coverage try { const frontendReport = await this.getCoverageReportFrontend(app, buildNumber, branch); if (packageName) { return this.calculatePackageSummary(frontendReport, packageName, className); } else if (className) { return this.calculateClassSummary(frontendReport, className); } else { return this.calculateTotalSummary(frontendReport); } } catch (frontendError: any) { throw handleHttpError(frontendError, `Failed to get coverage report for app: ${app}, build: ${buildNumber}, branch: ${branch}`); } } }
  • Helper function to compute total coverage summary from frontend coverage report data.
    private calculateTotalSummary(report: CoverageReportFront): CoverageSummary { const summary: CoverageSummary = { statements: 0, functions: 0, branches: 0, uncoveredStatements: 0, uncoveredFunctions: 0, uncoveredBranches: 0 }; Object.values(report.files).forEach(file => { summary.statements += Object.keys(file.statementMap).length; summary.functions += Object.keys(file.fnMap).length; summary.branches += Object.keys(file.branchMap).length; // Calcular no cubiertos summary.uncoveredStatements += Object.values(file.s).filter(v => v === 0).length; summary.uncoveredFunctions += Object.values(file.f).filter(v => v === 0).length; summary.uncoveredBranches += Object.values(file.b).flat().filter(v => v === 0).length; }); return summary; }
  • TypeScript interfaces for CoverageSummary and CoverageReport used in the tool's input/output handling.
    export interface CoverageSummary { statements: number; functions: number; branches: number; uncoveredStatements: number; uncoveredFunctions: number; uncoveredBranches: number; }
  • Helper to fetch and process JaCoCo backend coverage report (currently returns placeholder).
    private async getCoverageReportBackend(app: string, buildNumber: number, branch: string = 'main'): Promise<CoverageReport> { const jacocoUrl = `${buildJobBuildUrl('', app, buildNumber, branch)}/jacoco/jacoco.exec`; const response = await this.client.get(jacocoUrl, { responseType: 'arraybuffer' }); // Aquí deberías procesar el archivo jacoco.exec // Por simplicidad, devolvemos un reporte básico return { instructionCoverage: { covered: 0, missed: 0, percentage: 0, total: 0 }, branchCoverage: { covered: 0, missed: 0, percentage: 0, total: 0 }, lineCoverage: { covered: 0, missed: 0, percentage: 0, total: 0 } }; }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/gcorroto/mcp-jenkins'

If you have feedback or need assistance with the MCP directory API, please join our Discord server