Cheat notes · Module 06 · Golden paths and docs
Golden paths with software templates
A five-minute review for when you have done this module and want it back in your head. Open the full module for the steps and the lab, or the full text to print.
The idea
A template makes the right way the easy way: a form (parameters), actions run on the backend (steps), and links (output). The service starts with an owner, a system, docs and a catalog entry from its first commit.
Remember
- Parameters: JSON Schema with
ui:hints, one form page per item. Each property becomesparameters.<name>. Pickers (OwnerPicker,EntityPicker,RepoUrlPicker) read the catalog. - Steps: each runs one action on the backend with the backend's credentials:
fetch:templaterenders the skeleton,publish:githubcreates the repo,catalog:registeradds it. Outputs feed later steps:steps['publish'].output.repoContentsUrl. - Skeleton: files with
${{ values.x }}placeholders, rendered with Nunjucks byfetch:template. - Templates are entities: registered through a location that allows
Template, owned by the platform team. - Dry run: the template editor (Create, ⋮, Template Editor) runs steps without side effects and shows files, log and output. Actions without dry-run support are skipped.
Pitfalls
- Removing a value from the
fetchstep that "looks unused": the template still runs, and the rendered file hassystem:with nothing after it. Dry-run every template in CI and assert key fields. - Shipping a clever first template nobody needs. Start with the service type teams create most often.
Commands
curl -s -H "Authorization: Bearer $PORTAL_API_TOKEN" "localhost:7007/api/catalog/entities?filter=kind=template" | jq -r '.[].metadata.name' | Which templates the catalog has |
gh repo view OWNER/cart --json name,description | The repo the template created |
The skeleton of a template
spec:
parameters:
- title: About the service
required: [name, owner]
properties:
owner:
type: string
ui:field: OwnerPicker
ui:options:
catalogFilter: { kind: Group, spec.type: team }
steps:
- id: fetch
action: fetch:template
input:
url: ./skeleton
values:
owner: ${{ parameters.owner }}
- id: publish
action: publish:github
- id: register
action: catalog:register
input:
repoContentsUrl: ${{ steps['publish'].output.repoContentsUrl }}
Test yourself
Answer in your head first, then open the answer.
Where do template steps run?
On the backend, with the backend's credentials, one action per step.
What does a dry run in the template editor do?
Runs the steps without side effects and shows the rendered files, the log and the output.
Why does the owner field use OwnerPicker with a catalogFilter?
It only offers teams that exist, so an owner typo is impossible.
Where module 06 leaves you: The portal offers one template, Node.js service. A cart repo exists on GitHub, created by the template and already in the catalog, owned by team-checkout.