-
Notifications
You must be signed in to change notification settings - Fork 0
Templates
Comment bodies, chat messages and check-run output are rendered with Go text/template, executed against the event. Label entries (labels.add/remove) use the same engine.
template: |
## Pipeline {{.State}}{{if eq .State "success"}} ✅{{else}} ❌{{end}}
**Pipeline:** {{.PipelineName}} · **Run:** {{.RunName}}
**Commit:** `{{ .CommitSHA | trunc 8 }}`
{{- if .TargetURL }}
[View logs]({{.TargetURL}})
{{- end }}The relay ships 15 pre-built templates in the tekton-events-relay-templates ConfigMap. Each is tuned for a specific surface (GitHub PR comments, Slack messages, email bodies, etc.) with the right Markdown dialect, emoji, and layout for that destination.
| Page | What you'll find |
|---|---|
| Template-Field-Reference | Every available field, its type, and when it's populated |
| Template-Function-Reference | Sprig functions plus the domain helpers (Truncate, PRRef, IssueRef, UserMention) |
| Template-Markdown-Capabilities | What Markdown features each surface supports (tables, <details>, emoji, etc.) |
| Template-Customization-Guide | Step-by-step guide to writing and shipping your own templates |
| Notifier-Format-Requirements | Per-notifier format rules (Slack mrkdwn, Teams Adaptive Cards, Discord embeds, etc.) |
The template context is the same event the CEL layer sees — identical names, accessed with a leading dot:
{{.State}}, {{.Resource}}, {{.Provider}}, {{.RunName}}, {{.RunID}}, {{.Namespace}}, {{.PipelineName}}, {{.TaskName}}, {{.PipelineTaskName}}, {{.PipelineDisplayName}}, {{.TaskDisplayName}}, {{.TriggerName}}, {{.EventListenerName}}, {{.TaskCount}}, {{.CommitSHA}}, {{.Context}}, {{.Description}}, {{.TargetURL}}, {{.APIBaseURL}}, {{.Repo.Owner}}, {{.Repo.Name}}, {{.Repo.ID}}, {{.Repo.Workspace}}, {{.Repo.Project}}, {{.Repo.Org}}, {{.IsFinallyTask}}, {{.SCMEventType}}, {{.StartedAt}}, {{.FinishedAt}}.
Pointer fields — guard before dereferencing:
{{ if .PRNumber }}PR #{{ .PRNumber }}{{ end }}
Tekton results (slice of {Name, Value}):
{{ range .Results }}{{ if eq .Name "IMAGE_DIGEST" }}Image: `{{ .Value }}`{{ end }}{{ end }}
The full Sprig function library is available in SCM comment, check-run, Grafana, email, Jira, and accumulator templates: upper, lower, title, trim, trunc, replace, default, now, date, add, printf, join, ternary, regexReplaceAll, …
{{ .CommitSHA | trunc 8 }}
{{ .Description | default "no description" }}
{{ ternary "✅" "❌" (eq .State "success") }}
{{ regexReplaceAll "[.][0-9]+s" (toString (.FinishedAt.Sub .StartedAt)) "s" }}
Slack, Teams, and Discord use plain Go
text/templateonly, no Sprig. Useprintffor truncation (printf "%.200s" .Description) instead oftrunc.
Provider-aware helpers that override any Sprig equivalent:
| Function | Example | Renders |
|---|---|---|
IssueRef provider n |
{{ IssueRef .Provider .IssueNumber }} |
#42 in the provider's linking syntax |
PRRef provider n |
{{ PRRef .Provider .PRNumber }} |
PR/MR reference (#42, !42 on GitLab) |
UserMention provider user |
{{ UserMention .Provider "alice" }} |
@alice in the provider's syntax |
Truncate s n |
{{ Truncate .Description 200 }} |
Rune-aware truncation with ellipsis |
The chart ships 15 templates in configmap-templates.yaml, mounted at /etc/templates. Each is tuned for its destination's Markdown dialect.
Full GFM with <details> for results. Designed for mode: upsert so a single comment is updated as the run progresses.
## ✅ Pipeline `build-and-test` — **success**
| | |
|---|---|
| **Run** | `build-and-test-abc123` |
| **Namespace** | `ci` |
| **Commit** | `a1b2c3d4` |
| **Context** | `tekton/build` |
| **Tasks** | 6 |
| **Duration** | 42s |
> Build passed all checks
<details><summary>📦 Results (3)</summary>
| Name | Value |
|---|---|
| `IMAGE_DIGEST` | `sha256:abc123...` |
| `COVERAGE` | `87.3%` |
| `ARTIFACT_URL` | `https://...` |
</details>
🔗 [View logs in Tekton Dashboard](https://tekton.example.com/#/namespaces/ci/pipelineruns/build-and-test-abc123)Shown in the Checks tab. Results stay expanded instead of collapsed.
## ✅ Build result: **success**
| | |
|---|---|
| **Run** | `build-and-test-abc123` |
| **Pipeline** | `build-and-test` |
| **Namespace** | `ci` |
| **Tasks executed** | 6 |
| **Duration** | 42s |
### Summary
Build passed all checks
### Results
| Name | Value |
|---|---|
| `IMAGE_DIGEST` | `sha256:abc123...` |
| `COVERAGE` | `87.3%` |
🔗 [View logs in Tekton Dashboard](https://tekton.example.com/#/namespaces/ci/pipelineruns/build-and-test-abc123)GitLab Flavored Markdown with tables and <details>.
## ✅ Pipeline `deploy-staging` — **success**
| | |
|---|---|
| **Run** | `deploy-staging-xyz789` |
| **Namespace** | `staging` |
| **Commit** | `f0e1d2c3` |
| **Context** | `tekton/build` |
| **Duration** | 1m23s |
<details><summary>📦 Results (2)</summary>
| Name | Value |
|---|---|
| `DEPLOY_URL` | `https://staging.example.com` |
| `IMAGE_TAG` | `v1.2.3-abc123` |
</details>
🔗 [View logs in Tekton Dashboard](https://tekton.example.com/#/namespaces/staging/pipelineruns/deploy-staging-xyz789)Slack mrkdwn syntax. No Sprig, uses printf for truncation.
:white_check_mark: *deploy-staging* — *success*
> *Run:* `deploy-staging-xyz789` *Namespace:* `staging`
> *Commit:* `f0e1d2c3`
> *Duration:* 83s
> Deployed to staging environment
<https://tekton.example.com/#/namespaces/staging/pipelineruns/deploy-staging-xyz789|:mag: View logs>
Rotating light for failures only. Designed for when: 'stateIn("failure", "error")'.
:rotating_light: *deploy-production* failed in *production*
> *Run:* `deploy-production-abc123` *Commit:* `a1b2c3d4`
> *Duration:* 45s
> Error: image pull backoff for gcr.io/my-project/app:v1.2.3
<https://tekton.example.com/#/namespaces/production/pipelineruns/deploy-production-abc123|:mag: View logs>
Discord Markdown with code block for structured data.
✅ **Pipeline success** in `ci`
Run: deploy-staging-xyz789 Pipeline: deploy-staging Commit: f0e1d2c3 Duration: 83s
> Deployed to staging environment
🔗 [View in Dashboard](https://tekton.example.com/#/namespaces/ci/pipelineruns/deploy-staging-xyz789)
Adaptive Card TextBlock subset: bold, italic, lists, links only. No tables, no code blocks.
✅ **deploy-staging** — **success**
- **Run:** deploy-staging-xyz789
- **Namespace:** staging
- **Commit:** f0e1d2c3
- **Duration:** 83s
Deployed to staging environment
[View logs](https://tekton.example.com/#/namespaces/ci/pipelineruns/deploy-staging-xyz789)
Plain text. Used for both subject and body.
Pipeline success: deploy-staging
Run: deploy-staging-xyz789
Namespace: staging
Commit: f0e1d2c3
Deployed to staging environment
View logs: https://tekton.example.com/#/namespaces/ci/pipelineruns/deploy-staging-xyz789
Short one-line annotation correlatable with dashboards.
deploy-staging success (deploy-staging-xyz789) — f0e1d2c3
Works across GitHub, GitLab, Gitea, Bitbucket, Azure DevOps. Designed for mode: upsert.
## ✅ Pipeline `deploy-staging` — **success**
| | |
|---|---|
| **Run** | `deploy-staging-xyz789` |
| **Commit** | `f0e1d2c3` |
| **Namespace** | `staging` |
| **Started** | 2026-06-19 14:30:00 UTC |
<details><summary>📦 Pipeline results</summary>
| Name | Value |
|---|---|
| `DEPLOY_URL` | `https://staging.example.com` |
</details>
🔗 [View logs in Tekton Dashboard](https://tekton.example.com/#/namespaces/staging/pipelineruns/deploy-staging-xyz789)GFM with tables. Used for issue-level notifications.
## ⚠️ Pipeline `deploy-staging` — **failure**
| | |
|---|---|
| **Run** | `deploy-staging-xyz789` |
| **Namespace** | `staging` |
| **Context** | `tekton/build` |
| **Duration** | 45s |
> Error: image pull backoff
🔗 [View logs in Tekton Dashboard](https://tekton.example.com/#/namespaces/staging/pipelineruns/deploy-staging-xyz789)Minimal plain text for Jira's wiki-markup renderer.
Pipeline success: deploy-staging
Run: deploy-staging-xyz789
Commit: f0e1d2c3
Logs: https://tekton.example.com/#/namespaces/staging/pipelineruns/deploy-staging-xyz789
Limited Markdown (no <details>, unreliable tables). Uses bold lists instead.
## ✅ Pipeline `deploy-staging` — **success**
- **Run:** `deploy-staging-xyz789`
- **Namespace:** `staging`
- **Commit:** `f0e1d2c3`
- **Duration:** 83s
> Deployed to staging environment
🔗 [View logs in Tekton Dashboard](https://tekton.example.com/#/namespaces/staging/pipelineruns/deploy-staging-xyz789)GFM tables, no <details>.
## ✅ Pipeline `deploy-staging` — **success**
| | |
|---|---|
| **Run** | `deploy-staging-xyz789` |
| **Namespace** | `staging` |
| **Commit** | `f0e1d2c3` |
| **Tasks** | 6 |
| **Duration** | 83s |
> Deployed to staging environment
**Results**
| Name | Value |
|---|---|
| `DEPLOY_URL` | `https://staging.example.com` |
🔗 [View logs in Tekton Dashboard](https://tekton.example.com/#/namespaces/staging/pipelineruns/deploy-staging-xyz789)Summary context with task-level breakdown. Sprig available.
✅ Pipeline success — deploy-staging
Run: deploy-staging-xyz789
Namespace: staging
Commit: f0e1d2c3
Tasks: 6
Duration: 42s
Results:
- IMAGE_DIGEST: sha256:abc123...
- COVERAGE: 87.3%
URL: https://tekton.example.com/#/namespaces/staging/pipelineruns/deploy-staging-xyz789
- GitHub / Gitea / GitLab comments — full Markdown (tables, details/summary, emoji).
-
Slack — Slack mrkdwn:
*bold*,<url|text>links,:emoji:. No Sprig; useprintffor truncation. - Teams — Adaptive Card TextBlock subset (bold, italic, lists, links). No tables, no code blocks.
-
Discord — Discord Markdown. No Sprig; use
printffor truncation. -
Email — plain text or HTML (set
html: true). - Grafana — short annotation text, one line.
- Jira — wiki-markup subset. Keep it minimal.
-
Webhook — no template; shape the JSON with the
transform(gojq) expression instead, see Notifiers. - Datadog / PagerDuty — events built natively by the notifier; no templates.
See Template-Markdown-Capabilities for a detailed comparison of what each surface supports.
The accumulator renders a different context, SummaryData:
{{.PipelineName}} {{.RunName}} {{.State}}
{{ range .Tasks }}{{ .Emoji }} {{ .Name }} — {{ .State }} ({{ .Duration }})
{{ end }}
Fields: .PipelineName, .RunName, .State, and .Tasks[] with .Name, .State, .Emoji, .Duration. Without a custom template you get the shipped accumulator-default.tmpl.
Every templatable field (template, and email's subject) accepts up to three forms in the Helm chart. There are no hardcoded template defaults in the application code. For the required-template notifiers (email, grafana, and the jira comment action), omitting the field makes the chart wire in a shipped default from its tekton-events-relay-templates ConfigMap (configmap-templates.yaml). For optional-template handlers (slack, teams, discord, webhook, and all SCM comment actions), omitting the field is valid and uses the handler's built-in fallback — no shipped default is wired. See the category breakdown below.
1. Inline — short templates, written directly in values.yaml:
template: |
Pipeline {{.State}}: {{.RunName}}
Commit: {{.CommitSHA}}2. ConfigMap reference — long templates, kept in a ConfigMap and mounted at /etc/templates:
template:
configmapRef:
name: my-custom-templates # optional; defaults to tekton-events-relay-templates
key: slack.tpl3. Omitted — leave the field out and the chart points at the shipped default:
| Notifier | Field | Default key |
|---|---|---|
subject |
email-subject.tmpl |
|
template |
email-default.tmpl |
|
| grafana | template |
deploy-marker.tmpl |
| jira (comment) | template |
jira-comment.tmpl |
| slack | template |
slack-default.tmpl |
| teams | template |
teams-default.tmpl |
| discord | template |
discord-default.tmpl |
| accumulator | template |
accumulator-default.tmpl |
| GitHub PR comment | template |
github-pr-comment.tmpl |
| GitHub check run | template |
github-checkrun.tmpl |
| GitHub issue comment | template |
github-issue-comment.tmpl |
| GitHub discussion comment | template |
github-discussion-comment.tmpl |
| GitLab MR/issue note | template |
gitlab-note.tmpl |
| Gitea PR comment | template |
gitea-pr-comment.tmpl |
| Gitea issue comment | template |
gitea-issue-comment.tmpl |
| Bitbucket PR comment | template |
bitbucket-comment.tmpl |
| Azure DevOps PR comment | template |
azuredevops-comment.tmpl |
For the rich PR summary that works across providers, use pr-summary-rich.tmpl with any SCM comment action.
Raw app config (non-Helm): if you run the binary with a hand-written config (see examples/config.yaml), a template field is either an inline string or an absolute file path beginning with
/(e.g./etc/templates/slack.tmpl). The chart'sconfigmapRefform is sugar that resolves to such a path. There are no in-code defaults, so the field is required — mount the templates ConfigMap and point at it.
To write your own templates, see Template-Customization-Guide for a step-by-step walkthrough. The Template-Function-Reference covers every available function, and Template-Field-Reference lists every field you can use.
Common patterns:
Conditional sections:
{{- if .CommitSHA }}
| **Commit** | `{{ .CommitSHA | trunc 8 }}` |
{{- end }}Duration calculation:
{{- if and (not .StartedAt.IsZero) (not .FinishedAt.IsZero) }}
| **Duration** | {{ regexReplaceAll "[.][0-9]+s" (toString (.FinishedAt.Sub .StartedAt)) "s" }} |
{{- end }}Collapsible results:
<details><summary>📦 Results ({{ len .Results }})</summary>
| Name | Value |
|---|---|
{{ range .Results }}
| `{{ .Name }}` | `{{ Truncate .Value 120 }}` |
{{ end }}
</details>State-dependent emoji:
{{- if eq .State "success" }}✅
{{- else if eq .State "failure" }}❌
{{- else if eq .State "error" }}⚠️
{{- else if eq .State "canceled" }}🚫
{{- else }}⏳
{{- end }}Getting started
Reference
SCM providers
Notifiers
Running in production
More