Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

README.md

Generated configuration reference

This directory holds the config and secrets reference for every CCV app, one *.documented.toml file per config/secrets structure:

App Files
executor executor/config.documented.toml
aggregator aggregator/config.documented.toml, aggregator/secrets.documented.toml
committee verifier verifier/committee/config.documented.toml
token verifier verifier/token/config.documented.toml
verifier (shared) verifier/secrets.documented.toml
indexer indexer/config.documented.toml, indexer/secrets.documented.toml
bootstrap bootstrap/config.documented.toml, bootstrap/secrets.documented.toml
monitoring (shared) common/monitoring.documented.toml

Each file is a working TOML document: the values are the app's defaults where a default exists, and illustrative examples otherwise, and every field is annotated with its Go doc comment.

These files are generated — do not edit them

Every file carries a # Code generated by tools/configdoc. DO NOT EDIT. header. The single source of truth is the Go doc comment on each config struct field. To change what a field's documentation says, edit the doc comment on the struct (e.g. in executor/config.go, common/monitoring/config.go), then regenerate:

just config-docs

CI enforces freshness and completeness

TestConfigDocsFresh (in tools/configdoc) runs on every PR as a normal unit test (it has no Docker/DB dependency — it regenerates each doc in memory and diffs it against the committed file). CI fails if:

  • a committed file is out of date — you changed a struct or a doc comment but didn't run just config-docs; or
  • a documented field is missing a doc comment — the generator refuses to emit a field it can't describe.

In both cases the fix is the same: add the missing comment and/or run just config-docs, then commit the result.

Adding a new app (or config structure)

The generic engine lives in tools/configdoc; this repo's target list lives in tools/configdoc/registry. To document a new structure:

  1. Write a New() builder in tools/configdoc/registry that returns a fully-populated, valid instance of the config/secrets struct. Populate required fields with illustrative values, run the app's real defaulting routine if it has one (so defaults appear), and pin any non-deterministic values (e.g. hostnames) so the output is stable. Allocate pointer sub-structs you want documented — the encoder omits nil.
  2. Register a configdoc.Target in the Targets slice, giving it a Name, an output path under docs/config/, and its Kind (configdoc.KindConfig or configdoc.KindSecrets).
  3. Run just config-docs and commit the new file.

The generator TOML-encodes the instance and injects each field's Go doc comment, so there is no per-app rendering code to write — only the builder and the doc comments on the struct.

Reusing from another repo

tools/configdoc is a repo-agnostic engine. A repo that already depends on the chainlink-ccv module (e.g. a chain-specific integration) can import it directly and document its own config structs — no fork or copy:

g, err := configdoc.NewGenerator(cwd) // walks up to the enclosing go.mod
targets := []configdoc.Target{
    {Name: "canton", Out: "canton/config.documented.toml", Kind: configdoc.KindConfig, New: func() any { return newCantonConfig() }},
}
_, err = g.Write(targets, "docs/config")   // generate
stale, err := g.Check(targets, "docs/config") // verify (use in a freshness test / CLI -check)

NewGenerator auto-detects the module path and root, so nothing is hardcoded.

Doc comments come from source for a type that module declares, and from the DocComments method a dependency generated for one it does not — generation writes a doccomments_gen.go beside every documented type for exactly that reason, and those files are committed. A nested type from another module is therefore fine, as long as that module generates too; one that has never generated has no comments to read, and the completeness gate fails on its fields.