Skip to content

docs(examples): fill the outputs of the examples with examples-gen, and add the new examples - #191

Merged
tampakrap merged 4 commits into
crossplane-contrib:mainfrom
tampakrap:theo/docs_examples
Oct 24, 2026
Merged

tampakrap merged 4 commits into
crossplane-contrib:mainfrom
tampakrap:theo/docs_examples

Conversation

@tampakrap

@tampakrap tampakrap commented Oct 24, 2026 •

Copy link
Copy Markdown
Collaborator

Adds examples-gen, a small tool that fills the outputs of examples/README.md by running the commands, and uses it to add and regenerate the examples:

  1. feat(examples): introduce examples-gen…
    • A command in a code block that is followed by <output> is run, and its output replaces the placeholder.
    • --regenerate-all and --regenerate-match redo existing outputs.
    • A comment <!-- examples-gen: v1 --> before a block, together with --tag=v1, selects the outputs that depend on the Crossplane CLI v1.
    • earthly --allow-privileged +regen-examples runs it in Docker-in-Docker with the Crossplane CLI v2, and then with v1. Each run saves its own copy of the README, and merge-examples.sh combines them with a three-way merge. It fails if the two copies change the same lines, which is never expected to happen either way.
    • docs/contributing/examples-gen.md and CONTRIBUTING.md explain how to use it.
  2. docs(examples): add the new examples, with placeholders…
    • New and changed examples: Check Your Setup (xprin check, v2 and v1). The --artifacts-dir export. A validation-failure example. --no-container-reuse. patches.xrd with a legacy XRD, which behaves differently on CLI v1 and v2. Needs mistakes and invalid needs. The update-goldens workflow.
    • Examples vs e2e: the examples have their own files and no longer reference 0_e2e. The e2e tests use them instead.
  3. chore(examples): Regenerate everything: all the outputs, generated with the tool.
  4. chore(earthly): drop the redundant BUILDs…: the BUILD lines in e2e-regen-expected that the COPYs already imply.

…mples

The outputs of the examples in examples/README.md are pasted by hand, so
they go stale with every change of the output.

examples-gen reads a markdown file and, for each command of a code block
(a line that starts with "➜ ") that is followed by the line "<output>",
runs the command and puts its output (stdout and stderr) in place of the
placeholder. A block without a placeholder is not touched. With
--regenerate-all, or --regenerate-match=<text> for the commands that
contain the text, it first puts the placeholder in place of the existing
outputs, so that they are generated again in the same run. It doesn't
change what the commands print: whoever runs it reviews the diff.

Some outputs depend on the Crossplane CLI. A code block with a tag, in
a comment on the line before it (<!-- examples-gen: v1 -->), is filled
only with --tag=v1, and a block without a tag only without it.

`earthly --allow-privileged +regen-examples` runs it in
Docker-in-Docker, with yq and dyff (the hooks of the examples use them),
from the same working directory that the README shows in the absolute paths, and
exports only examples/README.md. It runs the examples with the current
Crossplane CLI (the untagged blocks) and with v1 (the tagged blocks), in
two targets (regen-examples-v2 and regen-examples-v1) that export their
own copy of the README. As the two copies change different blocks,
merge-examples.sh puts them together with a three-way merge, and fails
when the changes overlap. REGENERATE_ALL and REGENERATE_MATCH are the
arguments of the target for the two options.

docs/contributing/examples-gen.md explains how to run it both ways, and
CONTRIBUTING.md points to it.

Signed-off-by: Theo Chatzimichos <tampakrap@gmail.com>
…puts

New in examples/README.md:
- Check Your Setup: xprin check, which tells the Crossplane CLI that
  xprin detected (v2 and v1 outputs)
- Example 1: the external artifacts exported with --artifacts-dir, and
  what is in the directory
- Basic Examples, Example 4: the two ways that the validation fails, in
  one test case: an XR with a value that its XRD doesn't allow, and the
  CRDs of the provider that are not given
- Multiple Test Cases, Example 1: --no-container-reuse, compared with the
  default, where the first test case pays for the images and the
  container and the next ones reuse them
- Patching XRs, Example 1: patches.xrd with a legacy XRD, and how it
  differs between the Crossplane CLI v2 (--xrd of render) and v1 (xprin
  applies the defaults of the XRD), with the output of both. It replaces
  the example of the XRD defaults, which doesn't fail on a CLI that
  validates with the defaults
- Chained Tests, Examples 6 and 7: the mistakes in the use of needs, and
  the needs that make the file invalid
- Assertions, Example 3: the update-goldens workflow, from deleting the
  golden files to the file that it generates. It comes first, as the
  next example, the diff and dyff assertions (Example 4, which was
  Example 3), runs against the golden files that it generates: it points
  to it, instead of to a commented-out test that is not in the file any
  more

Updated the e2e tests to use the new examples as well.

Signed-off-by: Theo Chatzimichos <tampakrap@gmail.com>
It's been a while, so let's regenerate everything to see the new
improved times, the new paths and the updated debug outputs.

Signed-off-by: Theo Chatzimichos <tampakrap@gmail.com>
e2e-regen-expected has a BUILD and a COPY of the artifact for each of the
three CLI tiers. The COPY already builds the target, and the targets
don't export anything with AS LOCAL that only the BUILD would, so the
BUILDs do nothing, thus removing them.

Signed-off-by: Theo Chatzimichos <tampakrap@gmail.com>
@tampakrap
tampakrap merged commit 4677e24 into crossplane-contrib:main Oct 24, 2026
7 checks passed
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