Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions .github/workflows/c2c-ratio-pr.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
name: Comment-to-code (C2C) ratio

on:
pull_request:

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}
cancel-in-progress: >-
${{ github.ref != 'refs/heads/master' &&
github.event_name != 'merge_group' &&
!startsWith(github.ref, 'refs/heads/gh-readonly-queue') }}

permissions:
contents: read

jobs:
comment-to-code-ratio:
runs-on: ubuntu-24.04
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
fetch-depth: 0

- name: Install cloc
run: npm install --global cloc

- name: Generate report
continue-on-error: true
uses: deep5050/comment-to-code-ratio-action@v1.0.1
with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
issue_number: ${{ github.event.pull_request.number }}
options: >-
--quiet
--git
--diff
${{ github.event.pull_request.base.sha }}
${{ github.event.pull_request.head.sha }}
--md
--out=report.md
--exclude-dir=.git,3rdparty,build

- name: Check ratio
id: ratio
run: python3 scripts/check_comment_to_code_ratio.py report.md --limit 10

- name: Print final percentage
if: always()
run: |
echo "Comment percentage for PR changes: ${{ steps.ratio.outputs.comment_percentage || 'N/A' }}%"
108 changes: 108 additions & 0 deletions scripts/check_comment_to_code_ratio.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import argparse
import os
import sys
from pathlib import Path

EXPECTED_HEADER_SUFFIX = [
"== files",
"!= files",
"+ files",
"- files",
"== blank",
"!= blank",
"+ blank",
"- blank",
"== comment",
"!= comment",
"+ comment",
"- comment",
"== code",
"!= code",
"+ code",
"- code",
]
# Zero-based indices in `cloc --diff --md` rows after splitting by `|`.
COMMENT_COLUMN_INDICES = (10, 11, 12)
CODE_COLUMN_INDICES = (14, 15, 16)


def parse_changed_totals(report_path):
changed_comments = 0
changed_code = 0
header_found = False

for raw_line in report_path.read_text(encoding="utf-8").splitlines():
if "|" not in raw_line:
continue

cells = [cell.strip() for cell in raw_line.split("|")]
if cells and cells[-1] == "":
cells = cells[:-1]

if cells and cells[0] in {"Language", "File"}:
if cells[1:] != EXPECTED_HEADER_SUFFIX:
sys.exit("Unexpected cloc diff table format.")
header_found = True
continue

if not cells:
continue
if cells[0].startswith((":", "-", "SUM:")):
continue
if not header_found:
continue

try:
changed_comments += sum(
int(cells[index]) for index in COMMENT_COLUMN_INDICES
)
changed_code += sum(int(cells[index]) for index in CODE_COLUMN_INDICES)
except (IndexError, ValueError):
continue

if not header_found:
print("Unable to find cloc diff table header in report.")
sys.exit(1)

return changed_comments, changed_code


def main():
parser = argparse.ArgumentParser()
parser.add_argument("report")
parser.add_argument("--limit", type=float, default=10.0)
args = parser.parse_args()

report_path = Path(args.report)
if not report_path.exists():
print(f"{report_path} was not generated by the comment ratio action.")
sys.exit(1)

changed_comments, changed_code = parse_changed_totals(report_path)
total_changed_nonblank = changed_comments + changed_code
comment_percentage = (
0.0
if total_changed_nonblank == 0
else changed_comments * 100.0 / total_changed_nonblank
)

print(f"Comment percentage for PR changes: {comment_percentage:.2f}%")

github_output = os.getenv("GITHUB_OUTPUT")
if github_output:
with Path(github_output).open("a", encoding="utf-8") as output:
output.write(f"changed_comments={changed_comments}\n")
output.write(f"changed_code={changed_code}\n")
output.write(f"comment_percentage={comment_percentage:.2f}\n")

if comment_percentage > args.limit:
print(
f"Comment percentage for PR changes is {comment_percentage:.2f}%, "
f"which exceeds {args.limit:.2f}%.",
file=sys.stderr,
)
sys.exit(1)


if __name__ == "__main__":
main()
Loading