Skip to content

ci(format): pin cppcheck via uvx and make it blocking - #28

Open
sqr00t wants to merge 1 commit into
docs/cpp-format-policyfrom
ci/cppcheck-pinned
Open

ci(format): pin cppcheck via uvx and make it blocking#28
sqr00t wants to merge 1 commit into
docs/cpp-format-policyfrom
ci/cppcheck-pinned

Conversation

@sqr00t

@sqr00t sqr00t commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

Closes #27.

Completes the cpp job that #21 started. cppcheck now blocks, is version-pinned, and comes from
PyPI rather than apt — the job installs nothing from the system at all.

Why not just pin apt

You spotted the symptom today: the cppcheck install wedged for over an hour on three separate
runs
(#15, #22, #16) while the identical job finished in 20–70 seconds elsewhere. Pinning the apt
version would not have helped — Ubuntu carries only whatever its archive holds for a given runner
image, so the pin would be dictated by the image rather than chosen, and the reliability problem
would remain.

2cc6320 already capped it at 5 minutes and made it non-fatal. That stopped a wedge from taking the
blocking clang-format result down with it, but it treats the symptom. This removes the cause.

What changed

Before After
sudo apt-get update && apt-get install -y cppcheck uvx --from cppcheck==1.5.1 cppcheck (Cppcheck 2.17.1)
Unpinned — a runner-image bump could add diagnostics Pinned, same pattern as ruff@0.14.10 and clang-format@22.1.8
Advisory (continue-on-error) Blocking
Default check level --check-level=exhaustive

On --check-level=exhaustive: it is not decoration. At the default level cppcheck emits an
informational normalCheckLevelMaxBranches notice on energy_build.cpp, and --error-exitcode=1
counts that as a failure — so the job would go red on a notice rather than a defect. The options were
to suppress the notice or to actually analyse every branch. Analysing is the honest fix, and on a
1,231-line src/ it costs nothing measurable.

On scope: clang-format checks two files, cppcheck checks all of src/. That asymmetry is
deliberate and now stated in ADR 0010 — analysis reads the sources, it does not rewrite them, so
it does not threaten the byte-identity that ADR 0002 protects. The consequence is recorded too: a
genuine cppcheck finding in an upstream file cannot be fixed locally, it has to go upstream.

Verification

Run locally on this branch, all from the pinned versions CI uses:

uvx clang-format@22.1.8 --dry-run --Werror src/shim.hpp src/bindings.cpp   # clean
uvx --from cppcheck==1.5.1 cppcheck --enable=warning,portability \
  --check-level=exhaustive --suppress=missingIncludeSystem \
  --error-exitcode=1 src/                                                  # exit 0
uv run pytest -q                                                           # 30 passed

Documentation in the same PR

Unlike #21, the code and its documentation land together, so no intermediate commit describes the
wrong behaviour:

  • ADR 0010 — Decision gains the cppcheck pin; two new Consequences (two more pinned versions to
    maintain; uvx/PyPI now on the critical path instead of apt); a new rejected alternative
    (pinned apt); and the "upstream files are unchecked" line corrected, since they are analysed now
  • CONTRIBUTING.md — the CI table row, with the exact local reproduction command
  • ONBOARDING.md — both places that called it advisory
  • docs/runbooks/ci-triage.md — section 5 rewritten, plus a new "if cppcheck fails" branch
    covering the upstream-file case and the exhaustive-flag trap
  • docs/ROADMAP.md — task 3.4 struck through as done; only 3.1 remains in Phase 3

Stack

Top of the chain, above #22.

main
 └── fix/gcc-cpp-compat            #10
      └── docs/adr-records         #15
           └── docs/runbooks       #16
                └── docs/roadmap-and-rust-port  #17
                     └── docs/entry-documents   #18
                          └── docs/cpp-format-policy  #22
                               └── ci/cppcheck-pinned  ← this PR

Completes the cpp job. cppcheck now comes from PyPI (cppcheck==1.5.1,
Cppcheck 2.17.1) via uvx rather than apt, and blocks like clang-format does.

Moved off apt rather than merely pinned: the apt install wedged for over an
hour on three separate CI runs, and Ubuntu only carries whatever version its
archive holds, so the pin would have been dictated by the runner image.
The job now installs nothing from the system at all.

--check-level=exhaustive is required: at the default level cppcheck emits an
informational normalCheckLevelMaxBranches notice on energy_build.cpp, which
--error-exitcode=1 treats as a failure. Analysing every branch is the honest
fix; suppressing the notice is not.

Updates ADR 0010, CONTRIBUTING, ONBOARDING, the ci-triage runbook and closes
roadmap task 3.4.
sqr00t added a commit that referenced this pull request Aug 19, 2026
…itory

Changes what ADR 0009 is deciding. Strategies (a) and (b) in rust-port.md both
assumed an in-tree port and priced permanent divergence from upstream bw into
the first day's work; an out-of-tree port defers that cost entirely, so
ahl_dwc pays none of it while the exploration proceeds.

The live question narrows from "should we port" to "under what conditions
should ahl_dwc adopt an external implementation". The precondition is
unchanged and now matters more: adoption is judged solely on reproducing the
golden values within PHYS_RTOL, and there are four golden endpoints today.

Also corrects two claims overtaken by PR #28 — ADR 0009 called clang-format
and cppcheck permanently advisory, and rust-port.md's pain table still had
cppcheck pending a pin.

The external repository is not named: recorded from a verbal note with no link
available. Flagged in ADR 0009 as to be filled in.
@sqr00t
sqr00t force-pushed the ci/cppcheck-pinned branch from e9f13b7 to 81fd200 Compare August 19, 2026 17:40
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