Build the configuration
Answer what your deployment is, and this writes the three things that run it:
the config.yaml a normal run reads, the command that runs it, and the step a
workflow gives the composite Action. All three come from one set of answers,
and none of them asks for a credential.
Why it cannot drift
Section titled “Why it cannot drift”The controls are not a copy of the settings. cmd/gen_config exports
internal/config’s own types into a file the page reads, down to the default
each key resolves to, which it measures by validating a probe rather than by
restating a number. make check-config-options fails when that file is no
longer what the code produces, in the analysis suite and in CI, so the form
cannot offer a setting the binary does not have and cannot miss one it does.
The other direction is checked too, and its limit is worth saying out loud. The
configurations this form writes for the answer sets in
internal/config/testdata/config-cases.json go through the real parser in
internal/config’s own tests, including the shapes that have caught people out:
a cadence per family under every.families, an include_private left off, a
sink whose credentials are ${VAR} references, a card-only run with no
destination at all, and answers the parser is expected to refuse. Those cases
are generated by the module this page runs, so they cannot be a copy of it, and
every branch of that module that can change what it writes has one. What the
corpus does not prove is behaviour no answer set produces, which is why the
file that owns it lists what it cannot cover and why.
What the form allows and the parser refuses
Section titled “What the form allows and the parser refuses”A form is a form: a destination is a checkbox and the keys it cannot resolve without are not, so a few clicks are enough to write a file that dies at start-up. The page warns about the ones its own generated list of settings can see, above the outputs, and names the rest here. Refusing the rest in the form would mean keeping a second copy of a parser rule on this page, which is the drift the whole arrangement exists to avoid.
- A destination switched on with a required key left empty is refused by name,
with an example:
sinks.loki: url is required, for example http://loki:3100. The form warns about this one. - A credential field answered with the credential instead of the name of an environment variable is left out of the file. The form warns about this one.
- A file with nothing in it is refused:
the file is empty. - No account at all is refused:
targets: set at least one of user, orgs or repos. heartbeat: 0is refused: it must be positive, and leaving the key out is how the loop’s tick is derived instead.- A cadence that is not a duration is refused where it is used:
every.families.repo: time: invalid duration "soon". sinks.elasticsearch.api_keyfilled in besidesinks.elasticsearch.usernameis refused:sinks.elasticsearch: set either api_key or username and password, not both.- Writing
-assinks.sql.pathwhilesinks.stdoutis on is accepted and gives two writers one stream; pick one of them.
The form
Section titled “The form”The account and its API5
What to collect7
Where the points go50
influxdb
prometheus
otlp
loki
file
telegraf
graphite
sql
elasticsearch
How often3
The run's own log5
The run4
What these answers get wrong
config.yaml
Save this beside the binary, or at the path you give to -config, and run it with the command below.
github:
token: ${GITHUB_TOKEN}
targets:
user: octocat
sinks:
stdout: true
The command that runs it
ghchronicle -config config.yaml -once
Workflow step
Paste this into the steps of a workflow job. The token is a repository secret, never a value in the file.
- uses: jmrplens/ghchronicle@v1
with:
token: ${{ secrets.GHCHRONICLE_TOKEN }}
config: .github/ghchronicle.yaml
A credential field takes the NAME of an environment variable, and the file gets ${NAME}, which the binary expands at start-up. An answer that is not a variable name is left out of the file rather than written into it. The headers field is the exception: it is free text, and whatever is typed there is written as it stands.
What to do with each output
Section titled “What to do with each output”There is not one command, which is why the form writes it. A configuration that
names a destination is run with -once. A configuration that names none is
refused by -once, with the parser asking for a sink you deliberately did not
want, so it is run with -card-only and a path for the card instead. The
command above changes with the answers, and so does the step.
The step goes in the steps: of a workflow job. Answers no input can carry make
the step read the file, and the file has to be committed at the path the step
names; answers the four inputs can carry are written into the step itself, and
then there is no file at all. A step with no file that names no destination is a
card run, mode: card with a card: path, because that is the one thing the
Action turns into -card-only.
The two outputs default the opposite way on one setting, and the step is written
so it says which one you are getting. include-private is off unless you ask
for it, because a card that counts private repositories names them in a public
README; targets.include_private is on unless you say otherwise, because the
token already reaches them. So a file-less step always writes the input out
rather than leaving it to a default that means the opposite of the file beside
it. See GitHub Actions for the workflow around
it, and the token for what the secret needs to be
able to do.
The rest
Section titled “The rest”- The file: what each block is for, and what happens when a value is wrong.
- Targets: which repositories.
- Cadences: every family, its group and its built-in interval.
- Choosing a store: one page per destination.