维护 Pipeline 代码
本指南面向普通用户,用于在 Git 仓库中创建和维护 pipeline 定义。
本指南说明如何使用 PAC 在源代码仓库中维护 pipeline 定义。
目录
Pipeline 文件位置默认位置多个 Pipeline 文件Pipeline 定义结构基本结构使用现有 Pipeline事件注解将 Pull Request 事件匹配到 Pipeline Run将 Push 事件匹配到 Pipeline Run分支规范分支与路径过滤分支过滤路径过滤排除路径变更组合路径变更与忽略高级事件匹配CEL 表达式格式可用的 CEL 字段和函数基本字段文件变更字段高级字段函数CEL 表达式示例匹配来自特定分支的 Pull Request使用.pathChanged() 进行基于路径的过滤匹配多个路径模式事件标题匹配排除分支复杂 CEL 表达式示例通过正则表达式按分支匹配 PipelineRun使用 Files 属性按文件变更匹配 PipelineRun过滤 PipelineRun 以排除非代码变更按事件标题匹配 PipelineRun基于 Body Payload 匹配 PipelineRun按请求头匹配 PipelineRun运行中取消配置取消使用场景示例为提交和 URL 参数化可用变量变量使用示例Git 仓库信息事件信息Pull Request 信息使用 Git 认证 secretTask Resolution使用 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:定义可复用任务集的 Tekton 资源。你可以在 PipelineRun 中使用
pipelineRef引用现有的 Pipeline 资源,或者使用pipelineSpec直接定义任务。
基本结构
使用现有 Pipeline
你可以引用 Kubernetes 集群中已经定义的现有 Pipeline 资源:
Pipeline 资源可以定义在以下位置:
- 与你的 Repository CR 相同的 namespace 中
- 作为集群范围资源(ClusterTasks)
- 定义在你的 Git 仓库中,并使用 resolver 语法引用(请参见 Task Resolution 部分)
事件注解
PAC 使用注解来确定何时触发 pipeline。这些注解会添加到 PipelineRun 的 metadata 中。你可以通过在 pipeline run 上使用特定注解,将不同的 Git provider 事件与各个 pipeline 匹配起来。如果有多个 pipeline run 匹配同一个事件,Pipelines as Code 会并行运行它们,并在某个 pipeline run 完成后立即将结果发布回 Git provider。
将 Pull Request 事件匹配到 Pipeline Run
你可以使用下面的示例,将一个 pipeline 与目标分支为 main 的 pull_request 事件匹配:
将 Push 事件匹配到 Pipeline Run
你可以使用下面的示例,将一个 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 实体进行 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 提供了一个便捷的 globbing 命令,用于测试 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 事件的提交标题,以及pull_request事件的 pull request 或 merge request 标题。目前仅支持 GitHub、GitLab 和 Bitbucket Cloudlast_commit_title:事件中最后一次提交的标题(平台增强功能 - 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):将字符串与 regex 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" 的提交(除非位于受保护分支上)
通过正则表达式按分支匹配 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 或提交。event_title 在 pull_request 事件中表示 pull request 标题,在 push 事件中表示提交标题:
匹配标题中不包含 "Auto-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 变成了评论的 body,而不是原始的 pull request payload - 如果使用基于 body payload 的 CEL 来重新测试 Pull Request,请通过 amend 并强制推送来制造一次虚拟更新:
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 分支上的重复运行:
这可确保如果短时间内有多个 push 发生到 main 分支,只有最新的 pipeline 会运行,从而避免资源浪费。
与 Pull Request 一起使用:
当 PR 使用新提交更新时,该 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 参数(详情请参见 Advanced Repository Configuration)
本节介绍 PAC 动态变量。关于 Repository CR 参数,请参见 Advanced Repository Configuration。
- PipelineRun
params值 - Task 参数
- Step 脚本和命令
- pipeline 定义中的任何字符串值
可用变量
目前,你可以使用以下变量:
变量使用示例
Git 仓库信息
事件信息
Pull Request 信息
注意:{{ pull_request_number }} 变量仅适用于 pull_request 事件类型。对于 push 事件,此变量不会被填充。
使用 Git 认证 secret
对于私有仓库,PAC 会自动生成用于 git 认证的 secret。你可以在 pipeline 任务中引用该 secret:
注意:{{ git_auth_secret }} 变量仅适用于私有仓库。当你为私有仓库配置认证时,PAC 会自动创建该 secret(请参见 Configure Authentication for Private Repositories)。secret 名称格式为 pac-gitauth-<repository-name>-<hash>。
Task Resolution
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 中
- 然后你可以使用 Tekton Hub 中的 task 名称,通过
taskRef.name引用它们
注解编号:
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
此示例演示了一个完整的 CI pipeline,使用真实仓库完成 clone、test 和 build 阶段:
条件 Pipeline
根据分支使用不同的 pipeline:
最佳实践
1. 版本控制
- 将所有 pipeline 定义保存在 Git 中
- 通过 Merge Requests 审查 pipeline 变更
- 为 pipeline 版本打标签,以便实现可复现性
2. 组织方式
- 使用具有描述性的 pipeline 名称
- 将相关任务分组放在一起
- 针对不同类型的 pipeline 使用独立文件
3. 安全性
- 不要在 pipeline 文件中硬编码 secrets
- 对敏感数据使用 Kubernetes Secrets
- 使用 RBAC 限制 pipeline 权限
4. 可复用性
- 创建可复用的 task 定义
- 尽可能使用 Tekton Hub task
- 在多个仓库之间共享通用 task
5. 测试
- 在 feature 分支中测试 pipeline 变更
- 使用 Merge Request pipeline 验证变更
- 保持 pipeline 简洁且易于维护
故障排查
Pipeline 未触发
-
检查注解是否正确:
-
验证分支名称是否匹配:
-
检查 PAC 控制器日志:
变量未解析
- 验证变量语法:使用
{{ variable_name }}格式,例如{{ revision }}或{{ repo_url }} - 检查变量名拼写:确保变量名完全一致(例如
{{ repo_owner }}、{{ source_branch }}) - 验证变量可用性:某些变量(如
{{ pull_request_number }})仅适用于pull_request事件 - 查看 PAC 控制器日志中的变量解析错误
找不到 Task
- 验证 task 引用是否正确
- 检查仓库中是否存在 task 文件
- 验证 Tekton Hub task 名称
- 检查远程 task 的网络连通性
下一步
- PAC Resolver - 了解远程 task 和 pipeline 注解
- Trigger Pipelines - 了解不同的触发方式
- Configure Repository - 仓库设置指南
- Common Issues - 故障排查指南