Maintain Pipeline Code
For Regular Users
本指南面向普通用户,指导如何在其 Git 仓库中创建和维护流水线定义。
本指南介绍如何使用 PAC 在您的源代码仓库中维护流水线定义。
目录
流水线文件位置
PAC 会在仓库中的特定位置查找流水线定义:
默认位置
默认位置是仓库根目录下的 .tekton/pipelinerun.yaml。
your-repo/
├── .tekton/
│ └── pipelinerun.yaml
├── src/
└── README.md
多个流水线文件
您可以将流水线组织在多个文件中:
.tekton/
├── pipelinerun.yaml # 主流水线
├── test-pipeline.yaml # 测试流水线
└── deploy-pipeline.yaml # 部署流水线
PAC 会处理 .tekton/ 目录下所有的 .yaml 和 .yml 文件。
多文件中多个 PipelineRun
当您在不同文件中定义多个 PipelineRun 时:
- 每个 PipelineRun 独立评估
- 多个 PipelineRun 可以匹配同一事件(它们将并行运行)
- 每个 PipelineRun 必须有唯一注解来控制触发时机
- 使用描述性文件名组织不同类型的流水线(例如
test-pipeline.yaml、deploy-pipeline.yaml)
示例:如果 test-pipeline.yaml 和 deploy-pipeline.yaml 都匹配针对 main 分支的 push 事件,则两个流水线将并行运行。
流水线定义结构
PAC 流水线是带有 PAC 特定注解的标准 Tekton PipelineRun 资源。
理解 Tekton 资源
- PipelineRun:执行流水线的 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 相同的命名空间
- 作为集群范围资源(ClusterTasks)
- 在您的 Git 仓库中,并通过 resolver 语法引用(详见 Task Resolution 部分)
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 使用注解决定何时触发流水线。这些注解添加在 PipelineRun 的 metadata 中。您可以通过在流水线上使用特殊注解来匹配不同的 Git 提供商事件。如果有多个流水线匹配同一事件,Pipelines as Code 会并行运行它们,并在流水线运行结束后立即将结果回传给 Git 提供商。
匹配 Pull Request 事件到 PipelineRun
您可以使用以下示例将流水线匹配到针对 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 事件到 PipelineRun
您可以使用以下示例将流水线匹配到针对 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"
- 使用通配符的模式匹配,如
"refs/heads/*"
- 标签,如
"refs/tags/1.*"
示例:
多个分支:
metadata:
annotations:
pipelinesascode.tekton.dev/on-target-branch: "[main, release-nightly]"
pipelinesascode.tekton.dev/on-event: "[push]"
使用通配符匹配所有分支:
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 注解按目标分支过滤。您可以使用通配符匹配多个分支:
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 中变更文件的通配符将触发 PipelineRun。如果要匹配包含逗号的文件或路径,可以使用 , HTML 实体进行转义。
您仍需使用 on-target-branch 和 on-event 注解指定事件类型和目标分支。
:::important 路径变更注解限制
如果您使用 CEL 表达式(on-cel-expression),则 on-path-change 和 on-path-change-ignore 注解将被忽略。使用 CEL 时,请使用带有 files.* 属性或 .pathChanged() 函数的表达式进行基于路径的过滤。
:::
示例:
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 分支且包含对 docs 目录(及子目录)中 .md 文件或 manual 目录中 .rst 文件的变更时匹配并触发 PipelineRun。
路径模式:
- 使用通配符模式,不是正则表达式
src/** - 匹配 src 目录及其子目录下所有文件
*.go - 匹配仓库根目录下所有 Go 文件
- 多个模式用逗号分隔:
"[src/**,*.go,config/**]"
测试通配符模式:
tkn pac CLI 提供了方便的通配符测试命令:
tkn pac info globbing "[PATTERN]"
排除路径变更
您可以使用反向注解 pipelinesascode.tekton.dev/on-path-change-ignore,当指定路径未发生变更时触发 PipelineRun。
仍需指定事件类型和目标分支。如果使用 CEL 表达式,on-path-change-ignore 注解将被忽略。
此 PipelineRun 会在变更发生在 docs 文件夹外时运行:
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 事件的提交标题,pull_request 事件的拉取或合并请求标题。当前支持 GitHub、GitLab 和 Bitbucket Cloud
last_commit_title:事件中最后一次提交的标题(平台增强功能 - 上游 Tekton 不支持)
文件变更字段
这些字段允许基于事件中的具体文件变更进行过滤:
files.all:所有变更文件(新增、修改、删除、重命名)
files.added:新增文件
files.deleted:删除文件
files.modified:修改文件
files.renamed:重命名文件
注意:对于拉取请求,所有属于该请求的文件都会列出。这些属性适用于 push 和 pull_request 事件。
高级字段
body:来自 Git 提供商的完整负载体(技术预览)
headers:来自 Git 提供商的 HTTP 头(以 map 形式,头部名称均为小写)
函数
.matches(pattern):字符串匹配正则表达式模式
.pathChanged():字符串后缀函数。字符串可为通配符模式,用于检查路径是否变更。当前仅支持 GitHub 和 GitLab。注意:.pathChanged() 支持通配符,但不支持区分变更类型(新增、修改、删除)。更具体的过滤请使用 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 表达式中) - 支持通配符,但不支持区分变更类型(新增、修改、删除)
files.* 属性(CEL 表达式中) - 可针对特定变更类型,支持复杂 CEL 表达式
on-path-change 注解 - 简单注解方式(技术预览)
仅当路径变更时运行流水线,使用 .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() 支持通配符,但不区分文件变更类型。更具体过滤请使用下述 files.* 属性。
事件标题匹配
匹配所有标题以 [DOWNSTREAM] 开头的拉取请求:
metadata:
annotations:
pipelinesascode.tekton.dev/on-cel-expression: |
event == "pull_request" &&
event_title.startsWith("[DOWNSTREAM]")
排除分支
在 pull_request 事件中运行流水线,但跳过 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" 的提交(受保护分支除外)
使用正则表达式匹配分支名
匹配源分支名包含 feat/ 的 pull_request 事件:
metadata:
annotations:
pipelinesascode.tekton.dev/on-cel-expression: |
event == "pull_request" &&
source_branch.matches(".*feat/.*")
使用 files 属性匹配文件变更
使用 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:重命名文件
过滤排除非代码变更的 PipelineRun
排除仅修改文档、配置文件或其他非代码文件的 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 表达式中使用正则时,请正确转义特殊字符。反斜杠 (\) 需双写 (\\) 以正确转义。
匹配事件标题的 PipelineRun
匹配拉取请求或提交标题。event_title 是 pull_request 事件的 PR 标题,push 事件的提交标题:
metadata:
annotations:
pipelinesascode.tekton.dev/on-cel-expression: |
event == "pull_request" &&
event_title.startsWith("[DOWNSTREAM]")
匹配标题不包含 "Auto-commit" 的提交:
metadata:
annotations:
pipelinesascode.tekton.dev/on-cel-expression: |
event == "push" &&
!event_title.contains("Auto-commit")
匹配 Body 负载的 PipelineRun
技术预览
基于 body 负载匹配 PipelineRun 是技术预览功能。当前不受支持,可能功能不完整。建议勿用于生产环境。
Git 提供商传递的负载体可通过 CEL 变量 body 访问。您可以基于 Git 提供商发送的任意数据进行过滤。
例如,在 GitHub 上,匹配仅当 PR 目标为 main,作者为 superuser,且操作为 synchronize(即 PR 更新)时:
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 负载时,GitOps 评论如
/retest 可能无法正常工作,因为负载体变成了评论内容,而非原始 PR 负载
- 使用 CEL 匹配 body 负载时,若需重新测试 PR,请通过修改提交并强制推送实现:
git commit --amend --no-edit && git push --force-with-lease
匹配请求头的 PipelineRun
基于 Git 提供商发送的请求头过滤。请求头以列表形式提供,且均为小写。
匹配仅 GitHub 的 pull_request 事件:
metadata:
annotations:
pipelinesascode.tekton.dev/on-cel-expression: |
headers['x-github-event'] == "pull_request"
匹配仅 GitLab 的合并请求事件:
metadata:
annotations:
pipelinesascode.tekton.dev/on-cel-expression: |
headers['x-gitlab-event'] == "Merge Request Hook"
取消进行中的流水线
pipelinesascode.tekton.dev/cancel-in-progress 注解允许您在触发同类型新流水线时自动取消正在运行的流水线。
配置取消
将注解设置为 "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!"
行为:
- 当触发新流水线(例如同一分支的新 push)时,任何带有相同注解的正在运行流水线将被自动取消
- 有助于避免同一分支上多个流水线同时运行
- 被取消的流水线在 Git 提供商中显示为“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 分支快速多次推送时,仅运行最新流水线,避免资源浪费。
用于 Pull Requests:
metadata:
annotations:
pipelinesascode.tekton.dev/on-target-branch: "[main]"
pipelinesascode.tekton.dev/on-event: "[pull_request]"
pipelinesascode.tekton.dev/cancel-in-progress: "true"
当 PR 更新新提交时,取消该 PR 的正在运行流水线,启动新的流水线。
提交和 URL 参数化
您可以使用 {{<var>}} 格式的动态可展开变量来指定提交和 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 值
- 任务参数
- 步骤脚本和命令
- 流水线定义中的任意字符串值
可用变量
当前可用变量如下:
变量使用示例
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。您可以在流水线任务中引用该 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 可以自动解析来自多个来源的任务。您可以使用 PAC 注解(推荐)或 Tekton 解析器语法。
使用 PAC 注解(推荐)
PAC 提供注解,自动从 Tekton Hub 获取并嵌入远程任务。比使用解析器语法更简单。
远程任务注解
通过注解引用 Tekton Hub 任务:
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-1、task-2 等)引用更多任务
- PAC 自动将所有引用的任务定义嵌入 PipelineRun
- 您可以通过
taskRef.name 使用 Tekton Hub 中的任务名称引用它们
注解编号规则:
pipelinesascode.tekton.dev/task:第一个任务(等同于 task-0)
pipelinesascode.tekton.dev/task-1:第二个任务
pipelinesascode.tekton.dev/task-2:第三个任务
- 依此类推...
详情见 PAC Resolver。
使用解析器语法
您也可以使用 Tekton 的解析器语法引用任务。
本地任务
引用同一仓库中定义的任务:
.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 任务
引用 Tekton Hub 中的任务:
spec:
pipelineSpec:
tasks:
- name: git-clone
taskRef:
resolver: hub
params:
- name: name
value: git-clone
- name: kind
value: task
远程 URL 任务
使用 PAC 注解引用远程 URL 任务(推荐):
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
name: my-pipeline
annotations:
# PAC 自动处理远程任务认证
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 # 通过名称引用任务
流水线示例
简单构建流水线
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 测试流水线
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 ./...
多阶段流水线
此示例演示使用真实仓库的完整 CI 流水线,包含 clone、test 和 build 阶段:
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
条件流水线
根据分支使用不同流水线:
# .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. 版本控制
- 将所有流水线定义保存在 Git 中
- 通过合并请求审查流水线变更
- 为流水线版本打标签以保证可复现性
2. 组织结构
- 使用描述性流水线名称
- 将相关任务分组
- 不同流水线类型使用独立文件
3. 安全性
- 不要在流水线文件中硬编码 Secret
- 使用 Kubernetes Secret 存储敏感数据
- 通过 RBAC 限制流水线权限
4. 可复用性
- 创建可复用的任务定义
- 尽可能使用 Tekton Hub 任务
- 在多个仓库间共享通用任务
5. 测试
- 在功能分支中测试流水线变更
- 使用合并请求流水线验证变更
- 保持流水线简单且易维护
故障排查
流水线未触发
-
检查注解是否正确:
cat .tekton/pipelinerun.yaml | grep pipelinesascode.tekton.dev
-
验证分支名称是否匹配:
git branch --show-current
-
查看 PAC 控制器日志:
kubectl logs -n <pac-namespace> -l app=pipelines-as-code-controller --tail=100 # 将 <pac-namespace> 替换为实际命名空间(默认:tekton-pipelines)
变量未解析
- 验证变量语法:使用
{{ variable_name }} 格式,如 {{ revision }} 或 {{ repo_url }}
- 检查变量名称拼写:确保变量名完全匹配(如
{{ repo_owner }}、{{ source_branch }})
- 验证变量可用性:部分变量如
{{ pull_request_number }} 仅在 pull_request 事件中可用
- 查看 PAC 控制器日志中变量解析错误
任务未找到
- 验证任务引用是否正确
- 检查仓库中任务文件是否存在
- 验证 Tekton Hub 任务名称
- 检查远程任务的网络连接
后续步骤