如何配置动态表单
功能概述
动态表单配置功能允许你通过声明式方式,为 Pipeline 和 Task 等资源配置友好的交互体验。无需编写前端代码,只需在资源的 annotations 中添加 style.tekton.dev/descriptors 配置,即可实现:
- 动态表单生成:自动为资源参数生成交互式表单,在编排和执行 Pipelines 和 Tasks 时提供更好的体验。
- 丰富的组件支持:提供文本框、选择器、开关、YAML 编辑器等多种表单组件。
- 字段校验:内置校验规则,确保用户输入满足要求。
- 动态数据获取:支持通过 API 动态加载选项数据。
使用场景
- Pipeline 编排/运行时:在编排或触发
Pipeline 时,通过友好的表单让用户填写 namespace 和 secrets 等参数
- Task 复用:在
Task 或 Pipeline 模板层面,为常用参数提供默认值、下拉选项和校验
- 多环境选择:通过 API 动态查询可用环境或配置,并将其作为选择项
快速开始
基础配置结构
所有配置都通过 annotations 中的 style.tekton.dev/descriptors 字段定义:
metadata:
annotations:
style.tekton.dev/descriptors: |
- path: params.parameter-name
x-descriptors:
- configuration-item1
- configuration-item2
配置说明
path:指定参数路径,格式为 params.parameter-name
x-descriptors:配置项数组,每个配置项以 urn:alm:descriptor: 开头
简单示例
为某个 Task 参数配置一个必填文本输入框:
apiVersion: tekton.dev/v1
kind: Task
metadata:
name: simple-task
annotations:
style.tekton.dev/descriptors: |
- path: params.gitURL
x-descriptors:
- urn:alm:descriptor:label:zh:GitRepo
- urn:alm:descriptor:com.tectonic.ui:text
- urn:alm:descriptor:placeholder:zh:Git URL
- urn:alm:descriptor:com.tectonic.ui:validation:required
spec:
params:
- name: gitURL
type: string
steps:
- name: clone
image: alpine/git
script: |
git clone $(params.gitURL)
表单基础配置
表单标签
# Label for the form
- urn:alm:descriptor:label:en:English Name
- urn:alm:descriptor:label:zh:Chinese name
表单描述
# Description for the form
- urn:alm:descriptor:description:en:English Description
- urn:alm:descriptor:description:zh:Chinese Description
占位提示
# Placeholder for the form
- urn:alm:descriptor:placeholder:en:This is a Placeholder
- urn:alm:descriptor:placeholder:zh:This is a Placeholder
表单帮助提示
# Help tooltip for the form
- urn:alm:descriptor:tooltip:en:This is a Help Tip
- urn:alm:descriptor:tooltip:zh:This is a Help Tip
表单禁用状态
# Whether the form is disabled
- urn:alm:descriptor:com.tectonic.ui:disabled
支持的字段类型
文本输入
# value: string
- urn:alm:descriptor:com.tectonic.ui:text
多行文本输入
# value: string
- urn:alm:descriptor:com.tectonic.ui:textarea
标签输入
# value: array
- urn:alm:descriptor:com.tectonic.ui:tagsInput
单选
# Declare a radio option with value "option-a"
- urn:alm:descriptor:com.tectonic.ui:radio:option-a
# Set the English display label of option-a to "Option A"
- urn:alm:descriptor:com.tectonic.ui:radio:option-a:en:Option A
# Set the Chinese display label of option-a to "Option A(zh)"
- urn:alm:descriptor:com.tectonic.ui:radio:option-a:zh:Option A(zh)
# Declare a radio option with value "option-b"
- urn:alm:descriptor:com.tectonic.ui:radio:option-b
# Set the English display label of option-b to "Option B"
- urn:alm:descriptor:com.tectonic.ui:radio:option-b:en:Option B
# Set the Chinese display label of option-b to "Option B(zh)"
- urn:alm:descriptor:com.tectonic.ui:radio:option-b:zh:Option B(zh)
# Set the default selected option to "option-a"
- urn:alm:descriptor:com.tectonic.default:option-a
开关
# value: boolean
- urn:alm:descriptor:com.tectonic.ui:booleanSwitch
# Map value to specified string
# When switch is on, value is True
- urn:alm:descriptor:props:booleanSwitch:true:True
# When switch is off, value is False
- urn:alm:descriptor:props:booleanSwitch:false:False
YAML 编辑器
# value: string
- urn:alm:descriptor:com.tectonic.ui:yaml
下拉选择框
基础内容配置
# value: string
- urn:alm:descriptor:com.tectonic.ui:select
# Options
- urn:alm:descriptor:props:select:options:valueA
- urn:alm:descriptor:props:select:options:valueB
# Set the select box to multiple selection mode
# value: array
- urn:alm:descriptor:props:select:multiple
# Manually entered content can be used as selection items
- urn:alm:descriptor:props:select:allowCreate
# Content can be cleared
- urn:alm:descriptor:props:select:clearable
API 动态选项配置
当表单控件需要根据当前环境动态加载可用选项(例如可用 namespace、secrets 等)时,可以使用 API 动态配置,从后端接口实时获取下拉选项。
在这种模式下,API URL 通常会与 context variables 结合使用,根据用户当前的 cluster、namespace、project 或已填写参数动态构造请求路径。例如:
# Use ${context.cluster} variable in URL to dynamically retrieve namespace list for current cluster
- urn:alm:descriptor:expression:props.options:api:apiPath
- urn:alm:descriptor:expression:props.options:api:/kubernetes/${context.cluster}/api/v1/namespaces
可用的上下文变量
在动态 API 路径中,你可以使用 ${variable} 引用运行时上下文信息。
这些变量通常与 API URL 结合使用,以便在不同环境中动态构造请求地址,实现感知环境的选项加载逻辑。例如:
- urn:alm:descriptor:expression:props.options:api:apiPath
- urn:alm:descriptor:expression:props.options:api:/api/v1/${context.namespace}/deployments?repo=${context.params.repo}
配置返回数据的数据路径
- urn:alm:descriptor:expression:props.options:path:spec.items
当 API 返回复杂结构时,例如:
{
"spec": {
"items": [ ... ]
}
}
你可以使用 path 指定如何从结构中提取选项数组。
配置选项的标签和值映射字段
如果返回的数据对象较复杂,需要指定内部字段作为“显示名称”和“选项值”,可以使用:
- urn:alm:descriptor:expression:props.options:label:path:metadata.name
- urn:alm:descriptor:expression:props.options:value:path:metadata.name
当 API 返回的是简单的 string[] 数组时,不需要此配置。
配置 API 查询参数
如果需要向 API 请求传递查询参数(例如搜索关键字或过滤条件),可以使用:
# Add query parameter named "search" with user input as value
- urn:alm:descriptor:widgets:select
- urn:alm:descriptor:expression:props.options:api:/kubernetes/${context.cluster}/apis/tekton.dev/v1/namespaces/${context.namespace}/pipelineruns
- urn:alm:descriptor:expression:props.options:path:items
- urn:alm:descriptor:expression:props.options:label:path:metadata.name
- urn:alm:descriptor:expression:props.options:value:path:metadata.name
- urn:alm:descriptor:expression:props.options:api:params:search:${current.search}
当用户在下拉框中输入 "test" 时,实际请求将是:
/kubernetes/.../pipelineruns?search=test
高级用法:支持 JavaScript 表达式,例如:
${context.params.map(p => p.name).join(',')}
参数默认值
固定默认值
- urn:alm:descriptor:expression:props.default:default-value
基于表达式的动态默认值
可用变量:
-
option:选项原始数据
-
index:选项索引
-
length:选项总数
-
context:上下文参数
# Select options with specific labels
- urn:alm:descriptor:expression:props.default.exp:option.metadata.labels['default']==='true'
# Default to select the first item
- urn:alm:descriptor:expression:props.default.exp:index === 0
# Default to select the last item
- urn:alm:descriptor:expression:props.default.exp:index === length - 1
# Default to select when there is only one option
- urn:alm:descriptor:expression:props.default.exp:length === 1
# Default to select the current namespace
- urn:alm:descriptor:expression:props.default:${context.namespace}
# Complex conditions
- urn:alm:descriptor:expression:props.default.exp:option.metadata.name.includes('test') && option.status.conditions.some(c => c.status==='True')
表单校验
支持配置多种校验规则,多个规则可以同时生效。
必填校验
- urn:alm:descriptor:com.tectonic.ui:validation:required
长度校验
# Minimum length
- urn:alm:descriptor:com.tectonic.ui:validation:minLength:6
# Maximum length
- urn:alm:descriptor:com.tectonic.ui:validation:maxLength:64
数值范围校验
# Minimum value (applicable to numeric types)
- urn:alm:descriptor:com.tectonic.ui:validation:minimum:1
# Maximum value
- urn:alm:descriptor:com.tectonic.ui:validation:maximum:100
正则表达式校验
# Positive integer
- urn:alm:descriptor:com.tectonic.ui:validation:pattern:[1-9]\d*
# Kubernetes resource name (lowercase letters, numbers, hyphens)
- urn:alm:descriptor:com.tectonic.ui:validation:pattern:[a-z0-9]([-a-z0-9]*[a-z0-9])?
组合示例:配置一个带完整校验的密码字段
- path: params.password
x-descriptors:
- urn:alm:descriptor:label:zh:password
- urn:alm:descriptor:com.tectonic.ui:text
- urn:alm:descriptor:description:zh:At least 8 characters, including letters and numbers.
- urn:alm:descriptor:com.tectonic.ui:validation:required
- urn:alm:descriptor:com.tectonic.ui:validation:minLength:8
- urn:alm:descriptor:com.tectonic.ui:validation:maxLength:32
高级功能
在复杂的 CI/CD 场景中,以下高级表单组件可以帮助你处理更复杂的配置需求。
组合组件
在复杂的 CI/CD 场景中,你可能会遇到某个数组参数需要从多个不同来源(不同 API)收集数据的情况。例如,workloads 参数可能需要同时包含 "Deployments" 和 "StatefulSets",而这两者需要从完全不同的 Kubernetes API 中获取数据。
为此,你可以使用 Combine Component (widgets:combine)。它允许你在 UI 上将一个参数拆分为多个独立的子表单控件(例如,用单选按钮选择资源类型,再用下拉框选择具体资源),然后在提交到 Pipeline 之前,通过 JavaScript 表达式将它们的值合并为最终的数组或 JSON 对象。
配置
# Declare the use of the combine widget
- urn:alm:descriptor:widgets:combine
# Parent combine logic: defines how to merge all sub-component values into the final parameter
# Available variable: items (contains all sub-component values)
# Example: (items.deployments || []).concat(items.statefulsets || []) - merge multiple arrays into one
- urn:alm:descriptor:combine:value.exp:<js-expression>
# Parent: define sub-components
- urn:alm:descriptor:combine:items:
- path: <sub-component-name-1>
x-descriptors:
# Child split logic: defines how to extract this sub-component's value from the parent for echo display
# Available variable: parent (the current parameter value)
# Example: (parent || []).filter(p => p.startsWith('deploy:')) - extract items with 'deploy:' prefix
- urn:alm:descriptor:combine:value.exp:<js-expression>
# ... other descriptors for this sub-component
- path: <sub-component-name-2>
x-descriptors:
# Child split logic: defines how to extract this sub-component's value from the parent for echo display
- urn:alm:descriptor:combine:value.exp:<js-expression>
# ... other descriptors for this sub-component
更多 js-expression 语法请参考 JavaScript syntax。
示例:配置一个多选参数 target_resources,允许用户从 Deployments 和 StatefulSets 中选择资源。最终参数值将是一个数组,合并来自两个 API 的选择项,并添加特定前缀以区分类型(例如,["deploy:app-v1", "sts:db-v1"])。
- path: params.target_resources
x-descriptors:
# Declare the use of the combine widget
- urn:alm:descriptor:widgets:combine
# [Parent] Combine logic: concat the arrays from both 'deployments' and 'statefulsets' sub-components
- urn:alm:descriptor:combine:value.exp:(items.deployments || []).concat(items.statefulsets || [])
# Define sub-components
- urn:alm:descriptor:combine:items:
# Sub-component 1: Select Deployments
- path: deployments
x-descriptors:
# [Child 1] Split logic: extract items starting with 'deploy:' from the parent array
- urn:alm:descriptor:combine:value.exp:(parent || []).filter(p => p.startsWith('deploy:'))
- urn:alm:descriptor:label:en:Deployments
- urn:alm:descriptor:label:zh:Deployments
- urn:alm:descriptor:widgets:select
- urn:alm:descriptor:props:select:multiple
- urn:alm:descriptor:expression:props.options:api:/kubernetes/${context.cluster}/apis/apps/v1/namespaces/${context.namespace}/deployments
- urn:alm:descriptor:expression:props.options:path:items
- urn:alm:descriptor:expression:props.options:label:path:metadata.name
# Prepend 'deploy:' prefix
- urn:alm:descriptor:expression:props.options:value:path.exp:'deploy:'+$.metadata.name
# Sub-component 2: Select StatefulSets
- path: statefulsets
x-descriptors:
# [Child 2] Split logic: extract items starting with 'sts:' from the parent array
- urn:alm:descriptor:combine:value.exp:(parent || []).filter(p => p.startsWith('sts:'))
- urn:alm:descriptor:label:en:StatefulSets
- urn:alm:descriptor:label:zh:StatefulSets
- urn:alm:descriptor:widgets:select
- urn:alm:descriptor:props:select:multiple
- urn:alm:descriptor:expression:props.options:api:/kubernetes/${context.cluster}/apis/apps/v1/namespaces/${context.namespace}/statefulsets
- urn:alm:descriptor:expression:props.options:path:items
- urn:alm:descriptor:expression:props.options:label:path:metadata.name
# Prepend 'sts:' prefix
- urn:alm:descriptor:expression:props.options:value:path.exp:'sts:'+$.metadata.name
其在 UI 中的工作方式:
-
用户会同时看到两个独立的多选框:Deployments 和 StatefulSets。
-
Deployments 选择框从 Deployment API 获取数据,StatefulSets 选择框从 StatefulSet API 获取数据。
-
当用户在 Deployments 中选择 dummy 和 alm,在 StatefulSets 中选择 db-1 时,提交到 Task 的最终 target_resources 数组会自然合并为:
- name: target_resources
value:
- deploy:dummy
- deploy:alm
- sts:db-1
预览组件
Preview Component 允许用户直接在表单中预览所选资源的 YAML 内容。这在用户需要在将资源用于 Pipelines 之前验证其配置的场景中特别有用,例如检查 ConfigMap 内容、验证 Secret 数据,或查看 Task/Pipeline YAML 定义。
例如,当用户从下拉框中选择一个 ConfigMap 作为 Task 中的卷挂载或环境变量来源时,可以直接在表单中预览该 ConfigMap 的数据,以确保选择的是正确资源。
配置
# Enable preview - show button when parameter has value
- urn:alm:descriptor:enhance:preview:context.params.<param-name>
# API endpoint to fetch resource content
- urn:alm:descriptor:preview:resource:api:<api-url>
# JSONPath or JS expression to extract content from response
- urn:alm:descriptor:preview:resource:path:<jsonpath>
- urn:alm:descriptor:preview:resource:path.exp:<js-expression>
示例:配置一个用于选择 ConfigMap 的下拉框,并提供一个预览按钮查看其 YAML 内容。
- path: params.configmap
x-descriptors:
# Form label
- urn:alm:descriptor:label:en:ConfigMap
- urn:alm:descriptor:label:zh:ConfigMap
# Dropdown to select ConfigMap from current namespace
- urn:alm:descriptor:com.tectonic.ui:select
- urn:alm:descriptor:expression:props.options:api:/kubernetes/${context.cluster}/api/v1/namespaces/${context.namespace}/configmaps
- urn:alm:descriptor:expression:props.options:path:items
- urn:alm:descriptor:expression:props.options:label:path:metadata.name
- urn:alm:descriptor:expression:props.options:value:path:metadata.name
- urn:alm:descriptor:com.tectonic.ui:validation:required
# Preview feature
- urn:alm:descriptor:enhance:preview:context.params.configmap
- urn:alm:descriptor:preview:resource:api:/kubernetes/${context.cluster}/api/v1/namespaces/${context.namespace}/configmaps?fieldSelector=metadata.name%3D${context.params.configmap}
- urn:alm:descriptor:preview:resource:path:items[0]
其在 UI 中的工作方式:
- 用户从下拉框中选择一个 ConfigMap(例如
my-config)。
- 下拉框旁会显示一个预览按钮。
- 点击预览按钮后,会从 Kubernetes API 获取所选 ConfigMap。
- 原始 YAML 内容会以语法高亮的形式显示在预览面板中。
使用示例
在 Task 中配置动态表单
示例:为 Task 的 image 参数提供一个用于选择 namespace 的下拉框。
效果:当用户基于 UI 编排 Pipeline 或 TaskRun 时,该 Task 的 namespace 参数支持通过下拉框选择 namespace。
apiVersion: tekton.dev/v1
kind: Task
metadata:
name: demo-task
namespace: <your namespace>
annotations:
style.tekton.dev/descriptors: |
- path: params.namespace
x-descriptors:
- urn:alm:descriptor:label:en:namespace
- urn:alm:descriptor:label:zh:namespace(zh)
- urn:alm:descriptor:com.tectonic.ui:select
- urn:alm:descriptor:expression:props.options:api:/kubernetes/${context.cluster}/api/v1/namespaces
- urn:alm:descriptor:expression:props.options:path:items
- urn:alm:descriptor:expression:props.options:label:path:metadata.name
- urn:alm:descriptor:expression:props.options:value:path:metadata.name
- urn:alm:descriptor:com.tectonic.ui:validation:required
spec:
params:
- name: namespace
type: string
steps:
- name: demo
image: ubuntu
script: |
#!/bin/sh
pwd
在 Pipeline 中配置动态表单
示例:为 Pipeline 的 target-namespace 参数提供一个用于选择 namespace 的下拉框。
效果:当用户基于 UI 触发 Pipeline,或需要在其他资源(Trigger、TriggerTemplate)中关联该 pipeline 并配置运行时参数时,target-namespace 参数支持通过下拉框选择 namespace。
apiVersion: tekton.dev/v1
kind: Pipeline
metadata:
annotations:
style.tekton.dev/descriptors: |
- path: params.target-namespace
x-descriptors:
- urn:alm:descriptor:label:en:target-namespace
- urn:alm:descriptor:label:zh:target-namespace(zh)
- urn:alm:descriptor:com.tectonic.ui:select
- urn:alm:descriptor:expression:props.options:api:/kubernetes/${context.cluster}/api/v1/namespaces
- urn:alm:descriptor:expression:props.options:label:path:metadata.name
- urn:alm:descriptor:expression:props.options:value:path:metadata.name
- urn:alm:descriptor:expression:props.options:path:items
- urn:alm:descriptor:com.tectonic.ui:validation:required
name: demo-pipelines
namespace: <your namespace>
spec:
params:
- name: target-namespace
type: string
tasks:
- name: kubectl
taskRef:
resolver: hub
params:
- name: kind
value: task
- name: catalog
value: catalog
- name: name
value: kubectl
- name: version
value: "0.1"
故障排查
- 表单未显示或配置未生效:检查
style.tekton.dev/descriptors 的 YAML 格式是否正确,确认 path 是否配置为 params.parameter-name,验证每个 descriptor 是否以 - urn:alm:descriptor: 开头
- 动态选项未加载:确认 API 路径是否正确,检查当前用户是否有权限访问指定的 API 资源,验证
path、label 和 value 配置是否指向返回数据中实际存在的字段
- 默认值未生效:确认固定默认值使用的是
expression:props.default:value 格式,表达式默认值使用的是 === 而不是 =,检查表达式中的变量(option、index、length、context)拼写是否正确
- 上下文变量未解析:检查变量名是否正确(例如
context.namespace 而不是 context.namespaces),确认这些变量是否用于支持表达式的 descriptor 中,检查 JavaScript 表达式语法是否有错误