Configure Custom Mail Templates

Introduction

This guide explains how to add a new custom mail notification template for the Send Mail Task.

Scenarios

For most use cases, use built-in templates first:

  • Default Mail Template: outputs basic information of the current PipelineRun.
  • Custom Mail Template: supports custom email content through provided template options.

If built-in templates do not meet your requirements, follow this guide to create and configure a new template.

Prerequisites

  • Send Mail Task is available in your cluster.
  • You have permission to create ConfigMap in the target template namespace.

Template Support in Send Mail

The Send Mail Task supports template-based rendering for subject, body, and contentType. By referencing a shared template ConfigMap, teams can maintain mail content globally and reuse the same template across multiple pipelines.

For rendering workflow, built-in variables, and renderTemplateValues details, see Supported Template Parameters for Tasks.

Steps

1. Create a template ConfigMap

Create a ConfigMap and set parameters as follows:

Recommended namespace:

  • Place template ConfigMap in kube-public whenever possible. kube-public is a commonly used shared namespace, which makes it easier for TaskRun resources from different namespaces to reuse the same template.
  • If you store the template in another namespace, explicitly set renderTemplateNamespace to that namespace in your Task/Pipeline parameters. For details, see Supported Template Parameters for Tasks.

Required parameters:

  • Label tekton.alaudadevops.io/template-type: mail: marks this ConfigMap as a mail template so the webhook can identify it as a render source for Send Mail.
  • Data keys subject.tpl, body.tpl, contentType.tpl: rendered with Go template (gotemplate) syntax and mapped to subject, body, and contentType params. For gotemplate syntax, see Go text/template documentation. For available template variables, see Supported Template Parameters for Tasks.

Optional parameters:

  • Annotation tekton.alaudadevops.io/template-display-name: human-readable name shown in UI selectors and preview panels.
  • Annotation style.tekton.dev/descriptors: defines a nested form for renderTemplateValues in UI, so users can fill template variables with form controls instead of manually editing YAML. For descriptor syntax and patterns, see How to Configure Dynamic Forms.

Example:

apiVersion: v1
kind: ConfigMap
metadata:
  name: release-mail-template
  namespace: kube-public
  labels:
    tekton.alaudadevops.io/template-type: mail
  annotations:
    tekton.alaudadevops.io/template-display-name: "Release Mail Template"
    style.tekton.dev/descriptors: |
      - path: params.extraMessage
        x-descriptors:
          - urn:alm:descriptor:label:en:Extra Message
          - urn:alm:descriptor:description:en:Additional message shown in mail body.
          - urn:alm:descriptor:com.tectonic.ui:text
          - urn:alm:descriptor:placeholder:en:Input an extra message
data:
  subject.tpl: "PipelineRun {{ .context.pipelineRun.name }} - {{ .tasks.status }}"
  body.tpl: |
    PipelineRun: {{ .context.pipelineRun.name }}
    Status: {{ .tasks.status }}
    Message: {{ .values.extraMessage }}
  contentType.tpl: "text/plain; charset=UTF-8"

2. Configure pipeline to use your template

Set renderTemplateName and renderTemplateNamespace, then pass custom values through renderTemplateValues.

apiVersion: tekton.dev/v1
kind: Pipeline
metadata:
  name: demo-pipeline-with-mail-template
spec:
  workspaces:
    - name: smtp-credentials
  tasks:
    - name: build
      taskRef:
        name: build-task
  finally:
    - name: notify
      taskRef:
        name: send-mail
      params:
        - name: sendMailImage
          value: registry.alauda.cn:60070/devops/tektoncd/hub/msmtp:latest
        - name: renderTemplateName
          value: release-mail-template
        - name: renderTemplateNamespace
          value: kube-public
        - name: renderTemplateValues
          value: |
            extraMessage: "Project: {{ .project }}, Namespace: {{ .namespace }}"
        - name: from
          value: no-reply@example.com
        - name: to
          value:
            - team@example.com
      workspaces:
        - name: smtp-credentials
          workspace: smtp-credentials

3. Verify rendering results

Check a mutated TaskRun and confirm subject, body, and contentType have been appended to spec.params.

apiVersion: tekton.dev/v1
kind: TaskRun
metadata:
  name: demo-pipeline-with-mail-template-notify
  namespace: demo
spec:
  taskRef:
    name: send-mail
  params:
    - name: renderTemplateName
      value: release-mail-template
    - name: renderTemplateNamespace
      value: kube-public
    - name: renderTemplateValues
      value: |
        extraMessage: "Project: demo, Namespace: demo"
    - name: subject
      value: "PipelineRun demo-pipeline-run - Succeeded"
    - name: body
      value: |
        PipelineRun: demo-pipeline-run
        Status: Succeeded
        Message: Project: demo, Namespace: demo
    - name: contentType
      value: "text/plain; charset=UTF-8"

If rendering fails, check TaskRun annotation tekton.alaudadevops.io/template-render-error.

FAQ

Do I have to configure style.tekton.dev/descriptors?

No. It is optional. Configure it only when you want a structured UI form for renderTemplateValues.

Can I use both built-in variables and values.xxx in the same template?

Yes. You can combine built-in variables (for example, .context.pipelineRun.name, .tasks.status) with user values such as .values.extraMessage.

What happens if renderTemplateName is not set?

Template rendering is skipped. You need to provide subject and body params manually.

Which namespace should I use for template ConfigMap?

Use kube-public whenever possible. It is a common shared namespace, making it easier for TaskRun resources across different namespaces to reuse the same template.

If the template ConfigMap is stored in another namespace, set renderTemplateNamespace explicitly to that namespace. For parameter details, see Supported Template Parameters for Tasks.

What should I check first when rendering does not work?

  1. Confirm renderTemplateName and renderTemplateNamespace point to an existing template ConfigMap.
  2. Confirm the ConfigMap includes label tekton.alaudadevops.io/template-type: mail and required keys subject.tpl, body.tpl, and contentType.tpl.
  3. Check TaskRun annotation tekton.alaudadevops.io/template-render-error for the concrete error message.