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.yamldeploy-pipeline.yaml

示例:如果 test-pipeline.yamldeploy-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-branchon-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-branchon-event 注解指定事件类型和目标分支。

:::important 路径变更注解限制

如果您使用 CEL 表达式(on-cel-expression),则 on-path-changeon-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-changeon-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-branchon-event 注解
  • 如果不使用 on-cel-expression:PAC 会使用 on-target-branchon-event 注解进行匹配

不能同时使用 CEL 表达式和简单注解。请根据需求选择:

  • 使用简单注解(on-target-branchon-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_branchpull_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/'))

匹配 srcpkg 目录下新增文件:

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)$'))

该表达式:

  • 仅匹配目标分支为 mainpull_request 事件
  • 排除所有变更文件均匹配以下模式时的 PipelineRun:
    • docs/ 目录下文件 (^docs/)
    • Markdown 文件 (\\.md$)
    • 常见仓库元数据文件(.gitignoreOWNERSPROJECTLICENSE

注意:在 CEL 表达式中使用正则时,请正确转义特殊字符。反斜杠 (\) 需双写 (\\) 以正确转义。

匹配事件标题的 PipelineRun

匹配拉取请求或提交标题。event_titlepull_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
  • 任务参数
  • 步骤脚本和命令
  • 流水线定义中的任意字符串值

可用变量

当前可用变量如下:

变量描述示例适用事件
{{ repo_owner }}仓库所有者myorgusername所有事件
{{ repo_name }}仓库名称my-repo所有事件
{{ repo_url }}仓库完整 URLhttps://gitlab.com/user/repo所有事件
{{ revision }}提交的完整 SHAabc123def456...所有事件
{{ sender }}提交发送者的用户名或账户 IDusernameuser123所有事件
{{ source_branch }}事件来源分支名称mainfeature/xyz所有事件
{{ target_branch }}事件目标分支名称。对于 push 事件,与 source_branch 相同maindevelop所有事件
{{ pull_request_number }}拉取或合并请求编号,仅在 pull_request 事件类型中定义123仅拉取请求事件
{{ git_auth_secret }}自动生成的用于私有仓库检出时 Git 提供商令牌的 Secret 名称pac-gitauth-repo-xxx所有事件(私有仓库)

变量使用示例

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-1task-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. 测试

  • 在功能分支中测试流水线变更
  • 使用合并请求流水线验证变更
  • 保持流水线简单且易维护

故障排查

流水线未触发

  1. 检查注解是否正确:

    cat .tekton/pipelinerun.yaml | grep pipelinesascode.tekton.dev
  2. 验证分支名称是否匹配:

    git branch --show-current
  3. 查看 PAC 控制器日志:

    kubectl logs -n <pac-namespace> -l app=pipelines-as-code-controller --tail=100  # 将 <pac-namespace> 替换为实际命名空间(默认:tekton-pipelines)

变量未解析

  1. 验证变量语法:使用 {{ variable_name }} 格式,如 {{ revision }}{{ repo_url }}
  2. 检查变量名称拼写:确保变量名完全匹配(如 {{ repo_owner }}{{ source_branch }}
  3. 验证变量可用性:部分变量如 {{ pull_request_number }} 仅在 pull_request 事件中可用
  4. 查看 PAC 控制器日志中变量解析错误

任务未找到

  1. 验证任务引用是否正确
  2. 检查仓库中任务文件是否存在
  3. 验证 Tekton Hub 任务名称
  4. 检查远程任务的网络连接

后续步骤