维护 Pipeline 代码
面向普通用户
本指南适用于在 Git 仓库中创建和维护 pipeline 定义的普通用户。
本指南介绍如何使用 PAC 在源代码仓库中维护 pipeline 定义。
Pipeline 文件位置
PAC 会在仓库中的特定位置查找 pipeline 定义:
默认位置
默认位置是仓库根目录下的 .tekton/pipelinerun.yaml。
your-repo/
├── .tekton/
│ └── pipelinerun.yaml
├── src/
└── README.md
多个 Pipeline 文件
你可以将 pipeline 组织到多个文件中:
.tekton/
├── pipelinerun.yaml # 主 pipeline
├── test-pipeline.yaml # 测试 pipeline
└── deploy-pipeline.yaml # 部署 pipeline
PAC 会处理 .tekton/ 目录下所有 .yaml 和 .yml 文件。
多个文件中的多个 PipelineRun
当你在不同文件中有多个 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 特定注解。
了解 Tekton 资源
- PipelineRun:一个执行 pipeline 的 Tekton 资源。在 PAC 中,你在 Git 仓库里定义 PipelineRun 资源,PAC 会根据 Git 事件自动创建并管理它们。
- Pipeline:一个定义可复用任务集的 Tekton 资源。你可以在 PipelineRun 中使用
pipelineRef 引用一个已存在的 Pipeline 资源,或者使用 pipelineSpec 内联定义任务。
基本结构
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
name: my-pipeline
annotations:
pipelinesascode.tekton.dev/on-target-branch: "[refs/heads/main]"
pipelinesascode.tekton.dev/on-event: "[push]"
spec:
pipelineSpec:
tasks:
- name: hello
taskSpec:
steps:
- name: echo
image: alpine:latest
script: |
echo "Hello from PAC!"
使用现有 Pipeline
你可以引用 Kubernetes 集群中已定义的现有 Pipeline 资源:
在哪里定义 Pipeline 资源
Pipeline 资源可以定义在以下位置:
- 与你的 Repository CR 相同的 namespace 中
- 作为 Cluster 范围资源(ClusterTasks)
- 在你的 Git 仓库中,并使用 resolver 语法引用(参见 任务解析 部分)
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
name: my-pipeline
annotations:
pipelinesascode.tekton.dev/on-target-branch: "[refs/heads/main]"
pipelinesascode.tekton.dev/on-event: "[push]"
spec:
pipelineRef:
name: my-pipeline-resource
事件注解
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 事件匹配:
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
name: pipeline-pr-main
annotations:
pipelinesascode.tekton.dev/on-target-branch: "[main]"
pipelinesascode.tekton.dev/on-event: "[pull_request]"
spec:
pipelineSpec:
tasks:
- name: test
taskSpec:
steps:
- name: test
image: alpine:latest
script: |
echo "Running tests for PR to main"
将 Push 事件匹配到 Pipeline Run
你可以使用以下示例,将一个 pipeline 与目标为 refs/heads/main 分支的 push 事件匹配:
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
name: pipeline-push-on-main
annotations:
pipelinesascode.tekton.dev/on-target-branch: "[refs/heads/main]"
pipelinesascode.tekton.dev/on-event: "[push]"
spec:
pipelineSpec:
tasks:
- name: build
taskSpec:
steps:
- name: build
image: alpine:latest
script: |
echo "Building on push to main"
分支指定
你可以通过添加逗号分隔的条目来指定多个分支。例如,"[main, release-nightly]"。此外,你还可以指定以下内容:
- 分支的完整引用,例如
"refs/heads/main"
- 使用模式匹配的 glob,例如
"refs/heads/*"
- 标签,例如
"refs/tags/1.*"
示例:
多个分支:
metadata:
annotations:
pipelinesascode.tekton.dev/on-target-branch: "[main, release-nightly]"
pipelinesascode.tekton.dev/on-event: "[push]"
使用 glob 匹配所有分支:
metadata:
annotations:
pipelinesascode.tekton.dev/on-target-branch: "[refs/heads/*]"
pipelinesascode.tekton.dev/on-event: "[push]"
分支模式:
metadata:
annotations:
pipelinesascode.tekton.dev/on-target-branch: "[refs/heads/feature/*]"
pipelinesascode.tekton.dev/on-event: "[push]"
标签:
metadata:
annotations:
pipelinesascode.tekton.dev/on-target-branch: "[refs/tags/1.*]"
pipelinesascode.tekton.dev/on-event: "[push]"
注意:on-target-branch 和 on-event 注解是官方文档中指定的标准格式。对于基于注释的触发,请使用 pipelinesascode.tekton.dev/on-comment 注解。
分支和路径过滤
分支过滤
使用 on-target-branch 注解按目标分支进行过滤。你可以使用 glob 模式匹配多个分支:
metadata:
annotations:
pipelinesascode.tekton.dev/on-target-branch: "[refs/heads/feature/*]"
pipelinesascode.tekton.dev/on-event: "[push]"
过滤多个指定分支:
metadata:
annotations:
pipelinesascode.tekton.dev/on-target-branch: "[main, develop]"
pipelinesascode.tekton.dev/on-event: "[push, pull_request]"
路径过滤
技术预览
通过注解将 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 表达式进行基于路径的过滤。
:::
示例:
metadata:
name: pipeline-docs-and-manual
annotations:
pipelinesascode.tekton.dev/on-target-branch: "[main]"
pipelinesascode.tekton.dev/on-event: "[pull_request]"
pipelinesascode.tekton.dev/on-path-change: "[docs/**.md, manual/**.rst]"
此配置会在 pull_request 事件目标为 main 分支,并且包含以下变更时匹配并触发 PipelineRun:docs 目录(及其子目录)下以 .md 结尾的文件,或 manual 目录下以 .rst 结尾的文件。
路径模式:
- 使用 glob 模式,而不是 regex
src/** - 匹配 src 目录及其子目录中的所有文件
*.go - 匹配仓库根目录中的所有 Go 文件
- 对于多个模式,使用逗号分隔的值:
"[src/**,*.go,config/**]"
测试 glob 模式:
tkn pac CLI 提供了一个很方便的 glob 测试命令,用于测试 glob 模式匹配:
tkn pac info globbing "[PATTERN]"
排除路径变更
你可以使用反向注解 pipelinesascode.tekton.dev/on-path-change-ignore,在指定路径未发生变更时触发 PipelineRun。
你仍然需要指定事件类型和目标分支。如果你使用了 CEL 表达式,on-path-change-ignore 注解将被忽略。
当 docs 文件夹之外有变更时,此 PipelineRun 将运行:
metadata:
name: pipeline-not-on-docs-change
annotations:
pipelinesascode.tekton.dev/on-target-branch: "[main]"
pipelinesascode.tekton.dev/on-event: "[pull_request]"
pipelinesascode.tekton.dev/on-path-change-ignore: "[docs/***]"
组合路径变更与忽略
你可以将 on-path-change 和 on-path-change-ignore 注解组合使用:
metadata:
name: pipeline-docs-not-generated
annotations:
pipelinesascode.tekton.dev/on-target-branch: "[main]"
pipelinesascode.tekton.dev/on-event: "[pull_request]"
pipelinesascode.tekton.dev/on-path-change: "[docs/***]"
pipelinesascode.tekton.dev/on-path-change-ignore: "[docs/generated/***]"
此配置会在 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 表达式:
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
name: cel-pipeline
annotations:
pipelinesascode.tekton.dev/on-cel-expression: |
event == "pull_request" && target_branch == "main"
spec:
pipelineSpec:
tasks:
- name: test
taskSpec:
steps:
- name: test
image: alpine:latest
script: |
echo "Running tests"
可用的 CEL 字段和函数
基本字段
event:push 或 pull_request 事件
target_branch:目标分支
source_branch:pull_request 事件的来源分支。对于 push 事件,它与 target_branch 相同
event_title:匹配事件标题,例如 push 事件的 commit 标题,以及 pull_request 事件的 pull 或 merge request 标题。目前仅支持 GitHub、GitLab 和 Bitbucket Cloud
last_commit_title:事件中最后一个 commit 的标题(平台增强功能 - 上游 Tekton 不提供)
文件变更字段
这些字段允许你根据事件中的特定文件变更进行过滤:
files.all:所有变更文件(新增、修改、删除、重命名)
files.added:已新增的文件
files.deleted:已删除的文件
files.modified:已修改的文件
files.renamed:已重命名的文件
注意:对于 Pull Request,PR 中的每个文件都会被列出。这些属性同时适用于 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 事件:
metadata:
annotations:
pipelinesascode.tekton.dev/on-cel-expression: |
event == "pull_request" &&
target_branch == "main" &&
source_branch.startsWith("wip")
使用 .pathChanged() 进行基于路径的过滤
NOTE
Pipelines-as-Code 支持两种方式来匹配特定事件中变更的文件:
.pathChanged() 后缀函数(在 CEL 表达式中)- 支持 glob 模式,但不支持不同类型的“变更”(新增、修改、删除)
files.* 属性(在 CEL 表达式中)- 可针对特定类型的变更文件,并支持使用 CEL 表达式
on-path-change 注解 - 更简单的基于注解方式(技术预览)
如果只在某个路径发生变更时运行 pipeline,你可以使用带有 glob 模式的 .pathChanged() 后缀函数:
metadata:
annotations:
pipelinesascode.tekton.dev/on-cel-expression: |
event == "pull_request" &&
"docs/*.md".pathChanged()
这会匹配 docs 目录中的每个 markdown 文件。
匹配多个路径模式
metadata:
annotations:
pipelinesascode.tekton.dev/on-cel-expression: |
event == "push" &&
("src/**".pathChanged() || "config/**".pathChanged())
注意:.pathChanged() 支持 glob 模式,但不会区分文件变更类型(新增、修改、删除、重命名)。如需更精确的过滤,请使用下方描述的 files.* 属性。
事件标题匹配
要匹配所有标题以 [DOWNSTREAM] 开头的 Pull Request:
metadata:
annotations:
pipelinesascode.tekton.dev/on-cel-expression: |
event == "pull_request" &&
event_title.startsWith("[DOWNSTREAM]")
排除分支
要在 pull_request 事件上运行 pipeline,但跳过 experimental 分支:
metadata:
annotations:
pipelinesascode.tekton.dev/on-cel-expression: |
event == "pull_request" &&
!source_branch.matches("^experimental.*")
复杂 CEL 表达式示例
一个结合多个条件的完整示例:
metadata:
annotations:
pipelinesascode.tekton.dev/on-cel-expression: |-
(
source_branch.matches("^(main|master|release-.*)$") ||
!event_title.contains("Auto-commit")
) && ((
event == "push" && (
source_branch.matches("^(main|master|release-.*)$") ||
target_branch.matches("^(main|master|release-.*)$") ||
target_branch.startsWith("refs/tags/")
)
) || (
event == "pull_request" && (
target_branch.matches("^(main|master|release-.*)$")
)
))
此表达式:
- 匹配 push 或 pull_request 事件
- 仅在 main、master 或 release-* 分支(或标签)上触发
- 排除标题中包含
"Auto-commit" 的 commit(除非位于受保护分支上)
使用正则表达式按分支匹配 PipelineRun
使用正则表达式匹配分支名称。例如,针对来源分支名称包含子串 feat/ 的 pull_request 事件触发 PipelineRun:
metadata:
annotations:
pipelinesascode.tekton.dev/on-cel-expression: |
event == "pull_request" &&
source_branch.matches(".*feat/.*")
使用 Files 属性按文件变更匹配 PipelineRun
你可以使用 files 属性匹配特定类型的文件变更。这比 .pathChanged() 更强大,因为它可以针对特定变更类型(新增、修改、删除、重命名)。
匹配 tmp 目录中的任意变更文件:
metadata:
annotations:
pipelinesascode.tekton.dev/on-cel-expression: |
files.all.exists(x, x.matches('tmp/'))
匹配 src 或 pkg 目录中的任意新增文件:
metadata:
annotations:
pipelinesascode.tekton.dev/on-cel-expression: |
files.added.exists(x, x.matches('src/|pkg/'))
匹配名为 test.go 的修改文件:
metadata:
annotations:
pipelinesascode.tekton.dev/on-cel-expression: |
files.modified.exists(x, x.matches('test.go'))
可用的文件属性:
files.all:所有变更文件(新增、修改、删除、重命名)
files.added:已新增的文件
files.deleted:已删除的文件
files.modified:已修改的文件
files.renamed:已重命名的文件
过滤 PipelineRuns 以排除非代码变更
当仅修改文档或配置文件时,排除 PipelineRun。此示例会过滤 pull_request 事件,以排除仅影响文档、配置文件或其他非代码文件的变更:
metadata:
annotations:
pipelinesascode.tekton.dev/on-cel-expression: |
event == "pull_request" &&
target_branch == "main" &&
!files.all.all(x, x.matches('^docs/') || x.matches('\\.md$') || x.matches('(\\.gitignore|OWNERS|PROJECT|LICENSE)$'))
此表达式将:
- 仅匹配目标为
main 分支的 pull_request 事件
- 如果所有变更文件都匹配以下任一模式,则排除该 PipelineRun:
docs/ 目录中的文件(^docs/)
- Markdown 文件(
\\.md$)
- 常见仓库元数据文件(
.gitignore、OWNERS、PROJECT、LICENSE)
注意:在 CEL 表达式中使用正则模式时,请记得正确转义特殊字符。反斜杠(\)需要写成双反斜杠(\\),以便在 CEL 字符串上下文中正确转义。
按事件标题匹配 PipelineRun
按标题匹配 Pull Request 或 commit。event_title 在 pull_request 事件中表示 Pull Request 标题,在 push 事件中表示 commit 标题:
metadata:
annotations:
pipelinesascode.tekton.dev/on-cel-expression: |
event == "pull_request" &&
event_title.startsWith("[DOWNSTREAM]")
匹配标题中不包含 "Auto-commit" 的 commit:
metadata:
annotations:
pipelinesascode.tekton.dev/on-cel-expression: |
event == "push" &&
!event_title.contains("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 发生了更新)时才匹配:
metadata:
annotations:
pipelinesascode.tekton.dev/on-cel-expression: |
body.pull_request.base.ref == "main" &&
body.pull_request.user.login == "superuser" &&
body.action == "synchronize"
重要说明:
- 在匹配 Pull Request 的 body payload 时,像
/retest 这样的 GitOps 注释不会按预期工作,因为此时 payload body 变成了评论的 body,而不是原始 Pull Request payload
- 如果使用基于 body payload 的 CEL 要重新测试 Pull Request,请通过 amend 并 force-push 进行一次虚拟更新:
git commit --amend --no-edit && git push --force-with-lease
根据 Git provider 发送的 headers 进行过滤。headers 以列表形式可用,并且始终为小写。
通过检查 header 仅匹配 GitHub pull_request 事件:
metadata:
annotations:
pipelinesascode.tekton.dev/on-cel-expression: |
headers['x-github-event'] == "pull_request"
仅匹配 GitLab merge request 事件:
metadata:
annotations:
pipelinesascode.tekton.dev/on-cel-expression: |
headers['x-gitlab-event'] == "Merge Request Hook"
进行中的取消
pipelinesascode.tekton.dev/cancel-in-progress 注解允许你在触发新的同类型 pipeline 时自动取消正在运行的 pipeline。
配置取消
将该注解设置为 "true" 以启用自动取消:
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
name: my-pipeline
annotations:
pipelinesascode.tekton.dev/on-target-branch: "[refs/heads/main]"
pipelinesascode.tekton.dev/on-event: "[push]"
pipelinesascode.tekton.dev/cancel-in-progress: "true"
spec:
pipelineSpec:
tasks:
- name: hello
taskSpec:
steps:
- name: echo
image: alpine:latest
script: |
echo "Hello from PAC!"
行为:
- 当触发新的 pipeline 时(例如同一分支上有新的 push),任何当前正在运行且具有相同注解的 pipeline 都会自动取消
- 这有助于防止同一分支上同时运行多个 pipeline
- 被取消的 pipeline 会在 Git provider 中显示为“Cancelled”状态
使用场景示例
防止 main 分支上的重复运行:
metadata:
annotations:
pipelinesascode.tekton.dev/on-target-branch: "[refs/heads/main]"
pipelinesascode.tekton.dev/on-event: "[push]"
pipelinesascode.tekton.dev/cancel-in-progress: "true"
这可确保如果 main 分支在短时间内发生多次 push,只有最新的 pipeline 会运行,从而避免资源浪费。
与 Pull Request 一起使用:
metadata:
annotations:
pipelinesascode.tekton.dev/on-target-branch: "[main]"
pipelinesascode.tekton.dev/on-event: "[pull_request]"
pipelinesascode.tekton.dev/cancel-in-progress: "true"
当 PR 使用新 commit 更新时,任何正在运行的该 PR pipeline 都会被取消,并启动一个新的 pipeline。
对 commit 和 URL 进行参数化
你可以使用 {{<var>}} 格式的动态可展开变量来指定 commit 和 URL 的参数。这些变量可用于:
两种变量类型
PAC 支持两种变量类型:
- PAC 动态变量(
{{ variable_name }}):PAC 特定变量(例如 {{ revision }}、{{ repo_url }}),在创建 PipelineRun 之前由 PAC 替换
- Tekton 参数(
$(params.param-name)):Tekton Pipeline 参数,可在 Repository CR 的 spec.params 中定义(详见 高级仓库配置)
本节介绍 PAC 动态变量。关于 Repository CR 参数,请参见 高级仓库配置。
- PipelineRun
params 值
- Task 参数
- Step 脚本和命令
- pipeline 定义中的任何字符串值
可用变量
目前,你可以使用以下变量:
变量使用示例
Git 仓库信息
spec:
params:
- name: repo-url
value: "{{ repo_url }}"
- name: revision
value: "{{ revision }}"
- name: branch
value: "{{ source_branch }}"
pipelineSpec:
tasks:
- name: clone
taskSpec:
steps:
- name: clone
image: alpine/git:latest
script: |
git clone {{ repo_url }}
cd {{ repo_name }}
git checkout {{ revision }}
事件信息
spec:
params:
- name: sender
value: "{{ sender }}"
- name: branch
value: "{{ target_branch }}"
pipelineSpec:
tasks:
- name: notify
taskSpec:
steps:
- name: notify
image: alpine:latest
script: |
echo "Pipeline triggered by {{ sender }} on branch {{ target_branch }}"
Pull Request 信息
spec:
params:
- name: pr-number
value: "{{ pull_request_number }}"
pipelineSpec:
tasks:
- name: test
taskSpec:
steps:
- name: test
image: alpine:latest
script: |
echo "Testing Pull Request #{{ pull_request_number }}"
注意:{{ pull_request_number }} 变量仅适用于 pull_request 事件类型。对于 push 事件,该变量不会被填充。
使用 Git 认证 Secret
对于私有仓库,PAC 会自动生成一个用于 git 认证的 secret。你可以在 pipeline task 中引用该 secret:
spec:
pipelineSpec:
tasks:
- name: clone
taskSpec:
steps:
- name: clone
image: alpine/git:latest
env:
- name: GIT_CREDENTIALS
valueFrom:
secretKeyRef:
name: "{{ git_auth_secret }}"
key: password
script: |
git clone https://github.com/user/private-repo
注意:{{ git_auth_secret }} 变量仅适用于私有仓库。当你为私有仓库配置认证时,PAC 会自动创建此 secret(参见 为私有仓库配置认证)。secret 名称格式为 pac-gitauth-<repository-name>-<hash>。
任务解析
PAC 可以自动从多个来源解析 task。你可以使用 PAC 注解(推荐)或 Tekton resolver 语法。
使用 PAC 注解(推荐)
PAC 提供了注解,用于自动从 Tekton Hub 获取并嵌入远程 task。这比使用 resolver 语法更简单。
远程 Task 注解
使用注解引用 Tekton Hub 中的 task:
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
name: my-pipeline
annotations:
pipelinesascode.tekton.dev/on-target-branch: "[refs/heads/main]"
pipelinesascode.tekton.dev/on-event: "[push]"
pipelinesascode.tekton.dev/task: "git-clone"
pipelinesascode.tekton.dev/task-1: "golangci-lint"
spec:
pipelineSpec:
tasks:
- name: fetch
taskRef:
name: git-clone
params:
- name: url
value: "{{ repo_url }}"
- name: revision
value: "{{ revision }}"
- name: lint
taskRef:
name: golangci-lint
runAfter: [fetch]
工作原理:
- 注解
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:第二个 task
pipelinesascode.tekton.dev/task-2:第三个 task
- 依此类推...
更多详情请参见 PAC Resolver。
使用 Resolver 语法
你也可以使用 Tekton 的 resolver 语法来引用 task。
本地 Task
引用定义在同一仓库中的 task:
.tekton/
├── pipelinerun.yaml
└── tasks/
└── build-task.yaml
spec:
pipelineSpec:
tasks:
- name: build
taskRef:
resolver: git
params:
- name: url
value: "{{ repo_url }}"
- name: revision
value: "{{ revision }}"
- name: pathInRepo
value: .tekton/tasks/build-task.yaml
Tekton Hub Task
引用 Tekton Hub 中的 task:
spec:
pipelineSpec:
tasks:
- name: git-clone
taskRef:
resolver: hub
params:
- name: name
value: git-clone
- name: kind
value: task
远程 URL Task
使用 PAC 注解引用远程 URL 中的 task(推荐):
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
name: my-pipeline
annotations:
# PAC 会自动处理远程 task 的认证
pipelinesascode.tekton.dev/task: "https://raw.githubusercontent.com/tektoncd/catalog/main/task/git-clone/0.9/git-clone.yaml"
spec:
pipelineSpec:
tasks:
- name: build
taskRef:
name: git-clone # 按名称引用该 task
Pipeline 示例
简单的构建 Pipeline
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
name: build-pipeline
annotations:
pipelinesascode.tekton.dev/on-target-branch: "[refs/heads/main]"
pipelinesascode.tekton.dev/on-event: "[push]"
spec:
pipelineSpec:
tasks:
- name: build
taskSpec:
steps:
- name: build
image: golang:1.21
script: |
go build -o app ./cmd/app
go test ./...
面向 PR 的测试 Pipeline
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
name: test-pipeline
annotations:
pipelinesascode.tekton.dev/on-target-branch: "[main]"
pipelinesascode.tekton.dev/on-event: "[pull_request]"
spec:
pipelineSpec:
tasks:
- name: test
taskSpec:
steps:
- name: run-tests
image: golang:1.21
script: |
go test -v ./...
go vet ./...
go fmt ./...
多阶段 Pipeline
此示例演示了一个完整的 CI pipeline,使用真实仓库完成 clone、测试和构建阶段:
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
name: ci-pipeline
annotations:
pipelinesascode.tekton.dev/on-target-branch: "[main]"
pipelinesascode.tekton.dev/on-event: "[push, pull_request]"
spec:
workspaces:
- name: source
emptyDir: {}
pipelineSpec:
workspaces:
- name: source
tasks:
- name: clone
workspaces:
- name: source
taskSpec:
workspaces:
- name: source
steps:
- name: clone
image: alpine/git:latest
script: |
git clone https://github.com/tektoncd/catalog $(workspaces.source.path)
cd $(workspaces.source.path)
echo "Cloned repository successfully"
ls -la
- name: check-content
runAfter: [clone]
workspaces:
- name: source
taskSpec:
workspaces:
- name: source
steps:
- name: check
image: alpine:latest
script: |
cd $(workspaces.source.path)
echo "Repository structure:"
ls -la
echo "Total files:"
find . -type f | wc -l
- name: validate-yaml
runAfter: [check-content]
workspaces:
- name: source
taskSpec:
workspaces:
- name: source
steps:
- name: validate
image: alpine:latest
script: |
cd $(workspaces.source.path)
echo "Checking for YAML files"
find . -name "*.yaml" -o -name "*.yml" | head -10
条件式 Pipeline
根据分支使用不同的 pipeline:
# .tekton/pipelinerun-main.yaml
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
name: main-pipeline
annotations:
pipelinesascode.tekton.dev/on-target-branch: "[refs/heads/main]"
pipelinesascode.tekton.dev/on-event: "[push]"
spec:
pipelineSpec:
tasks:
- name: deploy
taskSpec:
steps:
- name: deploy
image: deploy-tool:latest
script: |
deploy.sh production
# .tekton/pipelinerun-develop.yaml
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
name: develop-pipeline
annotations:
pipelinesascode.tekton.dev/on-target-branch: "[refs/heads/develop]"
pipelinesascode.tekton.dev/on-event: "[push]"
spec:
pipelineSpec:
tasks:
- name: deploy
taskSpec:
steps:
- name: deploy
image: deploy-tool:latest
script: |
deploy.sh staging
最佳实践
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. 测试
- 在特性分支中测试 pipeline 变更
- 使用 Merge Request pipeline 验证变更
- 保持 pipeline 简单且易于维护
故障排查
Pipeline 未触发
-
检查注解是否正确:
cat .tekton/pipelinerun.yaml | grep pipelinesascode.tekton.dev
-
验证分支名称是否匹配:
git branch --show-current
-
检查 PAC controller 日志:
kubectl logs -n <pac-namespace> -l app=pipelines-as-code-controller --tail=100 # 将 <pac-namespace> 替换为你的实际 namespace(默认:tekton-pipelines)
变量未解析
- 验证变量语法:使用
{{ variable_name }} 格式,例如 {{ revision }} 或 {{ repo_url }}
- 检查变量名拼写:确保变量名完全一致(例如
{{ repo_owner }}、{{ source_branch }})
- 验证变量可用性:某些变量(如
{{ pull_request_number }})仅适用于 pull_request 事件
- 检查 PAC controller 日志中的变量解析错误
找不到 Task
- 验证 task 引用是否正确
- 检查仓库中是否存在 task 文件
- 验证 Tekton Hub task 名称
- 检查远程 task 的网络连通性
下一步