Skip to content

feat(ci): enforce lowerCamelCase and max depth in reference.conf#6792

Open
bladehan1 wants to merge 1 commit into
tronprotocol:developfrom
bladehan1:ci/reference-conf-gate
Open

feat(ci): enforce lowerCamelCase and max depth in reference.conf#6792
bladehan1 wants to merge 1 commit into
tronprotocol:developfrom
bladehan1:ci/reference-conf-gate

Conversation

@bladehan1
Copy link
Copy Markdown
Collaborator

What does this PR do?

Adds a CI gate that validates common/src/main/resources/reference.conf on every PR / push:

  • Every dot-separated segment of every key must match ^[a-z][a-zA-Z0-9]*$ (lowerCamelCase).
  • Total path depth must be ≤ 6 (current max in tree is 5; +1 buffer).
  • Four legacy PBFT keys are grandfathered via an explicit ALLOWLIST.
  • Array steps count toward depth (each [] = +1 level); nested arrays (HOCON list-of-list) are supported.

Implementation: .github/scripts/check_reference_conf.py using pyhocon (reference Python HOCON parser), wired into the existing checkstyle job in .github/workflows/pr-check.yml. Violations produce per-line stdout output plus one consolidated ::error file=...,title=reference.conf::... GHA annotation so failures show up in the PR check summary.

Why are these changes required?

reference.conf is the single source of default values for every config key in java-tron, and key names must auto-bind to XxxConfig.java bean fields via Typesafe Config's ConfigBeanFactory — which requires lowerCamelCase. Today the file has drifted: 4 PBFT keys violate the rule and the file header documents legacy exceptions handled via manual normalization. Without a gate, new contributors keep adding non-conforming keys, and silent binding failures accumulate.

A depth ceiling also prevents deeply nested hierarchies from creeping in; the current max is 5, so 6 leaves a one-level buffer for new keys without silently allowing further drift.

This PR has been tested by:

  • Manual Testing: ran the script against the real reference.conf — passes with 294 keys, all lowerCamelCase, max depth 5.
  • Built a local fixture suite (not committed) covering: empty / simple / dotted-form / at-max-depth / object array / scalar array / allowlist / format violations (Pascal / snake / digit / array-internal / non-allowlisted acronym) / depth violations (dotted + in-array) / combined + dedup invariant / env errors (parse failure, missing file). 20 assertions PASS.
  • Verified: parse failure (invalid HOCON) and missing file both exit 2 with ::error annotation; a single user-declared deep key produces exactly one depth violation line (leaf-only filtering).

Follow up

  • Sunset the 4 PBFT entries in ALLOWLIST via a rename + deprecation cycle (out of scope here — would break existing user config.conf files).
  • Bean-field ↔ key parity gate (each new reference.conf key must have a matching XxxConfig.java field) is an orthogonal concern.

Extra details

  • Allowlist exempts 4 legacy keys to keep user config.conf compatible: node.http.PBFTEnable, node.http.PBFTPort, node.rpc.PBFTEnable, node.rpc.PBFTPort.
  • Library choice: pyhocon over Typesafe Config because the gate runs before Gradle/JDK setup in CI (~3 steps: setup-python + pip install + invoke). Both implement the HOCON spec; outputs are equivalent.

Add a CI gate that scans common/src/main/resources/reference.conf and
fails the build when any key violates lowerCamelCase
(^[a-z][a-zA-Z0-9]*$ per dot-separated segment) or exceeds the maximum
hierarchy depth (6). Array element keys are validated the same way;
each array step counts as one depth level — e.g. an inner field at
`rate.limiter.rpc[].component` is depth 5.

Parsing is delegated to pyhocon, the reference Python HOCON
implementation. It returns a fully-merged ConfigTree where dotted-form
keys expand into nested objects — the same canonical key set Typesafe
Config and ConfigBeanFactory see at runtime — and handles
triple-strings, substitutions, includes, +=, and block comments
without us re-implementing the grammar.

Four legacy PBFT* keys are grandfathered via an in-script allowlist
so the gate fails only on new violations. A consolidated GHA error
annotation lists every offending key, and sys.exit(1) drives step
failure. The script also accepts `--debug` to print every parsed key
with its depth (trailing `/` marks namespace intermediates) for
manual verification against the source file.

Runs as a new step in the existing checkstyle job of pr-check.yml
(setup-python + `pip install pyhocon`), so no extra runner spin-up.
@github-actions github-actions Bot requested a review from halibobo1205 May 20, 2026 10:38
@bladehan1 bladehan1 requested a review from 317787106 May 20, 2026 10:42
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