From 0c53b6c9d8167a68d0bcd49ac6a452324a7503c0 Mon Sep 17 00:00:00 2001 From: Pradeep Tammali Date: Fri, 31 Jul 2026 21:49:46 +0200 Subject: [PATCH 1/3] refactor: render coverage tables as GitHub Flavoured Markdown Convert the HTML coverage tables to GFM while keeping badges, tooltips, and column padding, and share the PR and project table markup through macros. --- README.md | 1 + codecov/template_files/comment.md.j2 | 2 +- codecov/template_files/macros.md.j2 | 113 ++++++++++++----- codecov/template_files/pr.md.j2 | 181 +-------------------------- codecov/template_files/project.md.j2 | 165 +----------------------- pyproject.toml | 2 +- tests/test_template.py | 43 ++++++- 7 files changed, 129 insertions(+), 378 deletions(-) diff --git a/README.md b/README.md index c5a61a8..dd626b8 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,7 @@ Note: Either `GITHUB_PR_NUMBER` or `GITHUB_REF` is required. `GITHUB_PR_NUMBER` - `SKIP_COVERED_FILES_IN_REPORT`: Skip the files with coverage 100% from the report. Default is True. - `COMPLETE_PROJECT_REPORT`: Whether to include the complete project coverage report in the comment. Default is False. - `COVERAGE_REPORT_URL`: URL of the full coverage report to mention in the comment. +- `LABEL`: Optional text rendered in the comment footer. Default is unset (no footer). - `DEBUG`: Whether to enable debug mode. Default is False. ## Notes diff --git a/codecov/template_files/comment.md.j2 b/codecov/template_files/comment.md.j2 index d6af8c4..5ad84c2 100644 --- a/codecov/template_files/comment.md.j2 +++ b/codecov/template_files/comment.md.j2 @@ -41,7 +41,7 @@ {%- block footer %} {% if label %} - This report was generated by {{ label }} + {{ label }} {% endif %} {% endblock footer -%} diff --git a/codecov/template_files/macros.md.j2 b/codecov/template_files/macros.md.j2 index 20122b1..4a36cc9 100644 --- a/codecov/template_files/macros.md.j2 +++ b/codecov/template_files/macros.md.j2 @@ -1,33 +1,35 @@ +{#- + Every badge cell is a shields.io image, linked to the file and carrying a + sentence as its tooltip, so the wrapper is factored out into `badge`. Cells + no longer carry their own : in a GitHub Flavoured + Markdown table the alignment belongs to the delimiter row of the table. +-#} +{%- macro badge(path, text, label, message, color, base=false) -%} +[![]({{ label | generate_badge(message=message, color=color) }} "{{ text }}")]({{ path | file_url(base=base) }}) +{%- endmacro -%} + {%- macro statements_badge(path, statements_count, base=false) -%} - {% set text = "The " ~ path ~ " contains " ~ statements_count ~ " statement" ~ (statements_count | pluralize) ~"." -%} - {% set color = "007ec6" -%} - + {%- set text = "The " ~ path ~ " contains " ~ statements_count ~ " statement" ~ (statements_count | pluralize) ~"." -%} + {%- set color = "007ec6" -%} + {{- badge(path, text, "", statements_count | string, color, base) -}} {%- endmacro -%} {%- macro branches_badge(path, branches_count, base=false) -%} - {% set text = "The " ~ path ~ " contains " ~ branches_count ~ " branch" ~ (branches_count | pluralize(plural='es')) ~"." -%} - {% set color = "008080" -%} - + {%- set text = "The " ~ path ~ " contains " ~ branches_count ~ " branch" ~ (branches_count | pluralize(plural='es')) ~"." -%} + {%- set color = "008080" -%} + {{- badge(path, text, "", branches_count | string, color, base) -}} {%- endmacro -%} {%- macro missing_branches_badge(path, missing_branches_count, base=false) -%} {%- set text = missing_branches_count ~ " branch" ~ (missing_branches_count | pluralize(plural='es')) ~ " missing the coverage in " ~ path ~ "." -%} - {% if missing_branches_count == 0 -%} - {%- set color = "brightgreen" -%} - {% else -%} - {%- set color = "red" -%} - {% endif -%} - + {%- set color = "brightgreen" if missing_branches_count == 0 else "red" -%} + {{- badge(path, text, "", missing_branches_count | string, color, base) -}} {%- endmacro -%} {%- macro missing_lines_badge(path, missing_lines_count, base=false) -%} - {%- set text = missing_lines_count ~ " statement" ~ (statements_count | pluralize) ~ " missing the coverage in " ~ path ~ "." -%} - {% if missing_lines_count == 0 -%} - {%- set color = "brightgreen" -%} - {% else -%} - {%- set color = "red" -%} - {% endif -%} - + {%- set text = missing_lines_count ~ " statement" ~ (missing_lines_count | pluralize) ~ " missing the coverage in " ~ path ~ "." -%} + {%- set color = "brightgreen" if missing_lines_count == 0 else "red" -%} + {{- badge(path, text, "", missing_lines_count | string, color, base) -}} {%- endmacro -%} {%- macro coverage_rate_badge(path, percent_covered, percent_covered_display, covered_statements_count, statements_count, base=false) -%} @@ -35,20 +37,69 @@ {%- set label = percent_covered_display ~ "%" -%} {%- set message = "(" ~ covered_statements_count ~ "/" ~ statements_count ~ ")" -%} {%- set color = percent_covered | x100 | get_badge_color -%} - + {{- badge(path, text, label, message, color, base) -}} {%- endmacro -%} {%- macro diff_coverage_rate_badge(path, added_statements_count, covered_statements_count, percent_covered) -%} - {% if added_statements_count -%} - {% set text = "In this PR, " ~ (added_statements_count) ~ " new statement" ~ (added_statements_count | pluralize) ~ " " ~ (added_statements_count | pluralize(singular='is', plural='are')) ~ " added to " ~ path ~ ", and " ~ covered_statements_count ~ " statement" ~ (covered_statements_count | pluralize) ~ " "~ (covered_statements_count | pluralize(singular='is', plural='are')) ~ " covered (" ~ (percent_covered | pct) ~ ")." -%} - {% set label = (percent_covered | pct(precision=0)) -%} - {% set message = "(" ~ covered_statements_count ~ "/" ~ added_statements_count ~ ")" -%} + {%- if added_statements_count -%} + {%- set text = "In this PR, " ~ (added_statements_count) ~ " new statement" ~ (added_statements_count | pluralize) ~ " " ~ (added_statements_count | pluralize(singular='is', plural='are')) ~ " added to " ~ path ~ ", and " ~ covered_statements_count ~ " statement" ~ (covered_statements_count | pluralize) ~ " "~ (covered_statements_count | pluralize(singular='is', plural='are')) ~ " covered (" ~ (percent_covered | pct) ~ ")." -%} + {%- set label = (percent_covered | pct(precision=0)) -%} + {%- set message = "(" ~ covered_statements_count ~ "/" ~ added_statements_count ~ ")" -%} {%- set color = (percent_covered | x100 | get_badge_color()) -%} - {% else -%} - {% set text = "This PR does not seem to add statements to " ~ path ~ "." -%} - {% set label = "" -%} - {%- set color = "grey" -%} - {% set message = "N/A" -%} - {% endif -%} - + {{- badge(path, text, label, message, color) -}} + {%- else -%} + {%- set text = "This PR does not seem to add statements to " ~ path ~ "." -%} + {{- badge(path, text, "", "N/A", "grey") -}} + {%- endif -%} +{%- endmacro -%} + +{%- macro missing_lines_links(path, groups, base=false) -%} + {%- set comma = joiner() -%} + {%- for group in groups -%} + {{- comma() -}} + [{{ group.line_start }}{% if group.line_start != group.line_end %}-{{ group.line_end }}{% endif %}]({{ path | file_url(lines=(group.line_start, group.line_end), base=base) }}) + {%- endfor -%} +{%- endmacro -%} + +{%- macro missing_branches_links(path, branches, base=false) -%} + {%- set comma = joiner() -%} + {%- for branch in branches -%} + {{- comma() -}} + [{{ branch[0] | abs }} -> {{ branch[1] | abs }}]({{ path | file_url(lines=(branch[0] | abs, branch[1] | abs), base=base) }}) + {%- endfor -%} +{%- endmacro -%} + +{#- + The pull request table and the whole project table only differ by the column + holding the coverage of the newly added statements, by the links pointing at + the pull request diff instead of the base branch, and by the set of missing + line groups, so they share the three macros below. + + The em spaces keep the original column widths: GitHub compresses a table that + overflows the width of a comment, and Markdown has no syntax for a column + width, so the header cell is what reserves the room. +-#} +{%- macro table_header(branch_coverage, with_diff) -%} +| File | Statements | Missing |{% if branch_coverage %} Branches | Missing |{% endif %}
Coverage          |{% if with_diff %} Coverage         
(new stmts) |{% endif %}
Missing stmts               |{% if branch_coverage %}
Missing branches               |{% endif %} +| :-- | :-: | :-: |{% if branch_coverage %} :-: | :-: |{% endif %} :-: |{% if with_diff %} :-: |{% endif %} :-- |{% if branch_coverage %} :-- |{% endif %} +{%- endmacro -%} + +{%- macro file_row(file, missing_map, branch_coverage, base, with_diff) -%} +{%- set path = file.coverage.path -%} +{%- set info = file.coverage.info -%} +|   [{{ path.name }}]({{ path | file_url(base=base) }}) | {{ statements_badge(path, info.num_statements, base) }} | {{ missing_lines_badge(path, info.missing_lines, base) }} |{% if branch_coverage %} {{ branches_badge(path, info.num_branches, base) }} | {{ missing_branches_badge(path, info.missing_branches, base) }} |{% endif %} {{ coverage_rate_badge(path, info.percent_covered, info.percent_covered_display, info.covered_lines, info.num_statements, base) }} |{% if with_diff %} {{ diff_coverage_rate_badge(path, (file.diff.added_statements | length) if file.diff else none, (file.diff.covered_statements | length) if file.diff else none, file.diff.percent_covered if file.diff else none) }} |{% endif %} {{ missing_lines_links(path, missing_map.get(path, []), base) }} |{% if branch_coverage %} {{ missing_branches_links(path, file.coverage.missing_branches or [], base) }} |{% endif %} +{%- endmacro -%} + +{%- macro total_row(totals, diff_totals, branch_coverage, with_diff) -%} +| **Project Total** | {{ statements_badge("whole project", totals.num_statements) }} | {{ missing_lines_badge("the whole project", totals.missing_lines) }} |{% if branch_coverage %} {{ branches_badge("the whole project", totals.num_branches) }} | {{ missing_branches_badge("the whole project", totals.missing_branches) }} |{% endif %} {{ coverage_rate_badge("the whole project", totals.percent_covered, totals.percent_covered_display, totals.covered_lines, totals.num_statements) }} |{% if with_diff %} {{ diff_coverage_rate_badge("the whole project", diff_totals.total_num_lines, diff_totals.total_num_lines - diff_totals.total_num_violations, diff_totals.total_percent_covered) }} |{% endif %}   |{% if branch_coverage %}   |{% endif %} +{%- endmacro -%} + +{#- `diff_totals` is the DiffCoverage object for the pull request table, or none + for the whole project table, which has no newly added statements. -#} +{%- macro coverage_table(files, missing_map, totals, diff_totals, branch_coverage=false, base=false) -%} +{%- set with_diff = diff_totals is not none -%} +{{ table_header(branch_coverage, with_diff) }} +{% for parent, files_in_folder in files | groupby(attribute="path.parent") %}|   **{{ parent }}** | +{% for file in files_in_folder %}{{ file_row(file, missing_map, branch_coverage, base, with_diff) }} +{% endfor %}{% endfor %}{{ total_row(totals, diff_totals, branch_coverage, with_diff) }} {%- endmacro -%} diff --git a/codecov/template_files/pr.md.j2 b/codecov/template_files/pr.md.j2 index b049c0c..8aedc8a 100644 --- a/codecov/template_files/pr.md.j2 +++ b/codecov/template_files/pr.md.j2 @@ -4,188 +4,11 @@ {%- else -%}
Click to see the coverage of changed files
- - - {% if branch_coverage %}{% endif %} - - - {% if branch_coverage %}{% endif %} - - - {%- for parent, files_in_folder in files|groupby(attribute="path.parent") -%} - - - - - {%- for file in files_in_folder -%} - {%- set path = file.coverage.path -%} - - - - {#- Statements cell -#} - {%- block statements_badge_cell scoped -%} - {{- macros.statements_badge( - path=path, - statements_count=file.coverage.info.num_statements, - ) -}} - {%- endblock statements_badge_cell-%} - - {#- Missing cell -#} - {%- block missing_lines_badge_cell scoped -%} - {{- macros.missing_lines_badge( - path=path, - missing_lines_count=file.coverage.info.missing_lines, - ) -}} - {%- endblock missing_lines_badge_cell -%} - - {% if branch_coverage %} - {#- Branches cell -#} - {%- block branches_badge_cell scoped -%} - {{- macros.branches_badge( - path=path, - branches_count=file.coverage.info.num_branches, - ) -}} - {%- endblock branches_badge_cell -%} - - {#- Missing cell -#} - {%- block missing_branches_badge_cell scoped -%} - {{- macros.missing_branches_badge( - path=path, - missing_branches_count=file.coverage.info.missing_branches, - ) -}} - {%- endblock missing_branches_badge_cell -%} - {% endif %} - - {#- Coverage rate -#} - {%- block coverage_rate_badge_cell scoped -%} - {{- macros.coverage_rate_badge( - path=path, - percent_covered=file.coverage.info.percent_covered, - percent_covered_display=file.coverage.info.percent_covered_display, - covered_statements_count=file.coverage.info.covered_lines, - statements_count=file.coverage.info.num_statements, - ) -}} - {%- endblock coverage_rate_badge_cell -%} - - {#- Coverage of added lines (new stmts) -#} - {%- block diff_coverage_rate_badge_cell scoped -%} - {{- macros.diff_coverage_rate_badge( - path=path, - added_statements_count=((file.diff.added_statements | length) if file.diff else none), - covered_statements_count=((file.diff.covered_statements | length) if file.diff else none), - percent_covered=(file.diff.percent_covered if file.diff else none) - ) -}} - {%- endblock diff_coverage_rate_badge_cell -%} - - {#- Link to lines missing -#} - {%- block link_to_missing_diff_lines_cell scoped -%} - - - {%- endblock link_to_missing_diff_lines_cell -%} - - {#- Link to branch missing lines -#} - {%- if branch_coverage -%} - {%- block link_to_branches_missing_lines_cell scoped -%} - - {%- endblock link_to_branches_missing_lines_cell -%} - {%- endif -%} - - - {%- endfor -%} - {%- endfor -%} - - - - - - - {#- Statements cell -#} - {%- block statements_badge_total_cell scoped -%} - {{- macros.statements_badge( - path="whole project", - statements_count=coverage.info.num_statements, - ) -}} - {%- endblock statements_badge_total_cell -%} - - {#- Missing cell -#} - {%- block missing_lines_badge_total_cell scoped -%} - {{- macros.missing_lines_badge( - path="the whole project", - missing_lines_count=coverage.info.missing_lines, - ) -}} - {%- endblock missing_lines_badge_total_cell -%} - - {% if branch_coverage %} - {#- Branches cell -#} - {%- block branches_badge_total_cell scoped -%} - {{- macros.branches_badge( - path="the whole project", - branches_count=coverage.info.num_branches, - ) -}} - {%- endblock branches_badge_total_cell -%} - - {#- Missing cell -#} - {%- block missing_branches_badge_total_cell scoped -%} - {{- macros.missing_branches_badge( - path="the whole project", - missing_branches_count=coverage.info.missing_branches, - ) -}} - {%- endblock missing_branches_badge_total_cell -%} - {% endif %} - - {#- Coverage rate -#} - {%- block coverage_rate_badge_total_cell scoped -%} - {{- macros.coverage_rate_badge( - path="the whole project", - percent_covered=coverage.info.percent_covered, - percent_covered_display=coverage.info.percent_covered_display, - covered_statements_count=coverage.info.covered_lines, - statements_count=coverage.info.num_statements, - ) -}} - {%- endblock coverage_rate_badge_total_cell -%} - - {# Coverage of added lines #} - {%- block diff_coverage_rate_badge_total_cell scoped -%} - {{- macros.diff_coverage_rate_badge( - path="the whole project", - added_statements_count=diff_coverage.total_num_lines, - covered_statements_count=(diff_coverage.total_num_lines-diff_coverage.total_num_violations), - percent_covered=diff_coverage.total_percent_covered, - ) -}} - {%- endblock diff_coverage_rate_badge_total_cell -%} - - - {% if branch_coverage %} - - {% endif %} - - -
FileStatementsMissingBranchesMissing
Coverage         
Coverage         
(new stmts)

Missing stmts              

Missing branches              
  {{ parent }}
  {{ path.name }} - - {%- set comma = joiner() -%} - {%- for group in missing_diff_lines.get(path, []) -%} - {{- comma() -}} - - - {{- group.line_start -}} - {%- if group.line_start != group.line_end -%} - - - {{- group.line_end -}} - {%- endif -%} - - - {%- endfor -%} - - {%- set comma = joiner() -%} - {%- for branch in file.coverage.missing_branches -%} - {{- comma() -}} - {{- branch[0] | abs -}} -> {{- branch[1] | abs -}} - {%- endfor -%} -
Project Total  
+{{ macros.coverage_table(files, missing_diff_lines, coverage.info, diff_coverage, branch_coverage, false) }} {%- if max_files and count_files > max_files %} - _The report is truncated to {{ max_files }} files out of {{ count_files }}. + _The report is truncated to {{ max_files }} files out of {{ count_files }}._ {% endif %}
diff --git a/codecov/template_files/project.md.j2 b/codecov/template_files/project.md.j2 index 098087b..3657e69 100644 --- a/codecov/template_files/project.md.j2 +++ b/codecov/template_files/project.md.j2 @@ -5,172 +5,9 @@ _No additional project files to report the coverage._ {%- else -%}
Click to see whole project coverage
- - - {% if branch_coverage %}{% endif %} - - - {% if branch_coverage %}{% endif %} - - - +{{ macros.coverage_table(coverage_files, missing_lines_for_whole_project, coverage.info, none, branch_coverage, true) }} -{%- for parent, coverage_files_in_folder in coverage_files|groupby(attribute="path.parent") -%} - - - - -{%- for coverage_file in coverage_files_in_folder -%} -{%- set coverage_file_path = coverage_file.coverage.path -%} - - - -{#- Statements cell -#} -{%- block project_statements_badge_cell scoped -%} -{{- macros.statements_badge( - path=coverage_file_path, - statements_count=coverage_file.coverage.info.num_statements, - base=true, -) -}} -{%- endblock project_statements_badge_cell-%} - -{#- Missing cell -#} -{%- block project_missing_lines_badge_cell scoped -%} -{{- macros.missing_lines_badge( - path=coverage_file_path, - missing_lines_count=coverage_file.coverage.info.missing_lines, - base=true, -) -}} -{%- endblock project_missing_lines_badge_cell -%} - -{% if branch_coverage %} -{#- Branches cell -#} -{%- block project_branches_badge_cell scoped -%} -{{- macros.branches_badge( - path=coverage_file_path, - branches_count=coverage_file.coverage.info.num_branches, - base=true, -) -}} -{%- endblock project_branches_badge_cell -%} - -{#- Missing cell -#} -{%- block project_missing_branches_badge_cell scoped -%} -{{- macros.missing_branches_badge( - path=coverage_file_path, - missing_branches_count=coverage_file.coverage.info.missing_branches, - base=true, -) -}} -{%- endblock project_missing_branches_badge_cell -%} -{% endif %} - -{#- Coverage cell -#} -{%- block project_coverage_rate_badge_cell scoped -%} -{{- macros.coverage_rate_badge( - path=coverage_file_path, - percent_covered=coverage_file.coverage.info.percent_covered, - percent_covered_display=coverage_file.coverage.info.percent_covered_display, - covered_statements_count=coverage_file.coverage.info.covered_lines, - statements_count=coverage_file.coverage.info.num_statements, - base=true, -) -}} -{%- endblock project_coverage_rate_badge_cell -%} - -{#- Link to missing lines -#} -{%- block project_link_to_missing_lines_cell scoped -%} - - -{%- endblock project_link_to_missing_lines_cell -%} - -{#- Link to branch missing lines -#} -{%- if branch_coverage -%} -{%- block project_link_to_branches_missing_lines_cell scoped -%} - -{%- endblock project_link_to_branches_missing_lines_cell -%} -{%- endif -%} - - -{%- endfor -%} -{%- endfor -%} - - - - - - -{#- Statements cell -#} -{%- block project_statements_badge_total_cell scoped -%} -{{- macros.statements_badge( - path="whole project", - statements_count=coverage.info.num_statements, -) -}} -{%- endblock project_statements_badge_total_cell -%} - -{#- Missing cell -#} -{%- block project_missing_lines_badge_total_cell scoped -%} -{{- macros.missing_lines_badge( - path="the whole project", - missing_lines_count=coverage.info.missing_lines, -) -}} -{%- endblock project_missing_lines_badge_total_cell -%} - -{% if branch_coverage %} -{#- Branches cell -#} -{%- block project_branches_badge_total_cell scoped -%} -{{- macros.branches_badge( - path="the whole project", - branches_count=coverage.info.num_branches, -) -}} -{%- endblock project_branches_badge_total_cell -%} - -{#- Missing cell -#} -{%- block project_missing_branches_badge_total_cell scoped -%} -{{- macros.missing_branches_badge( - path="the whole project", - missing_branches_count=coverage.info.missing_branches, -) -}} -{%- endblock project_missing_branches_badge_total_cell -%} -{% endif %} - -{#- Coverage rate -#} -{%- block project_coverage_rate_badge_total_cell scoped -%} -{{- macros.coverage_rate_badge( - path="the whole project", - percent_covered=coverage.info.percent_covered, - percent_covered_display=coverage.info.percent_covered_display, - covered_statements_count=coverage.info.covered_lines, - statements_count=coverage.info.num_statements, -) -}} -{%- endblock project_coverage_rate_badge_total_cell -%} - - -{% if branch_coverage %} - -{% endif %} - - -
FileStatementsMissingBranchesMissing
Coverage         

Missing stmts              

Missing branches              
  {{ parent }}
  {{ coverage_file_path.name }} - -{%- set comma = joiner() -%} -{%- for group in missing_lines_for_whole_project.get(coverage_file_path, []) -%} -{{- comma() -}} - - -{{- group.line_start -}} -{%- if group.line_start != group.line_end -%} -- -{{- group.line_end -}} -{%- endif -%} - - -{%- endfor -%} - -{%- set comma = joiner() -%} -{%- for branch in coverage_file.coverage.missing_branches -%} -{{- comma() -}} -{{- branch[0] | abs -}} -> {{- branch[1] | abs -}} -{%- endfor -%} -
Project Total  
{%- endif -%} {%- endif -%} diff --git a/pyproject.toml b/pyproject.toml index 83efcde..199dc10 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -48,7 +48,7 @@ default-groups = [ "dev" ] [tool.ruff] target-version = "py311" line-length = 120 -extend-exclude = [ "*.mdc" ] +extend-exclude = [ "*.md", "*.mdc" ] format.quote-style = "single" lint.select = [ "E", # Errors diff --git a/tests/test_template.py b/tests/test_template.py index fac6b21..dd238f5 100644 --- a/tests/test_template.py +++ b/tests/test_template.py @@ -164,6 +164,11 @@ def test_comment_template(coverage_obj, diff_coverage_obj): ) assert result.startswith('## Coverage report') assert '' in result + assert '| File | Statements | Missing |' in result + assert '(new stmts)' in result + assert 'Missing stmts' in result + assert 'Branches' not in result + assert 'img.shields.io/badge/' in result def test_comment_template_branch_coverage(coverage_obj, diff_coverage_obj): @@ -192,9 +197,43 @@ def test_comment_template_branch_coverage(coverage_obj, diff_coverage_obj): ) assert result.startswith('## Coverage report') assert '' in result - assert 'BranchesMissing' in result + assert '| File | Statements | Missing | Branches | Missing |' in result assert 'Missing branches' in result - assert 'colspan="9"' in result + assert '(new stmts)' in result + # The delimiter row must always declare as many columns as the header row + assert '| :-- | :-: | :-: | :-: | :-: | :-: | :-: | :-- | :-- |' in result + + +def test_comment_template_project_report(coverage_obj, diff_coverage_obj): + coverage_files, total = template.select_files( + coverage=coverage_obj, + max_files=25, + skip_covered_files_in_report=True, + ) + result = template.get_comment_markdown( + template.read_template_file('comment.md.j2'), + coverage_obj, + diff_coverage_obj, + decimal.Decimal('100'), + decimal.Decimal('70'), + 'org/repo', + 1, + 'main', + '', + coverage_files=coverage_files, + count_coverage_files=total, + files=[], + count_files=0, + max_files=25, + branch_coverage=True, + complete_project_report=True, + ) + # The whole project table has no newly added statements column + assert '| File | Statements | Missing | Branches | Missing |' in result + assert 'Missing branches' in result + assert '(new stmts)' not in result + assert 'https://github.com/org/repo/blob/main/codebase/code.py' in result + assert '| :-- | :-: | :-: | :-: | :-: | :-: | :-- | :-- |' in result def test_template_no_files(coverage_obj): From dcd724e5c1742674c5cce1c02f171323bf47fc82 Mon Sep 17 00:00:00 2001 From: Pradeep Tammali Date: Fri, 31 Jul 2026 23:56:37 +0200 Subject: [PATCH 2/3] refactor: remove coverage report url infavour of label --- README.md | 1 - codecov/config.py | 1 - codecov/main.py | 1 - codecov/template_files/comment.md.j2 | 6 ------ tests/test_config.py | 2 -- 5 files changed, 11 deletions(-) diff --git a/README.md b/README.md index dd626b8..ae01fea 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,6 @@ Note: Either `GITHUB_PR_NUMBER` or `GITHUB_REF` is required. `GITHUB_PR_NUMBER` - `MAX_FILES_IN_COMMENT`: The maximum number of files to include in the coverage report comment. Default is 25. - `SKIP_COVERED_FILES_IN_REPORT`: Skip the files with coverage 100% from the report. Default is True. - `COMPLETE_PROJECT_REPORT`: Whether to include the complete project coverage report in the comment. Default is False. -- `COVERAGE_REPORT_URL`: URL of the full coverage report to mention in the comment. - `LABEL`: Optional text rendered in the comment footer. Default is unset (no footer). - `DEBUG`: Whether to enable debug mode. Default is False. diff --git a/codecov/config.py b/codecov/config.py index 9795f73..bc9772d 100644 --- a/codecov/config.py +++ b/codecov/config.py @@ -50,7 +50,6 @@ class Config: MAX_FILES_IN_COMMENT: int = 25 SKIP_COVERED_FILES_IN_REPORT: bool = True COMPLETE_PROJECT_REPORT: bool = False - COVERAGE_REPORT_URL: str | None = None LABEL: str | None = None DEBUG: bool = False diff --git a/codecov/main.py b/codecov/main.py index dd734e7..f2b02d9 100644 --- a/codecov/main.py +++ b/codecov/main.py @@ -95,7 +95,6 @@ def _create_comment(self) -> None: self.marker, branch_coverage=self.config.BRANCH_COVERAGE, complete_project_report=self.config.COMPLETE_PROJECT_REPORT, - coverage_report_url=self.config.COVERAGE_REPORT_URL, max_files=self.config.MAX_FILES_IN_COMMENT, files=diff_files_info, count_files=diff_count_files, diff --git a/codecov/template_files/comment.md.j2 b/codecov/template_files/comment.md.j2 index 5ad84c2..b989bb8 100644 --- a/codecov/template_files/comment.md.j2 +++ b/codecov/template_files/comment.md.j2 @@ -32,12 +32,6 @@ {% include "project.md.j2" %} {%- endblock project_coverage_by_file %} -{%- block full_coverage_report_link -%} - {%- if coverage_report_url %} -

See the full coverage report of the project here.

- {%- endif -%} -{%- endblock full_coverage_report_link %} - {%- block footer %} {% if label %} diff --git a/tests/test_config.py b/tests/test_config.py index 625765d..a2285cc 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -53,7 +53,6 @@ def test_config_from_environ_sample(): 'MINIMUM_ORANGE': '70', 'MAX_FILES_IN_COMMENT': 25, 'COMPLETE_PROJECT_REPORT': 'True', - 'COVERAGE_REPORT_URL': 'https://your_coverage_report_url', 'DEBUG': 'False', } ) == config.Config( @@ -66,7 +65,6 @@ def test_config_from_environ_sample(): MINIMUM_ORANGE=decimal.Decimal('70'), MAX_FILES_IN_COMMENT=25, COMPLETE_PROJECT_REPORT=True, - COVERAGE_REPORT_URL='https://your_coverage_report_url', DEBUG=False, ) From 65ac525a0daabceaa07b183853d0d6c93b751fa8 Mon Sep 17 00:00:00 2001 From: Pradeep Tammali Date: Sat, 1 Aug 2026 00:09:31 +0200 Subject: [PATCH 3/3] feature: remove badge tooltips --- codecov/template_files/comment.md.j2 | 6 ++--- codecov/template_files/macros.md.j2 | 39 ++++++++++------------------ 2 files changed, 15 insertions(+), 30 deletions(-) diff --git a/codecov/template_files/comment.md.j2 b/codecov/template_files/comment.md.j2 index b989bb8..2bc19de 100644 --- a/codecov/template_files/comment.md.j2 +++ b/codecov/template_files/comment.md.j2 @@ -5,17 +5,15 @@ {#- Project coverage badge -#} {%- block coverage_evolution_badge -%} {%- if coverage %} - {%- set text = "The project coverage is at " ~ coverage.info.percent_covered_display ~ "%." -%} {%- set color = coverage.info.percent_covered | x100 | get_badge_color -%} - + {%- endif -%} {%- endblock coverage_evolution_badge -%}    {#- PR coverage badge -#} {%- block diff_coverage_badge -%} - {%- set text = (diff_coverage.total_percent_covered | pct) ~ " of the statements added in this PR are covered." -%} {%- set color = diff_coverage.total_percent_covered | x100 | get_badge_color -%} - + {%- endblock diff_coverage_badge -%} {%- endblock coverage_badges -%} diff --git a/codecov/template_files/macros.md.j2 b/codecov/template_files/macros.md.j2 index 4a36cc9..9251a93 100644 --- a/codecov/template_files/macros.md.j2 +++ b/codecov/template_files/macros.md.j2 @@ -1,55 +1,42 @@ {#- - Every badge cell is a shields.io image, linked to the file and carrying a - sentence as its tooltip, so the wrapper is factored out into `badge`. Cells - no longer carry their own : in a GitHub Flavoured - Markdown table the alignment belongs to the delimiter row of the table. + Every badge cell is a shields.io image linked to the file, so the wrapper is + factored out into `badge`. Cells no longer carry their own + : in a GitHub Flavoured Markdown table the alignment + belongs to the delimiter row of the table. -#} -{%- macro badge(path, text, label, message, color, base=false) -%} -[![]({{ label | generate_badge(message=message, color=color) }} "{{ text }}")]({{ path | file_url(base=base) }}) +{%- macro badge(path, label, message, color, base=false) -%} +[![]({{ label | generate_badge(message=message, color=color) }})]({{ path | file_url(base=base) }}) {%- endmacro -%} {%- macro statements_badge(path, statements_count, base=false) -%} - {%- set text = "The " ~ path ~ " contains " ~ statements_count ~ " statement" ~ (statements_count | pluralize) ~"." -%} - {%- set color = "007ec6" -%} - {{- badge(path, text, "", statements_count | string, color, base) -}} + {{- badge(path, "", statements_count | string, "007ec6", base) -}} {%- endmacro -%} {%- macro branches_badge(path, branches_count, base=false) -%} - {%- set text = "The " ~ path ~ " contains " ~ branches_count ~ " branch" ~ (branches_count | pluralize(plural='es')) ~"." -%} - {%- set color = "008080" -%} - {{- badge(path, text, "", branches_count | string, color, base) -}} + {{- badge(path, "", branches_count | string, "008080", base) -}} {%- endmacro -%} {%- macro missing_branches_badge(path, missing_branches_count, base=false) -%} - {%- set text = missing_branches_count ~ " branch" ~ (missing_branches_count | pluralize(plural='es')) ~ " missing the coverage in " ~ path ~ "." -%} - {%- set color = "brightgreen" if missing_branches_count == 0 else "red" -%} - {{- badge(path, text, "", missing_branches_count | string, color, base) -}} + {{- badge(path, "", missing_branches_count | string, "brightgreen" if missing_branches_count == 0 else "red", base) -}} {%- endmacro -%} {%- macro missing_lines_badge(path, missing_lines_count, base=false) -%} - {%- set text = missing_lines_count ~ " statement" ~ (missing_lines_count | pluralize) ~ " missing the coverage in " ~ path ~ "." -%} - {%- set color = "brightgreen" if missing_lines_count == 0 else "red" -%} - {{- badge(path, text, "", missing_lines_count | string, color, base) -}} + {{- badge(path, "", missing_lines_count | string, "brightgreen" if missing_lines_count == 0 else "red", base) -}} {%- endmacro -%} {%- macro coverage_rate_badge(path, percent_covered, percent_covered_display, covered_statements_count, statements_count, base=false) -%} - {%- set text = "The coverage rate of " ~ path ~ " is " ~ percent_covered_display ~ "% (" ~ covered_statements_count ~ "/" ~ statements_count ~ ")." -%} {%- set label = percent_covered_display ~ "%" -%} {%- set message = "(" ~ covered_statements_count ~ "/" ~ statements_count ~ ")" -%} - {%- set color = percent_covered | x100 | get_badge_color -%} - {{- badge(path, text, label, message, color, base) -}} + {{- badge(path, label, message, percent_covered | x100 | get_badge_color, base) -}} {%- endmacro -%} {%- macro diff_coverage_rate_badge(path, added_statements_count, covered_statements_count, percent_covered) -%} {%- if added_statements_count -%} - {%- set text = "In this PR, " ~ (added_statements_count) ~ " new statement" ~ (added_statements_count | pluralize) ~ " " ~ (added_statements_count | pluralize(singular='is', plural='are')) ~ " added to " ~ path ~ ", and " ~ covered_statements_count ~ " statement" ~ (covered_statements_count | pluralize) ~ " "~ (covered_statements_count | pluralize(singular='is', plural='are')) ~ " covered (" ~ (percent_covered | pct) ~ ")." -%} {%- set label = (percent_covered | pct(precision=0)) -%} {%- set message = "(" ~ covered_statements_count ~ "/" ~ added_statements_count ~ ")" -%} - {%- set color = (percent_covered | x100 | get_badge_color()) -%} - {{- badge(path, text, label, message, color) -}} + {{- badge(path, label, message, percent_covered | x100 | get_badge_color()) -}} {%- else -%} - {%- set text = "This PR does not seem to add statements to " ~ path ~ "." -%} - {{- badge(path, text, "", "N/A", "grey") -}} + {{- badge(path, "", "N/A", "grey") -}} {%- endif -%} {%- endmacro -%}