在 Git 中定义 PipelineRun
本指南适用于在其 Git 仓库中定义 PAC PipelineRun 清单的普通用户。
本指南说明 PAC 从哪里读取 pipeline 文件、如何构建 PipelineRun 清单,以及如何使用注解来匹配 Git 事件。
目录
Pipeline 文件位置默认位置多个 Pipeline 文件Pipeline 定义结构基本结构使用现有 Pipeline事件注解将 Pull Request 事件匹配到 PipelineRun将 Push 事件匹配到 PipelineRun分支指定分支和路径过滤分支过滤路径过滤排除路径变更组合路径变更和忽略高级事件匹配CEL 表达式格式可用的 CEL 字段和函数基本字段文件变更字段高级字段函数CEL 表达式示例匹配来自特定分支的 Pull Request使用.pathChanged() 进行基于路径的过滤匹配多个路径模式匹配事件标题排除分支复杂 CEL 表达式示例使用正则表达式按分支匹配 PipelineRun使用 Files 属性按文件变更匹配 PipelineRun过滤 PipelineRun 以排除非代码变更按事件标题匹配 PipelineRun基于 Body Payload 匹配 PipelineRun按请求头匹配 PipelineRun运行中取消配置取消示例用例对提交和 URL 参数化可用变量变量使用示例Git 仓库信息事件信息Pull Request 信息使用 Git Authentication SecretTask 解析使用 PAC 注解(推荐)远程 Task 注解使用 Resolver 语法本地 TaskTekton Hub Task远程 URL TaskPipeline 示例简单的构建 Pipeline面向 PR 的测试 Pipeline多阶段 Pipeline条件 Pipeline最佳实践1. 版本控制2. 组织方式3. 安全性4. 可复用性5. 测试故障排查Pipeline 未触发变量未解析找不到 Task后续步骤Pipeline 文件位置
PAC 会在仓库中的特定位置查找 pipeline 定义:
默认位置
默认位置是仓库根目录中的 .tekton/pipelinerun.yaml。
多个 Pipeline 文件
你可以将 pipeline 组织到多个文件中:
PAC 将处理 .tekton/ 目录中的所有 .yaml 和 .yml 文件。
当你在不同文件中有多个 PipelineRun 定义时:
- 每个 PipelineRun 都会独立评估
- 多个 PipelineRun 可以匹配同一个事件(它们将并行运行)
- 每个 PipelineRun 必须使用唯一的注解来控制其触发时机
- 使用具有描述性的文件名来组织不同类型的 pipeline(例如,
test-pipeline.yaml、deploy-pipeline.yaml)
示例:如果你同时有 test-pipeline.yaml 和 deploy-pipeline.yaml,并且它们都匹配对 main 分支的 push 事件,那么两个 pipeline 都会并行运行。
Pipeline 定义结构
PAC pipeline 是一个标准的 Tekton PipelineRun 资源,并带有 PAC 专用注解。
- PipelineRun:用于执行 pipeline 的 Tekton 资源。在 PAC 中,你可以在 Git 仓库中定义 PipelineRun 资源,PAC 会根据 Git 事件自动创建并管理它们。
- Pipeline:定义一组可复用 task 的 Tekton 资源。你可以在 PipelineRun 中使用
pipelineRef引用现有的 Pipeline 资源,或者使用pipelineSpec直接定义 task。
基本结构
使用现有 Pipeline
你可以引用已经在 Kubernetes 集群中定义好的现有 Pipeline 资源:
Pipeline 资源可以定义在以下位置:
- 与你的 Repository CR 相同的 namespace 中
- 作为集群范围资源(ClusterTasks)
- 在你的 Git 仓库中,并使用 resolver 语法引用(请参阅 Task 解析 部分)
事件注解
PAC 使用注解来决定何时触发 pipeline。这些注解会添加到 PipelineRun 的 metadata 中。你可以在 pipeline run 上使用特殊注解,将不同的 Git provider 事件与每个 pipeline 匹配。如果有多个 pipeline run 与某个事件匹配,Pipelines as Code 会并行运行它们,并在某个 pipeline run 完成后立即将结果发布到 Git provider。
将 Pull Request 事件匹配到 PipelineRun
你可以使用以下示例,将 pipeline 与一个目标为 main 分支的 pull_request 事件匹配:
将 Push 事件匹配到 PipelineRun
你可以使用以下示例,将 pipeline 与一个目标为 refs/heads/main 分支的 push 事件匹配:
分支指定
你可以通过添加以逗号分隔的条目来指定多个分支。例如,"[main, release-nightly]"。此外,你还可以指定以下内容:
- 分支的完整引用,例如
"refs/heads/main" - 使用模式匹配的 glob,例如
"refs/heads/*" - 标签,例如
"refs/tags/1.*"
示例:
多个分支:
使用 glob 匹配所有分支:
分支模式:
标签:
注意:on-target-branch 和 on-event 注解是官方文档中定义的标准格式。对于基于注释的触发器,请使用 pipelinesascode.tekton.dev/on-comment 注解。
分支和路径过滤
分支过滤
使用 on-target-branch 注解按目标分支进行过滤。你可以使用 glob 模式匹配多个分支:
过滤多个指定分支:
路径过滤
通过注解将 PipelineRun 匹配到特定路径变更,仅是一个技术预览功能。技术预览功能当前不受支持,可能也尚未完全具备功能。我们不建议在生产环境中使用它们。
要基于事件中的特定路径变更来触发 PipelineRun,请使用注解 pipelinesascode.tekton.dev/on-path-change。
可以指定多个路径,并用逗号分隔。PR 中变更文件的第一个匹配 glob 将触发 PipelineRun。如果你想匹配包含逗号的文件或路径,可以使用 , HTML 实体进行转义。
你仍然需要使用 on-target-branch 和 on-event 注解来指定事件类型和目标分支。
:::important 路径变更注解限制
如果你使用 CEL 表达式(on-cel-expression),on-path-change 和 on-path-change-ignore 注解将被忽略。在使用 CEL 时,请使用带有 files.* 属性或 .pathChanged() 函数的 CEL 表达式进行基于路径的过滤。
:::
示例:
当一个 pull_request 事件目标为 main 分支,并且包含对 docs 目录(及其子目录)中以 .md 为后缀的文件,或 manual 目录中以 .rst 为后缀的文件的变更时,此配置将匹配并触发 PipelineRun。
路径模式:
- 使用 glob 模式,而不是 regex
src/**- 匹配src目录及其子目录中的所有文件*.go- 匹配仓库根目录中的所有 Go 文件- 对于多个模式,使用以逗号分隔的值:
"[src/**,*.go,config/**]"
测试 glob 模式:
tkn pac CLI 提供了一个方便的 glob 命令,用于测试 glob 模式匹配:
排除路径变更
你可以使用反向注解 pipelinesascode.tekton.dev/on-path-change-ignore,在指定路径未发生变更时触发 PipelineRun。
你仍然需要指定事件类型和目标分支。如果你使用 CEL 表达式,on-path-change-ignore 注解将被忽略。
当 docs 文件夹之外有变更时,此 PipelineRun 将运行:
组合路径变更和忽略
你可以组合使用 on-path-change 和 on-path-change-ignore 注解:
当 docs 目录中有变更,但 docs/generated 目录中没有变更时,此配置会触发 PipelineRun。
重要:on-path-change-ignore 注解始终优先于 on-path-change 注解。如果某个文件同时匹配这两种模式,则不会触发 PipelineRun。
高级事件匹配
Pipelines as Code 支持使用 Common Expression Language (CEL) 基于过滤器进行高级事件匹配。
:::important CEL 与注解匹配
- 如果你使用
on-cel-expression:PAC 将使用 CEL 表达式,并忽略on-target-branch和on-event注解 - 如果你不使用
on-cel-expression:PAC 将使用on-target-branch和on-event注解进行匹配
你不能同时使用 CEL 表达式和简单注解。请根据需要选择一种方式:
- 对于基本匹配,使用简单注解(
on-target-branch、on-event) - 对于复杂过滤、取反和高级条件,使用 CEL 表达式
:::
与简单的 on-target-branch 注解匹配相比,CEL 表达式允许更复杂的过滤和取反。
CEL 表达式格式
使用 pipelinesascode.tekton.dev/on-cel-expression 注解并提供 CEL 表达式:
可用的 CEL 字段和函数
基本字段
event:一个 push 或pull_request事件target_branch:目标分支source_branch:pull_request事件的来源分支。对于 push 事件,它与target_branch相同event_title:匹配事件标题,例如 push 事件的 commit 标题,以及pull_request事件的 pull request 或 merge request 标题。本档仅涵盖 GitHub 和 GitLab。last_commit_title:事件中最后一个 commit 的标题(平台增强功能 - upstream Tekton 中不可用)
文件变更字段
这些字段允许你根据事件中的特定文件变更进行过滤:
files.all:所有变更的文件(新增、修改、删除、重命名)files.added:已新增的文件files.deleted:已删除的文件files.modified:已修改的文件files.renamed:已重命名的文件
注意:对于 pull request,属于该 pull request 的每个文件都会被列出。这些属性适用于 push 和 pull_request 事件。
高级字段
body:来自 Git provider 的完整 payload body(技术预览)headers:来自 Git provider 的 HTTP headers(以 map 形式提供,headers 始终为小写)
函数
.matches(pattern):使用正则表达式模式匹配字符串.pathChanged():字符串的后缀函数。该字符串可以是一个 glob 模式,用于检查路径是否发生变更。目前仅支持 GitHub 和 GitLab 作为 provider。注意:.pathChanged()支持 glob 模式,但不支持不同类型的变更(新增、修改、删除)。如需更精确的过滤,请使用files.*属性.startsWith(prefix):检查字符串是否以给定前缀开头.contains(substring):检查字符串是否包含给定子字符串.exists(iterator, condition):检查集合中的任意元素是否匹配条件(与files.*属性一起使用)
CEL 表达式示例
匹配来自特定分支的 Pull Request
要匹配一个目标为 main 分支且来源于 wip 分支的 pull_request 事件:
使用 .pathChanged() 进行基于路径的过滤
Pipelines-as-Code 支持两种方式来匹配某个特定事件中变更的文件:
.pathChanged()后缀函数(在 CEL 表达式中)- 支持 glob 模式,但不支持不同类型的“变更”(新增、修改、删除)files.*属性(在 CEL 表达式中)- 可以针对特定类型的变更文件,并支持使用 CEL 表达式on-path-change注解 - 更简单的基于注解的方法(技术预览)
如果只想在某个路径发生变更时运行 pipeline,可以使用带有 glob 模式的 .pathChanged() 后缀函数:
这将匹配 docs 目录中的每个 markdown 文件。
匹配多个路径模式
注意:.pathChanged() 支持 glob 模式,但不区分文件变更类型(新增、修改、删除、重命名)。如需更具体的过滤,请使用下文所述的 files.* 属性。
匹配事件标题
要匹配所有标题以 [DOWNSTREAM] 开头的 pull request:
排除分支
要在 pull_request 事件上运行 pipeline,但跳过 experimental 分支:
复杂 CEL 表达式示例
一个组合多个条件的完整示例:
此表达式:
- 匹配 push 或
pull_request事件 - 仅在 main、master 或 release-* 分支(或标签)上触发
- 排除标题中包含 "Auto-commit" 的 commit(受保护分支除外)
使用正则表达式按分支匹配 PipelineRun
使用正则表达式匹配分支名称。例如,针对来源分支名称包含子字符串 feat/ 的 pull_request 事件触发 PipelineRun:
使用 Files 属性按文件变更匹配 PipelineRun
你可以使用 files 属性匹配特定类型的文件变更。与 .pathChanged() 相比,这种方式更强大,因为它可以针对特定的变更类型(新增、修改、删除、重命名)。
匹配 tmp 目录中的任意变更文件:
匹配 src 或 pkg 目录中的任意新增文件:
匹配名称为 test.go 的修改文件:
可用的文件属性:
files.all:所有变更的文件(新增、修改、删除、重命名)files.added:已新增的文件files.deleted:已删除的文件files.modified:已修改的文件files.renamed:已重命名的文件
过滤 PipelineRun 以排除非代码变更
当仅变更文档或配置文件时,排除 PipelineRun。此示例会过滤 pull_request 事件,以排除仅影响文档、配置文件或其他非代码文件的变更:
此表达式将:
- 仅匹配目标为
main分支的pull_request事件 - 如果所有变更文件都匹配以下任一模式,则排除该 PipelineRun:
docs/目录中的文件(^docs/)- Markdown 文件(
\\.md$) - 常见的仓库元数据文件(
.gitignore、OWNERS、PROJECT、LICENSE)
注意:在 CEL 表达式中使用 regex 模式时,请记得正确转义特殊字符。反斜杠(\)需要写成双反斜杠(\\),才能在 CEL 字符串上下文中正确转义。
按事件标题匹配 PipelineRun
通过标题匹配 pull request 或 commit。对于 pull_request 事件,event_title 将是 pull request 标题;对于 push 事件,则是 commit 标题:
匹配标题中不包含 "Auto-commit" 的 commit:
基于 Body Payload 匹配 PipelineRun
基于 body payload 匹配 PipelineRun 仅是一个技术预览功能。技术预览功能当前不受支持,可能也尚未完全具备功能。我们不建议在生产环境中使用它们。
Git provider 传入的 payload body 在 CEL 变量中可作为 body 使用。你可以利用它根据 Git provider 发送的任何数据进行过滤。
例如,在 GitHub 上,仅当 pull request 目标为 main、作者为 superuser,且 action 为 synchronize(即 pull request 发生了更新)时才匹配:
重要说明:
- 当在 Pull Request 中匹配 body payload 时,诸如
/retest之类的 GitOps 注释将无法按预期工作,因为 payload body 会变成注释本身的内容,而不是原始 pull request payload - 如果在 body payload 上使用 CEL 想要重新测试 Pull Request,可以通过执行一次伪更新来强制推送:
git commit --amend --no-edit && git push --force-with-lease
按请求头匹配 PipelineRun
根据 Git provider 发送的 headers 进行过滤。headers 以列表形式提供,并且始终为小写。
通过检查 header,仅匹配 GitHub pull_request 事件:
仅匹配 GitLab merge request 事件:
运行中取消
pipelinesascode.tekton.dev/cancel-in-progress 注解允许你在触发同类型的新 pipeline 时自动取消正在运行的 pipeline。
配置取消
将注解设置为 "true" 以启用自动取消:
行为:
- 当触发新的 pipeline 时(例如,对同一分支的新 push),任何当前正在运行且带有相同注解的 pipeline 都会被自动取消
- 这对于防止同一分支上同时运行多个 pipeline 很有用
- 被取消的 pipeline 会在 Git provider 中显示为“Cancelled”状态
示例用例
防止 main 分支上的重复运行:
这可确保如果对 main 分支快速发生多次 push,只有最新的 pipeline 会运行,从而避免资源浪费。
与 Pull Request 配合使用:
当 PR 通过新 commit 更新时,任何正在运行且属于该 PR 的 pipeline 都会被取消,并启动一个新的 pipeline。
对提交和 URL 参数化
你可以使用 {{<var>}} 格式的动态可展开变量来指定提交和 URL 的参数。这些变量可用于:
PAC 支持两类变量:
- PAC 动态变量(
{{ variable_name }}):PAC 专用变量(例如{{ revision }}、{{ repo_url }}),在创建 PipelineRun 之前由 PAC 替换 - Tekton 参数(
$(params.param-name)):可在 Repository CR 的spec.params中定义的 Tekton Pipeline 参数(详情请参阅 高级 Repository 配置)
本节介绍 PAC 动态变量。关于 Repository CR 参数,请参阅 高级 Repository 配置。
- PipelineRun
params值 - Task 参数
- Step 脚本和命令
- pipeline 定义中的任何字符串值
可用变量
目前,你可以使用以下变量:
变量使用示例
Git 仓库信息
事件信息
Pull Request 信息
注意:{{ pull_request_number }} 变量仅适用于 pull_request 事件类型。对于 push 事件,此变量不会被填充。
使用 Git Authentication Secret
对于私有仓库,PAC 会自动生成一个用于 git 身份验证的 secret。你可以在 pipeline task 中引用此 secret:
注意:{{ git_auth_secret }} 变量仅适用于私有仓库。当 Repository 引用了 Git access token 时,PAC 会自动创建此 secret;请参阅 为 PAC 创建 Git Secret。secret 名称格式为 pac-gitauth-<repository-name>-<hash>。
Task 解析
PAC 可以自动从多个来源解析 task。你可以使用 PAC 注解(推荐)或 Tekton resolver 语法。
使用 PAC 注解(推荐)
PAC 提供了注解,用于自动从 Tekton Hub 获取并嵌入远程 task。这比使用 resolver 语法更简单。
远程 Task 注解
使用注解引用 Tekton Hub 中的 task:
工作原理:
- 注解
pipelinesascode.tekton.dev/task: "git-clone"会告诉 PAC 从 Tekton Hub 获取该 task - 使用带编号的注解(
task-1、task-2等)引用其他 task - PAC 会自动将所有引用的 task 定义嵌入到你的 PipelineRun 中
- 然后你可以使用
taskRef.name以及 Tekton Hub 中的 task 名称来引用它们
注解编号:
pipelinesascode.tekton.dev/task:第一个 task(等同于task-0)pipelinesascode.tekton.dev/task-1:第二个 taskpipelinesascode.tekton.dev/task-2:第三个 task- 依此类推...
更多详情请参阅 PAC Resolver。
使用 Resolver 语法
你也可以使用 Tekton 的 resolver 语法来引用 task。
本地 Task
引用在同一仓库中定义的 task:
Tekton Hub Task
引用 Tekton Hub 中的 task:
远程 URL Task
使用 PAC 注解引用远程 URL 中的 task(推荐):
Pipeline 示例
简单的构建 Pipeline
面向 PR 的测试 Pipeline
多阶段 Pipeline
此示例使用一个真实仓库演示了包含 clone、test 和 build 阶段的完整 CI pipeline:
条件 Pipeline
根据分支使用不同的 pipeline:
最佳实践
1. 版本控制
- 将所有 pipeline 定义保存在 Git 中
- 通过 Merge Request 审查 pipeline 变更
- 为 pipeline 版本打标签以提高可复现性
2. 组织方式
- 使用具有描述性的 pipeline 名称
- 将相关 task 分组放在一起
- 为不同类型的 pipeline 使用不同的文件
3. 安全性
- 不要在 pipeline 文件中硬编码 secret
- 对敏感数据使用 Kubernetes Secrets
- 使用 RBAC 限制 pipeline 权限
4. 可复用性
- 创建可复用的 task 定义
- 尽可能使用 Tekton Hub task
- 在多个仓库之间共享公共 task
5. 测试
- 在 feature 分支中测试 pipeline 变更
- 使用 Merge Request pipeline 验证变更
- 保持 pipeline 简单且易于维护
故障排查
Pipeline 未触发
-
检查注解是否正确:
-
验证分支名称是否匹配:
-
检查 PAC controller 日志:
变量未解析
- 验证变量语法:使用
{{ variable_name }}格式,例如{{ revision }}或{{ repo_url }} - 检查变量名拼写:确保变量名完全一致(例如,
{{ repo_owner }}、{{ source_branch }}) - 验证变量可用性:某些变量(如
{{ pull_request_number }})仅适用于pull_request事件 - 查看 PAC controller 日志中的变量解析错误
找不到 Task
- 验证 task 引用是否正确
- 检查仓库中是否存在 task 文件
- 验证 Tekton Hub task 名称
- 检查远程 task 的网络连通性
后续步骤
- PAC Resolver - 了解远程 task 和 pipeline 注解
- 触发 Pipeline - 了解不同的触发方式
- 指南 - 仓库设置操作指南
- 常见问题 - 故障排查指南