Skip to content

Template Function Reference

Fábio Luciano edited this page Jun 22, 2026 · 1 revision

Template Function Reference

Templates use Go text/template with two layers of functions: a sprig subset for general-purpose string/date/math operations, and domain-specific helpers for provider-aware cross-references. This page documents every available function, its signature, and examples.

Function availability by notifier

Not all notifiers get the same functions. Before using a function, check whether your target notifier supports it.

Function category SCM comments Grafana Jira Accumulator Slack Teams Discord Email
Sprig subset
Domain helpers

Slack, Teams, Discord, and Email use plain Go templates. Use printf for formatting, if/range/eq for logic, and manual string construction for everything else.

Domain helpers

These functions are defined by the relay and take precedence over any sprig equivalents. They produce provider-aware output.

IssueRef

IssueRef(provider string, issueNum int, owner string, repo string) string

Returns the provider-specific markdown syntax for referencing an issue.

Provider Same-repo output Cross-repo output
github #42 owner/repo#42
gitlab #42 owner/repo#42
gitea #42 owner/repo#42
bitbucket_cloud #42 owner/repo#42
bitbucket_server #42 owner/repo#42
azure_devops #42 #42 (no cross-repo)
sourcehut "" (not supported) ""

Examples:

{{ IssueRef .Provider 42 "" "" }}

Renders #42 on most providers, empty string on SourceHut.

{{ IssueRef .Provider 42 "acme" "backend" }}

Renders acme/backend#42 on GitHub/GitLab/Gitea/Bitbucket, #42 on Azure DevOps.

Guard usage (safe to call even when IssueNumber is nil):

{{ if .IssueNumber }}Related: {{ IssueRef .Provider .IssueNumber .Repo.Owner .Repo.Name }}{{ end }}

PRRef

PRRef(provider string, prNum int, owner string, repo string) string

Returns the provider-specific syntax for referencing a pull request or merge request.

Provider Same-repo output Cross-repo output
github #42 owner/repo#42
gitlab !42 owner/repo!42
gitea #42 owner/repo#42
bitbucket_cloud #42 owner/repo#42
bitbucket_server #42 owner/repo#42
azure_devops #42 #42 (no cross-repo)
sourcehut "" (not supported) ""

Note the GitLab difference: merge requests use ! instead of #.

Examples:

{{ PRRef .Provider 123 "" "" }}

Renders #123 on most providers, !123 on GitLab.

{{ PRRef .Provider 123 "acme" "frontend" }}

Renders acme/frontend!123 on GitLab, acme/frontend#123 on GitHub/Gitea/Bitbucket.

UserMention

UserMention(provider string, username string) string

Returns the provider-specific syntax for mentioning a user. All supported providers use @username.

Provider Output
github @alice
gitlab @alice
gitea @alice
bitbucket_cloud @alice
bitbucket_server @alice
azure_devops @alice
sourcehut alice (no mention syntax)

Example:

Assigned to {{ UserMention .Provider "alice" }}

Truncate

Truncate(s string, limit int) string

Rune-aware truncation with ... suffix. Counts runes (Unicode characters), not bytes, so multi-byte characters like emoji don't cause issues.

  • If limit is 0, returns the original string (no limit).
  • If the string is shorter than the limit, returns it unchanged.
  • If truncated, appends ... (consuming 3 characters of the limit).
  • If limit is less than 3, truncates without the ellipsis.

Examples:

{{ Truncate .Description 200 }}

If Description is 250 characters, returns the first 197 characters followed by ....

{{ Truncate .Description 300 }}

If Description is 250 characters, returns the full string unchanged.

{{ Truncate "short" 200 }}

Returns short (already under the limit).

Sprig functions (safe subset)

The relay starts with sprig's full TxtFuncMap and removes dangerous functions. Here are the most commonly used categories.

Removed functions (security)

These functions are stripped from the template environment:

Function Why removed
env, expandenv, expand Prevents environment variable exfiltration
base64Encode, base64Decode Prevents cryptographic misuse
genPrivateKey, genCA, genSelfSignedCert Prevents key generation in templates

String functions

Function Signature Example Output
upper upper(string) {{ .State | upper }} SUCCESS
lower lower(string) {{ .State | lower }} success
title title(string) {{ .State | title }} Success
trim trim(string) {{ .Description | trim }} trimmed
trimAll trimAll(string) {{ " hello " | trimAll }} hello
trimPrefix trimPrefix(prefix, string) {{ "build-123" | trimPrefix "build-" }} 123
trimSuffix trimSuffix(suffix, string) {{ "123-test" | trimSuffix "-test" }} 123
replace replace(old, new, string) {{ "hello world" | replace "world" "relay" }} hello relay
trunc trunc(n, string) {{ .CommitSHA | trunc 8 }} first 8 characters
contains contains(substr, string) {{ contains "fail" .Description }} bool
hasPrefix hasPrefix(prefix, string) {{ hasPrefix "tekton-" .RunName }} bool
hasSuffix hasSuffix(suffix, string) {{ hasSuffix "-run" .RunName }} bool
repeat repeat(count, string) {{ repeat 3 "-" }} ---
quote quote(string) {{ .RunName | quote }} "my-run"
squote squote(string) {{ .RunName | squote }} 'my-run'
cat cat(args...) {{ cat "hello" "world" }} hello world
split split(sep, string) {{ index (split ":" "a:b:c") "_1" }} b
splitList splitList(sep, string) {{ splitList "/" "a/b/c" }} [a b c]
join join(sep, list) {{ join "," (list "a" "b") }} a,b
regexReplaceAll regexReplaceAll(pattern, string, repl) See below matched pattern replaced

Truncation in non-sprig notifiers: For Slack, Teams, Discord, and Email, use printf "%.200s" .Description instead of Truncate. The printf function is always available.

Math functions

Function Signature Example Output
add add(a, b) {{ add 1 2 }} 3
sub sub(a, b) {{ sub 10 3 }} 7
mul mul(a, b) {{ mul 3 4 }} 12
div div(a, b) {{ div 10 3 }} 3
mod mod(a, b) {{ mod 10 3 }} 1
max max(a, b) {{ max 5 3 }} 5
min min(a, b) {{ min 5 3 }} 3

Date/time functions

Function Signature Example Output
now now() {{ now }} current time
date date(fmt, time) {{ date "2006-01-02" .StartedAt }} 2024-01-15
dateModify dateModify(mod, time) {{ dateModify "-24h" now }} 24h ago
ago ago(time) {{ ago .StartedAt }} 5m30s
duration duration(seconds) {{ duration 90 }} 1h30m0s
unixEpoch unixEpoch(time) {{ unixEpoch .StartedAt }} unix timestamp

Duration calculation (common pattern):

{{- if and (not .StartedAt.IsZero) (not .FinishedAt.IsZero) -}}
Duration: {{ regexReplaceAll "[.][0-9]+s" (toString (.FinishedAt.Sub .StartedAt)) "s" }}
{{- end }}

Collection functions

Function Signature Example Output
list list(items...) {{ list "a" "b" }} [a b]
first first(n, list) {{ first 2 (list 1 2 3) }} [1 2]
last last(n, list) {{ last 2 (list 1 2 3) }} [2 3]
reverse reverse(list) {{ reverse (list 1 2 3) }} [3 2 1]
sortAlpha sortAlpha(list) {{ sortAlpha (list "c" "a" "b") }} [a b c]
uniq uniq(list) {{ uniq (list 1 1 2 3) }} [1 2 3]
has has(item, list) {{ has "a" (list "a" "b") }} true
append append(list, items...) {{ append (list 1 2) 3 }} [1 2 3]
concat concat(lists...) {{ concat (list 1) (list 2 3) }} [1 2 3]

Logic functions

Function Signature Example Output
ternary ternary(trueVal, falseVal, condition) {{ ternary "✅" "❌" (eq .State "success") }} or
default default(defaultVal, val) {{ .PipelineName | default .RunName }} falls back to RunName
empty empty(val) {{ if empty .Description }}no desc{{ end }} checks emptiness
coalesce coalesce(vals...) {{ coalesce .Description "N/A" }} first non-empty
toJson toJson(val) {{ . | toJson }} JSON string

Type conversion

Function Signature Example Output
toString toString(val) {{ toString 42 }} "42"
toInt toInt(val) {{ "42" | toInt }} 42
toBool toBool(val) {{ toBool "true" }} true

String building

Function Signature Example Output
printf printf(fmt, args...) {{ printf "%.8s" .CommitSHA }} first 8 chars
println println(args...) {{ println "hello" "world" }} hello world\n
indent indent(spaces, string) {{ indent 2 "line1\nline2" }} indented
nindent nindent(spaces, string) {{ nindent 2 "line1" }} newline + indented

Common patterns

Conditional content with default

{{ .PipelineName | default .RunName }}

State-based emoji (non-sprig notifiers)

{{- if eq .State "success" }}✅
{{- else if eq .State "failure" }}❌
{{- else if eq .State "error" }}⚠️
{{- else if eq .State "canceled" }}🚫
{{- else }}⏳
{{- end }}

Truncated description with fallback

{{ Truncate (.Description | default "No description available") 300 }}

Duration formatting

{{- if and (not .StartedAt.IsZero) (not .FinishedAt.IsZero) }}
Duration: {{ regexReplaceAll "[.][0-9]+s" (toString (.FinishedAt.Sub .StartedAt)) "s" }}
{{- end }}

Results table (sprig only)

{{- if .Results }}
<details><summary>Results ({{ len .Results }})</summary>

| Name | Value |
|---|---|
{{- range .Results }}
| {{ .Name }} | {{ Truncate .Value 120 }} |
{{- end }}

</details>
{{- end }}

Results list (non-sprig notifiers)

{{- if .Results }}
Results:
{{- range .Results }}
- {{ .Name }}: {{ printf "%.120s" .Value }}
{{- end }}
{{- end }}

Clone this wiki locally