1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// Template rendering powered by Tera.
// Supports both Go-style `{{ .Field }}` and Tera-style `{{ Field }}`.
// Go-style templates are preprocessed (leading dots stripped) before Tera renders them.
// Tera gives us: if/else/endif, for loops, pipes (| lower, | upper, | replace),
// | default, | trim, | title, and many more built-in filters.
//
// ## Template-render-error handling policy
//
// **Hard-bail on any user-supplied template render error.**
//
// Silently falling back to the raw template string (or to an empty value) on a
// render failure has burned users repeatedly: a typo like `{{ .Teg }}` in a
// signature path is rendered-as-literal and the signer is invoked with a path
// that doesn't exist, producing a confusing downstream error rather than a
// clear template diagnostic.
//
// Callers that render user-supplied templates (config fields, hook commands,
// signing args, release header/footer, etc.) MUST propagate the
// `render_template` / `render` error via `?` or `.with_context(...)?`. If you
// see `.unwrap_or_else(|e| { log.warn(...); raw.clone() })` in lib code,
// convert it to a bail with a stage-named context message.
//
// The single exception is `render_template_opt` for purely internal defaults
// (e.g. "default icon url") where a render-failure genuinely has a sensible
// fallback — those sites should be rare and commented.
//
// Enforcement: code review + the `anti-patterns.md` hook (which already
// forbids `.unwrap()` in lib code, catching most drift automatically).
pub use ;
pub use ;
pub use ;