Skip to content

Fix bugs in CI scripts and workflows; add test suites and improve documentation#573

Open
greenc-FNAL wants to merge 15 commits intomainfrom
maintenance/workflows-scripts-tests-fixes
Open

Fix bugs in CI scripts and workflows; add test suites and improve documentation#573
greenc-FNAL wants to merge 15 commits intomainfrom
maintenance/workflows-scripts-tests-fixes

Conversation

@greenc-FNAL
Copy link
Copy Markdown
Contributor

@greenc-FNAL greenc-FNAL commented May 7, 2026

Summary

This maintenance branch corrects a collection of bugs across GitHub Actions
workflows and Python CI scripts, adds comprehensive unit-test suites for
scripts that previously had zero test coverage, and improves the documentation
and usability of developer-facing utilities.


Workflow fixes (.github/workflows/)

coverage.yaml

  • Removed invalid --omit flag from pytest invocation. --omit is a
    coverage.py option with no --cov-omit equivalent in pytest-cov; passing
    it on the command line caused the "Generate scripts coverage report" step to
    fail with "unrecognised arguments". The omit pattern is now declared in
    pyproject.toml under [tool.coverage.run], which pytest-cov reads
    automatically.
  • Declared missing has_coverage_python_xml job output. The
    coverage_outputs step emitted has_coverage_python_xml to $GITHUB_OUTPUT,
    but the coverage job's outputs: block never listed it, so downstream jobs
    that consumed needs.coverage.outputs.has_coverage_python_xml silently
    received an empty string.
  • Added coverage-complete job. Triggered on issue_comment events; posts
    a PR comment reporting the coverage result and calls complete-pr-comment to
    update the triggering comment's reaction emoji.

clang-tidy-check.yaml

  • Added "No clang-tidy issues found" comment for passing runs that produce
    no reportable findings.
  • Added complete-pr-comment call to update the triggering comment's
    reaction after the job finishes.

cmake-build.yaml

  • Added issues: write permission (required by the complete-pr-comment
    action).
  • Added complete-pr-comment call to update the reaction on the triggering
    comment after the build completes.

.github/actions/post-clang-tidy-results/action.yaml

  • Added has_content output so callers can distinguish "passed with
    findings" from "passed with nothing to report".

Script bug fixes and improvements (scripts/)

check_codeql_alerts.py — 7 bugs fixed

  1. base_alerts_raw possibly unbound — initialised to [] before the
    refs/pull/ branch to avoid NameError when the ref is not a PR ref.
  2. Alert message always empty in API mode_to_alert_api read
    raw.get("message", {}).get("text"), but the GitHub Code Scanning API
    places the message inside most_recent_instance; PR comments now show the
    actual alert description.
  3. write_summary: threshold not interpolated"(level ≥ {threshold})" was a plain string literal, so the literal text {threshold} was written
    into GITHUB_STEP_SUMMARY instead of the configured value.
  4. min_level threshold not applied in API mode_compare_alerts_via_api
    returned all open alerts regardless of severity; now filters new alerts by
    the configured threshold. Resolved (fixed_*) alerts are intentionally left
    unfiltered.
  5. _build_multi_section_comment strips intentional blank lines — the join
    expression "\n".join(line for line in lines if line) discarded the empty
    separator strings, causing adjacent ## headings to render without a blank
    line between them.
  6. _build_multi_section_comment produces a link-only comment when no
    context is available
    — on the first scan of a PR (no previous commit or
    base SHA), the function now falls back to rendering the main new_alerts /
    fixed_alerts comparison instead of a bare link.
  7. _paginate_alerts_api makes one extra API call per sequence — a final
    page shorter than per_page items now stops pagination immediately rather
    than making an additional empty-page request.

sarif-alerts.py — 4 bugs fixed, new filtering options

  1. sys not imported at module levelimport sys was inside
    if __name__ == "__main__":; programmatic calls to main() that hit a
    missing-file error would raise NameError.
  2. No error handling for malformed or unreadable inputjson.JSONDecodeError
    and OSError from _process_sarif propagated as raw tracebacks; they are
    now caught, reported cleanly to stderr, and counted toward a non-zero exit
    code. Processing of remaining files continues.
  3. Directory input not supported — added _collect_sarif_paths() to expand
    directory arguments to the sorted list of .sarif files they contain
    (recursive, with an empty-directory warning).
  4. No severity or baseline filtering — added --level (none/note/warning/error,
    default: none), --baseline (repeatable; e.g. --baseline new --baseline absent),
    and --max-message N options. Multi-line messages are now collapsed to a
    single line.

Other script fixes

  • codeql_reset_dismissed_alerts.py — module docstring, function docstrings,
    CLI help text, and output format improved; the alert URL is now printed
    alongside the rule ID.
  • fix_header_guards.py — all read_text() / write_text() calls now pass
    encoding="utf-8".
  • normalize_coverage_lcov.py — all read_text() / write_text() calls
    now pass encoding="utf-8".
  • create_coverage_symlinks.py — removed unreachable dead code in
    should_link(): the six explicit suffix checks (.c++, .h++, .icc,
    .tcc, .i, .ii) duplicated members already present in SUPPORTED_SUFFIXES.
  • clang_tidy_check_summary.py, clang_tidy_fixes_to_problems.py
    improved module docstrings, help text, and metavar annotations for all CLI
    options; added epilog examples and RawDescriptionHelpFormatter.

New and extended test suites (scripts/test/)

conftest.py (new)

Performs the sys.path insertion for scripts/ once per pytest session,
eliminating the per-file duplication that was present in the four existing test
files.

test_check_codeql_alerts.py (new) — 110 tests, ~84 % line coverage

Covers: severity normalisation; message/location extraction; rule metadata
indexing; SARIF baselineState parsing and threshold filtering; GitHub API
alert pagination (single page, multi-page, early exit on partial last page);
API comparison logic (new/fixed/matched, vs-main, vs-prev, vs-base); PR comment
rendering including blank-line preservation and fallback behaviour;
set_outputs; write_summary including threshold interpolation regression;
and end-to-end main() in both SARIF mode and API mode. All GitHub API calls
are mocked.

test_sarif_alerts.py (new) — 39 tests + 1 conditionally skipped

Covers: path collection including directory expansion and empty-directory
warning; SARIF result processing including level and baseline filtering, message
truncation and whitespace collapsing, multiple runs, invalid JSON, non-object
JSON, unreadable file, and missing optional fields; and end-to-end main()
including partial-failure behaviour and the module-level sys import assertion.

test_coverage_scripts.py (new) — 71 tests

Adds first-ever unit tests for the four Python coverage helper scripts:

Script Coverage before Coverage after
normalize_coverage_lcov.py 0 % ~81 %
normalize_coverage_xml.py 0 % ~80 %
export_llvm_lcov.py 0 % ~96 %
create_coverage_symlinks.py 0 % ~92 %

Documentation and configuration

  • scripts/README.md — added a "Developer Tools" section with full usage
    documentation and examples for clang_tidy_check_summary.py,
    clang_tidy_fixes_to_problems.py, and codeql_reset_dismissed_alerts.py.
  • scripts/QUICK_REFERENCE.md — added matching quick-reference entries for
    the three developer tools.
  • pyproject.toml — added [tool.ruff.lint.isort] known-first-party list
    so scripts in scripts/test/ are sorted correctly (avoiding false I001
    violations); added [tool.coverage.run] omit to exclude test helpers from
    coverage measurement.
  • .gitignore — added .coverage to prevent the pytest-cov data file
    from being tracked.

Post-review fixes (f54c335)

Addressed three Copilot review comments from PR review:

  • scripts/test/test_sarif_alerts.py — removed unused bare import importlib
    (only importlib.util is used; import importlib.util is sufficient and was
    already present).
  • scripts/sarif-alerts.py --level — changed choices=sorted(_KNOWN_LEVELS)
    to choices=list(_LEVEL_ORDER) so argparse presents and validates levels in
    severity order (none, note, warning, error) rather than alphabetical order.
  • scripts/sarif-alerts.py --max-message — added _positive_int() argparse
    type function that rejects values less than 1, preventing incorrect truncation
    behaviour with zero or negative inputs.

Further post-review fixes (026a6d2)

Addressed five Pylint complaints in scripts/test/test_sarif_alerts.py:

  • W0212 (protected-access) — added # pylint: disable=protected-access /
    # pylint: enable=protected-access around the block that assigns _collect
    and _process typed aliases from private module symbols; access is
    intentional in this test module.
  • C0301 (line-too-long) — suppressed with # pylint: disable-next=line-too-long
    on the line preceding the _collect assignment; ruff format refuses to break
    this line because the overflow comes from a trailing # type: ignore comment
    that cannot be moved to a different line.
  • C1803 (use-implicit-booleaness-not-comparison) — replaced
    list(_process(f)) == [] with not list(_process(f)).
  • W0613 (unused-argument) — removed the unused capsys parameter from
    test_returns_zero_on_success (the fixture was never referenced in the body).

Seven bugs are fixed in scripts/check_codeql_alerts.py:

1. base_alerts_raw possibly unbound (NameError at runtime)
   Initialise base_alerts_raw to [] before the 'if ref.startswith("refs/pull/"):'
   block so it is always bound regardless of the ref value.

2. Alert message always empty in API mode
   _to_alert_api read raw.get("message", {}).get("text"), but the GitHub Code
   Scanning API places the message inside most_recent_instance, not at the top
   level.  Fixed to (instance.get("message") or {}).get("text"), so PR comments
   now show the actual alert description instead of silently falling back to the
   rule name.

3. write_summary: threshold not interpolated in step summary
   The format string "(level >= {threshold}).\n" was a plain string literal, not
   an f-string.  The literal text "{threshold}" was written into GITHUB_STEP_SUMMARY
   instead of the configured threshold value.

4. min_level threshold not applied in API comparison mode
   _compare_alerts_via_api returned all open alerts regardless of severity.
   Added a min_level parameter (default "warning") and apply
   severity_reaches_threshold to new_alerts, new_vs_prev, and new_vs_base so
   that note/none-level alerts do not trigger PR failures or pollute comments
   when the threshold is warning or error.  Resolved (fixed_*) alerts are
   intentionally left unfiltered — surfacing any resolved alert is always useful.

5. _build_multi_section_comment strips intentional blank lines
   The join expression "\n".join(line for line in lines if line) silently
   discarded the empty separator strings appended after every section, causing
   adjacent ## headings to be rendered without a blank line between them.
   Changed to "\n".join(lines) to match the pattern used by build_comment.

6. _build_multi_section_comment produces a link-only comment when no
   vs_prev/vs_base context is available
   On the first scan of a PR (no previous commit or base SHA), all four
   vs_prev/vs_base lists are empty and the function rendered only the
   code-scanning link.  Added a fallback block that renders new_alerts and
   fixed_alerts (the main vs-default-branch comparison) when no finer-grained
   context is present.

7. _paginate_alerts_api: add early exit on partial last page
   The pagination loop terminated only on an empty page.  A short final page
   (fewer than per_page items) now also stops iteration immediately, avoiding
   one unnecessary API call per paginated request.

A comprehensive test suite is added in scripts/test/test_check_codeql_alerts.py
(110 tests across 18 test classes, 84 % line coverage of check_codeql_alerts.py):

- TestSeverity / TestSanitizeMessage / TestExtractMessage: normalisation and
  message extraction helpers.
- TestExtractLocation: all fallback paths (physicalLocation, relatedLocations,
  logicalLocations, codeFlows).
- TestRuleLookupMap: rule metadata indexing.
- TestCollectAlerts: SARIF baselineState parsing, threshold filtering, multi-run
  merging, rule metadata attachment.
- TestLoadSarif: single file, directory merge, missing file, invalid JSON.
- TestAlertHelpers: Alert dataclass methods (icon, rule_display, severity_suffix).
- TestFormatSection / TestBuildComment: PR comment rendering including overflow,
  links, plural/singular forms, threshold interpolation, trailing newline.
- TestToAlertApi: all fields, both location formats (flat API and nested SARIF),
  message source, security severity, dismissed reason.
- TestPaginateAlertsApi: single/multi-page, early exit on partial page, empty
  first page, non-list error, ref forwarding.
- TestCompareAlertsViaApi: new/fixed/matched detection; min_level filtering of
  new alerts; fixed alerts NOT filtered (regression guard for the intentional
  asymmetry); prev-commit and base-SHA comparisons; API error handling; non-PR
  ref skips base fetch.
- TestBuildMultiSectionComment: vs_base/vs_prev rendering; fallback to vs-main
  when no context; blank-line preservation between sections; no double-render
  when detail is present; code-scanning link.
- TestSetOutputs / TestWriteSummary: GITHUB_OUTPUT and GITHUB_STEP_SUMMARY
  writing, missing-env no-ops, threshold interpolation regression.
- TestMainSarifMode: end-to-end new/fixed/no alerts; threshold suppression;
  multi-file SARIF directory; GITHUB_OUTPUT values.
- TestMainApiMode: end-to-end API mode with mocked GitHub API; min_level
  filtering; GitHubAPIError -> exit 2; missing GITHUB_REPOSITORY -> exit 2;
  SARIF baselineState suppresses API mode entirely.

All network calls are mocked via unittest.mock; no real GitHub API access is
required.  The tests are placed in scripts/test/ and are collected by the
'Generate scripts coverage report' step in .github/workflows/coverage.yaml,
contributing to the 'scripts' Codecov flag.
Four bugs and several usability gaps are fixed in scripts/sarif-alerts.py:

1. sys not imported at module level (NameError at runtime)
   'import sys' was inside the 'if __name__ == "__main__":' guard, so calling
   main() programmatically (e.g. from tests or another script) would raise
   NameError the first time a missing file was encountered and the error path
   tried to write to sys.stderr.  Moved to a module-level import.

2. No error handling for malformed or unreadable input files
   json.JSONDecodeError and OSError from _process_sarif propagated as raw
   tracebacks, aborting all remaining files.  _process_sarif now raises
   descriptive OSError / ValueError; main() catches them, prints a clean error
   to stderr, records the failure, and continues processing remaining files.
   main() returns exit code 1 if any file had errors, 0 otherwise.

3. Directory input not supported
   Users working with CI artifact directories had to enumerate every .sarif
   file manually.  Added _collect_sarif_paths() which expands directory
   arguments to the sorted list of .sarif files they contain (recursive), warns
   on empty directories, and passes plain file paths through unchanged.

4. No --level or --baseline filtering
   The primary use case for a SARIF inspection tool is to focus on specific
   alert categories (e.g. only 'new' alerts at 'warning' or above).  Added:
   - --level LEVEL  (none/note/warning/error, default: none -- show all)
   - --baseline STATE  (repeatable; e.g. --baseline new --baseline absent)
   Also added --max-message N (default 200) to truncate long messages for
   terminal readability, and whitespace collapsing of multi-line messages.

A test suite is added in scripts/test/test_sarif_alerts.py (39 tests + 1
conditionally skipped, across three test classes):

- TestCollectSarifPaths: file pass-through, directory expansion, recursive
  glob, empty-directory warning, mixed inputs, sorted order.
- TestProcessSarif: output format, location extraction (with/without line
  number, no locations), level and baseline filtering (exact, multiple, none),
  message truncation and whitespace collapsing, multiple runs, invalid JSON,
  non-object JSON, unreadable file (skipped on root), missing optional fields
  (message, ruleId, level, baselineState).
- TestMain: zero/one exit codes, missing file, bad JSON, output content, total
  line, --level and --baseline filtering, repeated --baseline, directory input,
  multiple files, per-file header line, partial failure (bad file does not
  prevent processing of remaining good files), empty SARIF, --max-message,
  module-level sys import assertion.
sarif-alerts.py
- Replace 'from typing import Iterable' with 'from collections.abc import
  Iterator' and annotate _process_sarif's return type as Iterator[str].
  Iterable is too broad for a generator function; Iterator is the precise type
  and eliminates the Pylance 'Return type ... is not assignable to declared
  return type' diagnostic.
- Replace 'key=_LEVEL_ORDER.get' in the --level help string with
  'key=lambda k: _LEVEL_ORDER[k]'.  dict.get returns T | None, which is not a
  valid sort key type; the lambda guarantees int and removes the Pylance
  'Argument of type ... is not assignable to parameter key' diagnostic.

test_sarif_alerts.py
- Consolidate stdlib imports into a single sorted block (os was added after
  the typing imports in a separate group, triggering an isort/Pylance ordering
  diagnostic).  Add 'import importlib.util' explicitly so the submodule is
  visible to type checkers without relying on implicit namespace resolution.
  Add 'from collections.abc import Callable, Iterator' to type the aliases.
- Add 'assert hasattr(_spec.loader, "exec_module")' before the exec_module
  call, making it clear to Pylance that the concrete loader supports the
  ExecutionLoader protocol; keep the existing '# type: ignore[union-attr]' as
  a belt-and-suspenders suppression.
- Annotate the _collect / _process / _main aliases with explicit Callable
  types so Pylance can type-check every call site rather than treating them as
  Unknown (the module is loaded via importlib, so its attributes are not in any
  stub).  Add '# type: ignore[attr-defined]' on each alias assignment to
  suppress the expected ModuleType attribute-not-found diagnostic.
- Remove the unused 'import sys as _sys' and 'import importlib as _il' from
  test_sys_not_imported_lazily; those names were never referenced in the test
  body, causing 'local variable is assigned but never used' diagnostics.
Two bugs in .github/workflows/coverage.yaml are fixed, dead code in
create_coverage_symlinks.py is removed, and unit tests are added for the
four Python coverage helper scripts that previously had no test coverage.

## Workflow fixes

### Invalid --omit argument in 'Generate scripts coverage report' step
pytest does not accept --omit as a CLI flag; it belongs to the coverage
tool and has no --cov-omit equivalent in pytest-cov.  Passing it caused
the step to fail immediately with 'unrecognised arguments', silently
swallowed as non-fatal (warning-only step).

Fix: removed --omit from the pytest invocation.  The omit pattern is
now declared in pyproject.toml under [tool.coverage.run], which
pytest-cov reads automatically via its --cov-config default.  A comment
explains why the relative glob works regardless of invocation directory.

### has_coverage_python_xml output not declared at job level
The coverage_outputs step emitted has_coverage_python_xml to
$GITHUB_OUTPUT, but the coverage job's outputs: block never declared
it.  Any downstream consumer of
needs.coverage.outputs.has_coverage_python_xml received an empty string,
making the output silently useless.

Fix: added has_coverage_python_xml to the job-level outputs: map so the
value propagates correctly to dependent jobs.

## Script fix: dead code in create_coverage_symlinks.should_link
The function checked path.suffix against the SUPPORTED_SUFFIXES set and
then repeated explicit checks for .c++, .h++, .icc, .tcc, .i, and .ii
via str.endswith and a second path.suffix in {...} guard.  All six of
those extensions are already members of SUPPORTED_SUFFIXES, so every
secondary branch was unreachable.  Collapsed to a single expression:
    return path.suffix in SUPPORTED_SUFFIXES

## New: scripts/test/conftest.py
Each of the four existing test files independently inserted scripts/ onto
sys.path at collection time, duplicating the mutation on every pytest run
that collected more than one file.  A new conftest.py performs the
insertion once (with a guard to avoid repeated entries), and all four
test files have had their sys.path.insert calls and the now-unused
'import sys' removed.

## New: scripts/test/test_coverage_scripts.py (71 tests)
Adds unit tests for the four coverage helper scripts that were invoked
only through CMake targets and had 0% Python test coverage:

  normalize_coverage_lcov.py (0% -> 81%)
    _relative_subpath: direct subpath, outside-base returns None, None
      base, symlink resolution
    _is_repo_content: accepted prefixes (phlex/, plugins/, form/,
      build-clang/, .coverage-generated), rejected unknown prefix and
      empty path
    normalize(): absolute SF rewritten to relative, external files
      excluded and reported, missing files reported, relative SF
      resolved via --coverage-root, --absolute-paths flag, records
      without SF preserved, empty SF value preserved, trailing lines
      without end_of_record handled without crash
    main(): success returns 0, missing file returns non-zero, external
      file warning written to stderr

  normalize_coverage_xml.py (0% -> 80%)
    _relative_subpath: subpath within base, outside-base None, None base
    normalize(): absolute path rewritten relative, external file
      reported, missing file reported, <source> element normalised,
      custom --source-dir, relative filename within coverage_root,
      --path-map applied, empty class list produces no errors
    main(): success returns 0, external returns non-zero, missing
      returns non-zero, invalid --path-map raises SystemExit, valid
      --path-map parsed without error

  export_llvm_lcov.py (0% -> 96%)
    build_parser(): returns ArgumentParser, required args parsed,
      empty llvm_cov_args list
    main(): success creates output file, parent directories created,
      CalledProcessError returncode propagated, missing args triggers
      SystemExit, assembled command matches expected argv

  create_coverage_symlinks.py (0% -> 92%)
    should_link(): .cpp/.h/.c/.icc/.tcc/.i/.ii/.cxx/.hpp accepted;
      .txt/.py rejected; directory rejected; nonexistent file rejected
    iter_source_files(): yields C/C++ files, recurses subdirectories,
      empty directory yields nothing
    create_symlinks(): symlinks created, non-source files skipped,
      output dir recreated if it exists, nested paths preserved,
      existing stale symlink replaced
    parse_args(): required args parsed, missing arg raises SystemExit
    main(): success returns 0 and creates symlinks, nonexistent build
      root returns 1
- Improve external and in-script documentation
- Improve help text and options
- Improve CodeQL alert output
- Minor code style issues
Comment thread scripts/test/test_clang_tidy_check_summary.py Fixed
Comment thread scripts/sarif-alerts.py Fixed
@greenc-FNAL
Copy link
Copy Markdown
Contributor Author

greenc-FNAL commented May 7, 2026

❌ 1 new CodeQL alert compared to main

  • Warning # 176 py/unused-global-variable at scripts/sarif-alerts.py:11:1 — The global variable '_KNOWN_LEVELS' is not used.

Review the full CodeQL report for details.

@greenc-FNAL greenc-FNAL force-pushed the maintenance/workflows-scripts-tests-fixes branch from 3f635c6 to 0d13857 Compare May 7, 2026 22:58
@greenc-FNAL greenc-FNAL changed the title maintenance/workflows scripts tests fixes Fix bugs in CI scripts and workflows; add test suites and improve documentation May 7, 2026
@greenc-FNAL greenc-FNAL marked this pull request as ready for review May 7, 2026 23:04
greenc-FNAL and others added 2 commits May 7, 2026 18:05
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
…ring sanitization'

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR improves CI reliability and developer tooling by fixing GitHub Actions workflow issues, hardening/expanding several Python helper scripts used in CI, and adding substantial unit test coverage plus updated documentation for script utilities.

Changes:

  • Fix multiple CI workflow/script bugs (coverage workflow args/outputs; CodeQL + SARIF handling; clang-tidy workflow reporting).
  • Add/expand Python test suites under scripts/test/ and centralize test import setup via conftest.py.
  • Improve script documentation and CLI usability (README/quick reference, richer argparse help, docstrings).

Reviewed changes

Copilot reviewed 24 out of 25 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
scripts/test/test_sarif_alerts.py New tests covering SARIF directory expansion, filtering, message truncation, and main() behavior.
scripts/test/test_fix_header_guards.py New tests for header-guard checking/fixing and workflow-style invocations.
scripts/test/test_coverage_scripts.py New tests for coverage helper scripts (lcov/xml normalization, llvm export wrapper, symlink helper).
scripts/test/test_codeql_reset_dismissed_alerts.py New tests for CodeQL dismissed-alert reset tool (API mocking, pagination, CLI).
scripts/test/test_clang_tidy_fixes_to_problems.py New tests for clang-tidy fixes → gcc-style problem output converter.
scripts/test/test_clang_tidy_diff_issues.py Remove per-file sys.path mutation; rely on shared pytest conftest.py.
scripts/test/test_clang_tidy_check_summary.py New tests for clang-tidy checklist summarizer (parsing, formatting, CLI).
scripts/test/test_check_codeql_alerts.py New comprehensive tests for CodeQL alert comparison/comment generation (SARIF + API modes).
scripts/test/conftest.py New session-level sys.path insertion for importing scripts/ modules in tests.
scripts/sarif-alerts.py Add directory support, filtering options, improved error handling, and CLI enhancements.
scripts/README.md Add detailed “Developer Tools” documentation and usage examples.
scripts/QUICK_REFERENCE.md Add quick-reference entries for new developer tool scripts.
scripts/normalize_coverage_lcov.py Use explicit UTF-8 encoding for reading/writing.
scripts/fix_header_guards.py Use explicit UTF-8 encoding for reading/writing.
scripts/create_coverage_symlinks.py Simplify should_link() by relying on SUPPORTED_SUFFIXES only.
scripts/codeql_reset_dismissed_alerts.py Improve docstrings/CLI help and include alert URLs in output; refactor request/pagination details.
scripts/clang_tidy_fixes_to_problems.py Expand documentation/help text and clarify behavior; minor refactors and output wording.
scripts/clang_tidy_check_summary.py Expand documentation/help text and clarify checklist generation behavior.
scripts/check_codeql_alerts.py Fix API message extraction, pagination, threshold handling, and comment formatting; add fallback comment rendering.
pyproject.toml Configure ruff isort first-party modules for scripts/ and move coverage omit patterns into coverage config.
.gitignore Ignore .coverage file produced by coverage tooling.
.github/workflows/coverage.yaml Fix pytest invocation, add missing job output, and add completion comment/reaction update job.
.github/workflows/cmake-build.yaml Add permissions and completion reaction update step.
.github/workflows/clang-tidy-check.yaml Add “no issues found” comment and completion reaction update; wire action output for content detection.
.github/actions/post-clang-tidy-results/action.yaml Add has_content output for downstream workflow conditional behavior.

Comment thread scripts/test/test_sarif_alerts.py Outdated
Comment thread scripts/sarif-alerts.py
Comment thread scripts/sarif-alerts.py
Reported issue:

```
scripts/test/test_sarif_alerts.py:509: error: Argument 1 to "Path" has incompatible type "str | None"; expected "str | PathLike[str]"  [arg-type]
```
@codecov
Copy link
Copy Markdown

codecov Bot commented May 7, 2026

Codecov Report

❌ Patch coverage is 97.34513% with 3 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
scripts/sarif-alerts.py 95.38% 3 Missing ⚠️
@@            Coverage Diff             @@
##             main     #573      +/-   ##
==========================================
+ Coverage   85.39%   85.60%   +0.20%     
==========================================
  Files         145      156      +11     
  Lines        3711     5355    +1644     
  Branches      646      646              
==========================================
+ Hits         3169     4584    +1415     
- Misses        329      556     +227     
- Partials      213      215       +2     
Flag Coverage Δ
scripts 86.25% <97.34%> (?)
unittests 85.60% <97.34%> (+0.20%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
scripts/check_codeql_alerts.py 84.01% <100.00%> (ø)
scripts/clang_tidy_check_summary.py 97.10% <ø> (ø)
scripts/clang_tidy_fixes_to_problems.py 89.17% <100.00%> (ø)
scripts/codeql_reset_dismissed_alerts.py 99.03% <100.00%> (ø)
scripts/create_coverage_symlinks.py 92.15% <100.00%> (ø)
scripts/fix_header_guards.py 98.07% <100.00%> (ø)
scripts/normalize_coverage_lcov.py 81.21% <100.00%> (ø)
scripts/sarif-alerts.py 95.23% <95.38%> (ø)

... and 6 files with indirect coverage changes


Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 57d80b1...3fedfa2. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

- Remove unused bare 'import importlib' from test_sarif_alerts.py
  (only importlib.util is used; import importlib.util is sufficient)
- Fix --level choices order: use list(_LEVEL_ORDER) so argparse presents
  levels in severity order (none/note/warning/error) rather than
  alphabetical order (error/none/note/warning)
- Add _positive_int() argparse type for --max-message to reject values
  less than 1, preventing incorrect truncation behaviour with 0 or
  negative inputs
Comment thread scripts/sarif-alerts.py Fixed
greenc-FNAL and others added 2 commits May 7, 2026 23:36
- W0212 (protected-access): wrap _collect_sarif_paths and _process_sarif
  alias assignments in a pylint disable/enable block; accessing private
  symbols is intentional in this test module
- C0301 (line-too-long): suppress with disable-next=line-too-long; ruff
  refuses to break the line because the overflow comes from a trailing
  # type: ignore comment it cannot move
- C1803 (use-implicit-booleaness-not-comparison): replace
  'list(_process(f)) == []' with 'not list(_process(f))'
- W0613 (unused-argument): remove the unused 'capsys' parameter from
  test_returns_zero_on_success (the fixture is not referenced in the
  test body)
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
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.

3 participants