Skip to content

Add Cobertura support - #31

Open
mattgek wants to merge 3 commits into
mainfrom
add-cobertura
Open

mattgek wants to merge 3 commits into
mainfrom
add-cobertura

Conversation

@mattgek

@mattgek mattgek commented Sep 16, 2026

Copy link
Copy Markdown
Collaborator

No description provided.

Signed-off-by: matthiasgekiere <matthias.gekiere@codekt.be>
Comment thread src/merge.js Outdated
Comment thread src/formats/cobertura.js Outdated
Comment thread src/merge.js Outdated
Comment thread src/main.js Outdated
Comment thread src/formats/cobertura.js Outdated
Comment thread src/formats/cobertura.js Outdated
Comment thread src/formats/cobertura.js Outdated
Comment thread src/inputs.js
Comment on lines 5 to +7
*/
export function readInputs() {
const lcovFilePathsInput = core.getInput('lcov-file-paths', {
const filePathsInput = core.getInput('file-paths', {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Medium - Existing LCOV workflows fail because the input contract was renamed and made stricter

The action no longer reads the previously documented lcov-file-paths input and now requires a new file-paths input plus a required format value. A workflow that upgrades from the prior action without changing its configuration therefore fails in core.getInput before it can read or upload its existing LCOV report, making this additive format-support change a breaking runtime regression for all existing consumers.

Show fix

Keep lcov-file-paths as a backward-compatible alias and default the format to lcov when the legacy input is used (or otherwise provide a compatibility migration path); do not make existing LCOV workflows fail solely because they have not opted into Cobertura.

More info - Reply on this comment to give feedback or ignore the issue.

Signed-off-by: matthiasgekiere <matthias.gekiere@codekt.be>
Signed-off-by: matthiasgekiere <matthias.gekiere@codekt.be>
Comment thread src/reportPaths.js
Comment on lines +47 to +54
function extractCoberturaFilenames(content, repositoryRoot) {
const paths = [];
for (const match of content.matchAll(/\bfilename\s*=\s*"([^"]+)"/gi)) {
const normalized = normalizeSourcePath(match[1], repositoryRoot);
if (normalized) {
paths.push(normalized);
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Medium - Cobertura EOF metadata ignores source roots and valid quote styles

The new Cobertura path extractor scans only double-quoted filename attributes and never reads the report's <sources> elements. A valid report using filename='a.js' produces no EOF entry, while one using <source>src</source> with filename="a.js" produces an a.js key instead of src/a.js; because the original report is uploaded unchanged, the backend's EOF lookup cannot match these covered files and can retain coverage past end-of-file.

Show fix

Parse Cobertura XML rather than using a double-quote-only regex, resolve each relative filename against its <source> roots, and use the same canonical repository-relative path when building the EOF map.

More info - Reply on this comment to give feedback or ignore the issue.

Comment thread src/reportPaths.js
Comment on lines +12 to +17
if (base.endsWith('.lcov') || base.endsWith('.info') || base.includes('lcov')) {
return 'lcov';
}

if (base.endsWith('.xml') || base.includes('cobertura')) {
return 'cobertura';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Medium - Removing the format override breaks nonstandard coverage filenames

The follow-up removes the explicit format input and now classifies every report only from its basename: arbitrary names such as report.dat are rejected, while a valid Cobertura report named lcov.xml is classified as LCOV because the includes('lcov') test runs before the .xml test. Workflows that previously supplied format: lcov or format: cobertura for such files therefore fail before upload or send the report with the wrong format.

Show fix

Retain the format input as an optional override for backwards compatibility, or detect the format from report content and only use the filename heuristic as a fallback; ensure .xml files containing lcov in their name are not misclassified.

More info - Reply on this comment to give feedback or ignore the issue.

Comment on lines +21 to +27
const project = await loadProjectFiles();
if (!project || project.files.length === 0) {
throw new Error(
'No source files found in this repository. ' +
'Check out the repository in this job (e.g. actions/checkout) before uploading coverage.',
);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Medium - Artifact-only uploads now fail without a checked-out source tree

collectUploadPayload now requires loadProjectFiles() to return at least one source file before it reads or uploads any report. This breaks the previously supported pattern of downloading coverage artifacts in an upload-only job without running checkout, and the standalone Cobertura and mixed-report examples still omit checkout even though following them now ends with No source files found.

Suggested change
const project = await loadProjectFiles();
if (!project || project.files.length === 0) {
throw new Error(
'No source files found in this repository. ' +
'Check out the repository in this job (e.g. actions/checkout) before uploading coverage.',
);
}
const project = (await loadProjectFiles()) ?? { root: process.cwd(), files: [] };

More info - Reply on this comment to give feedback or ignore the issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant