ci: track annotation coverage of commons - #7863
Conversation
Two of the three code-health metrics I set out to add turned out not to be worth having, so this adds one and fixes a number. Annotation coverage (new): share of exported functions in lua/wikis/commons whose preceding doc block carries @param or @return. Annotations are what make commons statically understandable, and at 94.99% the metric works as a regression guard rather than a growth target -- the actionable figures are the 121 unannotated functions and whether a PR adds more. Reported with deltas against the base commit, same shape as the coverage job. The script takes a root argument so the base tree is measured with this PR's script rather than the base's, keeping the delta about code rather than measurement. LuaLS problem count (fixed): the summary reported `grep -c 'Warning'`, which gives 263 where LuaLS itself reports 238 -- a single diagnostic can span several lines. Use the totals LuaLS prints, and add files-with-problems. Deliberately not added: - luacheck findings. Already 0 warnings / 0 errors across 1707 files and gated there, so a trend line would be permanently flat. - A delta on LuaLS problems. The count is not deterministic: 237-240 over 8 runs on identical code, in both pretty and json output, with no --threads flag to pin it. A per-PR delta would show phantom movement of a few either way. Files-with-problems was stable at 142 across all runs, so that is the number to watch. The summary now says as much. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Matches the coverage job. Step summaries are not retrievable from the API, so the numbers could not be checked without opening the run page. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
hjpalpha
left a comment
There was a problem hiding this comment.
does the anno coverage check account for the existence of exported functions that have neither input nor return?
Exempt functions that need no annotation (@hjpalpha). A function taking no parameters and returning no value needs neither @param nor @return, but was being counted as unannotated -- so the metric penalised correctly written code. 19 of the 121 "unannotated" functions were in that position. Excluding them puts coverage at 95.74% over 2397 functions that do need tags, with 102 genuinely missing them. Whether a body returns a value is decided by scanning to the `end` at the function's own indentation. That is a heuristic, so it is biased toward asking for an annotation rather than excusing one, and the exempt count is now a reported row so the exemption stays visible instead of silently shrinking the denominator. Have the script emit the Markdown table itself, taking --base for the comparison tree (@ElectricalBoy). Removes 33 lines of shell that existed only to re-parse what the script already knew. --raw still prints key=value for debugging. Add actions/setup-python rather than relying on the runner image's python (@ElectricalBoy), and use `"test" in path.parts` over string matching (@ElectricalBoy) -- verified equivalent here, 4 files either way. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
It did not — good catch, that was a real flaw. Breaking down the 121 the metric called unannotated:
So 19 were being counted against a metric they can't satisfy — it was penalising correctly written code. Fixed in 7ed443e. Those functions are now reported as exempt and excluded from the ratio, which puts coverage at 95.74% over the 2397 functions that do need tags, with 102 genuinely missing them (was 94.99% / 121). Two deliberate choices in how it's done:
|
CI checks out the PR merge commit, so HEAD includes everything on the base branch, but the comparison used pull_request.base.sha -- the fork point, which drifts behind as the base branch advances. The delta then reports commits from everyone else that got merged in, not just this PR's. Use the merge commit's first parent, which is the base branch tip. Falls back to omitting deltas when HEAD is not a merge commit (workflow_dispatch). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Two unrelated changes were sharing a branch: a new metric and a fix to an existing one. Split so they can be reviewed and reverted independently. The LuaLS summary fix now lives in #7877. luals-code-style here is byte identical to main again; this branch only adds annotation coverage. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Split the LuaLS problem-count fix out into #7877 — it was an unrelated fix to an existing metric sharing a branch with a new one. The |
| - name: Setup python | ||
| uses: actions/setup-python@v6 | ||
| with: | ||
| python-version: '3.13' |
There was a problem hiding this comment.
Changed to 3.14 in 6aba51f, matching the six other python workflows.
|
|
||
| def main(): | ||
| parser = argparse.ArgumentParser() | ||
| parser.add_argument("root", nargs="?", default=DEFAULT_ROOT) |
There was a problem hiding this comment.
| parser.add_argument("root", nargs="?", default=DEFAULT_ROOT) | |
| parser.add_argument("root", nargs="?", type=pathlib.Path, default=DEFAULT_ROOT) |
same as #7864 (comment)
Both from review (@ElectricalBoy): - `type=pathlib.Path` on the root and --base arguments, which drops the pathlib.Path() constructors at the call sites. argparse applies the conversion to the string default too, so the no-argument case still gets a Path. - python-version 3.14 rather than 3.13, matching the six other python workflows in the repo. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
What
New metric: share of exported functions in
lua/wikis/commonswhose doc block carries@paramor@return.The LuaLS problem-count fix that was here has moved to #7877.
How it was tested
ruff check+formatworkflow_dispatch