Maintain Pipeline Code

For Regular Users

本指南面向普通用户,指导如何在其 Git 仓库中创建和维护流水线定义。

本指南介绍如何使用 PAC 在源代码仓库中维护流水线定义。

目录

Pipeline File LocationDefault LocationMultiple Pipeline FilesPipeline Definition StructureBasic StructureUsing Existing PipelineEvent AnnotationsMatching a Pull Request Event to a Pipeline RunMatching a Push Event to a Pipeline RunBranch SpecificationBranch and Path FilteringBranch FilteringPath FilteringExcluding Path ChangesCombining Path Change and IgnoreAdvanced Event MatchingCEL Expression FormatAvailable CEL Fields and FunctionsBasic FieldsFile Change FieldsAdvanced FieldsFunctionsCEL Expression ExamplesMatch Pull Request from Specific BranchPath-Based Filtering with .pathChanged()Match Multiple Path PatternsEvent Title MatchingExclude BranchComplex CEL Expression ExampleMatching PipelineRun by Branch with RegexMatching PipelineRun by File Changes with Files PropertyFiltering PipelineRuns to Exclude Non-Code ChangesMatching PipelineRun to Event TitleMatching PipelineRun on Body PayloadMatching PipelineRun to Request HeaderCancellation in ProgressConfigure CancellationExample Use CasesParameterizing Commits and URLsAvailable VariablesVariable Usage ExamplesGit Repository InformationEvent InformationPull Request InformationUsing Git Authentication SecretTask ResolutionUsing PAC Annotations (Recommended)Remote Task AnnotationsUsing Resolver SyntaxLocal TasksTekton Hub TasksRemote URL TasksPipeline ExamplesSimple Build PipelineTest Pipeline for PRsMulti-Stage PipelineConditional PipelineBest Practices1. Version Control2. Organization3. Security4. Reusability5. TestingTroubleshootingPipeline Not TriggeringVariables Not ResolvingTasks Not FoundNext Steps

Pipeline File Location

PAC 会在仓库中的特定位置查找流水线定义:

Default Location

默认位置是仓库根目录下的 .tekton/pipelinerun.yaml

your-repo/
├── .tekton/
│   └── pipelinerun.yaml
├── src/
└── README.md

Multiple Pipeline Files

你可以将流水线组织在多个文件中:

.tekton/
├── pipelinerun.yaml          # 主流水线
├── test-pipeline.yaml        # 测试流水线
└── deploy-pipeline.yaml      # 部署流水线

PAC 会处理 .tekton/ 目录下所有 .yaml.yml 文件。

Multiple PipelineRuns in Multiple Files

当你在不同文件中定义多个 PipelineRun 时:

  • 每个 PipelineRun 独立评估
  • 多个 PipelineRun 可以匹配同一事件(它们将并行运行)
  • 每个 PipelineRun 必须有唯一的注解来控制触发时机
  • 使用描述性文件名组织不同类型的流水线(例如 test-pipeline.yamldeploy-pipeline.yaml

示例:如果 test-pipeline.yamldeploy-pipeline.yaml 都匹配对 main 分支的 push 事件,则两个流水线将并行运行。

Pipeline Definition Structure

PAC 流水线是带有 PAC 特定注解的标准 Tekton PipelineRun 资源。

Understanding Tekton Resources
  • PipelineRun:Tekton 资源,用于执行流水线。在 PAC 中,你在 Git 仓库中定义 PipelineRun 资源,PAC 会根据 Git 事件自动创建和管理它们。
  • Pipeline:Tekton 资源,定义可复用的任务集合。你可以在 PipelineRun 中通过 pipelineRef 引用已有 Pipeline 资源,或使用 pipelineSpec 内联定义任务。

Basic Structure

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!"

Using Existing Pipeline

你可以引用 Kubernetes 集群中已定义的 Pipeline 资源:

Where to Define Pipeline Resources

Pipeline 资源可以定义在:

  • 与你的 Repository CR 相同的命名空间
  • 作为集群范围资源(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

Event Annotations

PAC 使用注解来确定何时触发流水线。这些注解添加在 PipelineRun 的 metadata 中。你可以通过在流水线运行上使用特殊注解,匹配不同的 Git 提供商事件。如果有多个流水线运行匹配同一事件,Pipelines as Code 会并行执行它们,并在流水线运行完成后立即将结果发布到 Git 提供商。

Matching a Pull Request Event to a Pipeline Run

你可以使用以下示例,将流水线匹配到针对 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"

Matching a Push Event to a Pipeline Run

你可以使用以下示例,将流水线匹配到针对 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"

Branch Specification

你可以通过逗号分隔的条目指定多个分支,例如 "[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 注解。

Branch and Path Filtering

Branch Filtering

使用 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]"

Path Filtering

Technology Preview

通过注解匹配 PipelineRun 到特定路径变更是技术预览功能。技术预览功能目前不受支持,可能功能不完整。我们不建议在生产环境中使用。

要基于事件中的特定路径变更触发 PipelineRun,请使用注解 pipelinesascode.tekton.dev/on-path-change

可以指定多个路径,使用逗号分隔。第一个匹配 PR 中变更文件的通配符将触发 PipelineRun。如果你想匹配包含逗号的文件或路径,可以使用 HTML 实体 , 转义逗号。

你仍需使用 on-target-branchon-event 注解指定事件类型和目标分支。

:::important Path Change Annotation Limitation

如果你使用 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]"

Excluding Path Changes

你可以使用反向注解 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/***]"

Combining Path Change and Ignore

你可以组合使用 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 不会被触发。

Advanced Event Matching

Pipelines as Code 支持使用 Common Expression Language (CEL) 进行高级事件匹配过滤。

:::important CEL vs Annotation Matching

  • 如果使用 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 Expression Format

使用 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"

Available CEL Fields and Functions

Basic Fields

  • 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 支持)

File Change Fields

这些字段允许基于事件中的具体文件变更进行过滤:

  • files.all:所有变更文件(新增、修改、删除、重命名)
  • files.added:新增文件
  • files.deleted:删除文件
  • files.modified:修改文件
  • files.renamed:重命名文件

注意:对于拉取请求,所有属于该请求的文件都会列出。这些属性对 push 和 pull_request 事件均可用。

Advanced Fields

  • body:来自 Git 提供商的完整负载体(技术预览)
  • headers:来自 Git 提供商的 HTTP 头(以 map 形式,头部名称均为小写)

Functions

  • .matches(pattern):字符串匹配正则表达式模式
  • .pathChanged():字符串后缀函数。字符串可为通配符模式,用于检查路径是否变更。目前仅支持 GitHub 和 GitLab。注意:.pathChanged() 支持通配符,但不区分变更类型(新增、修改、删除)。更具体过滤请使用 files.* 属性
  • .startsWith(prefix):检查字符串是否以指定前缀开始
  • .contains(substring):检查字符串是否包含指定子串
  • .exists(iterator, condition):检查集合中是否存在满足条件的元素(用于 files.* 属性)

CEL Expression Examples

Match Pull Request from Specific Branch

匹配针对 main 分支且源分支以 wip 开头的 pull_request 事件:

metadata:
  annotations:
    pipelinesascode.tekton.dev/on-cel-expression: |
      event == "pull_request" &&
      target_branch == "main" &&
      source_branch.startsWith("wip")

Path-Based Filtering with .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 文件。

Match Multiple Path Patterns

metadata:
  annotations:
    pipelinesascode.tekton.dev/on-cel-expression: |
      event == "push" &&
      ("src/**".pathChanged() || "config/**".pathChanged())

注意.pathChanged() 支持通配符,但不区分文件变更类型。更具体过滤请使用下述 files.* 属性。

Event Title Matching

匹配所有标题以 [DOWNSTREAM] 开头的拉取请求:

metadata:
  annotations:
    pipelinesascode.tekton.dev/on-cel-expression: |
      event == "pull_request" &&
      event_title.startsWith("[DOWNSTREAM]")

Exclude Branch

pull_request 事件中运行流水线,但排除源分支以 experimental 开头的:

metadata:
  annotations:
    pipelinesascode.tekton.dev/on-cel-expression: |
      event == "pull_request" &&
      !source_branch.matches("^experimental.*")

Complex CEL Expression Example

一个结合多条件的综合示例:

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" 的提交(受保护分支除外)

Matching PipelineRun by Branch with Regex

使用正则表达式匹配分支名。例如,触发源分支名包含 feat/ 的 pull_request 事件的 PipelineRun:

metadata:
  annotations:
    pipelinesascode.tekton.dev/on-cel-expression: |
      event == "pull_request" &&
      source_branch.matches(".*feat/.*")

Matching PipelineRun by File Changes with Files Property

你可以使用 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:重命名文件

Filtering PipelineRuns to Exclude Non-Code Changes

排除仅修改文档或配置文件的 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 表达式中使用正则表达式时,请正确转义特殊字符。反斜杠 (\) 需要双写 (\\) 以在 CEL 字符串上下文中正确转义。

Matching PipelineRun to Event Title

匹配拉取请求或提交的标题。event_title 对于 pull_request 事件是拉取请求标题,对于 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")

Matching PipelineRun on Body Payload

Technology Preview

基于 body 负载匹配 PipelineRun 是技术预览功能。技术预览功能目前不受支持,可能功能不完整。我们不建议在生产环境中使用。

Git 提供商传递的负载体可通过 CEL 变量 body 访问。你可以基于 Git 提供商发送的任意数据进行过滤。

例如,在 GitHub 上,匹配仅当拉取请求目标为 main,作者为 superuser,且操作为 synchronize(即拉取请求更新)时:

metadata:
  annotations:
    pipelinesascode.tekton.dev/on-cel-expression: |
      body.pull_request.base.ref == "main" &&
      body.pull_request.user.login == "superuser" &&
      body.action == "synchronize"

重要提示

  • 在拉取请求中匹配 body 负载时,GitOps 评论(如 /retest)可能无法正常工作,因为负载体变为评论内容,而非原始拉取请求负载
  • 使用 CEL 匹配 body 负载时,若需重新测试拉取请求,请通过修改提交并强制推送实现:git commit --amend --no-edit && git push --force-with-lease

Matching PipelineRun to Request Header

基于 Git 提供商发送的 HTTP 头过滤。头部以列表形式提供,且均为小写。

匹配仅 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"

Cancellation in Progress

pipelinesascode.tekton.dev/cancel-in-progress 注解允许你在触发同类型新流水线时,自动取消正在运行的流水线。

Configure Cancellation

将注解设置为 "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”状态

Example Use Cases

防止 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 时,仅运行最新流水线,避免资源浪费。

用于拉取请求

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 的正在运行流水线,并启动新的流水线。

Parameterizing Commits and URLs

你可以使用 {{<var>}} 格式的动态可展开变量,指定提交和 URL 的参数。这些变量可用于:

Two Types of Variables

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
  • 任务参数
  • 步骤脚本和命令
  • 流水线定义中的任意字符串值

Available Variables

当前可用变量如下:

变量描述示例适用范围
{{ repo_owner }}仓库所有者myorgusername所有事件
{{ repo_name }}仓库名称my-repo所有事件
{{ repo_url }}仓库完整 URLhttps://gitlab.com/user/repo所有事件
{{ revision }}提交的完整 SHA 版本号abc123def456...所有事件
{{ 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所有事件(私有仓库)

Variable Usage Examples

Git Repository Information

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 }}

Event Information

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 Information

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 事件,该变量不被填充。

Using Git Authentication 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>

Task Resolution

PAC 可以自动从多个来源解析任务。你可以使用 PAC 注解(推荐)或 Tekton 解析器语法。

PAC 提供注解,自动从 Tekton Hub 获取并嵌入远程任务。比使用解析器语法更简单。

Remote Task Annotations

通过注解引用 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

Using Resolver Syntax

你也可以使用 Tekton 的解析器语法引用任务。

Local Tasks

引用同一仓库中定义的任务:

.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 Tasks

引用 Tekton Hub 任务:

spec:
  pipelineSpec:
    tasks:
    - name: git-clone
      taskRef:
        resolver: hub
        params:
        - name: name
          value: git-clone
        - name: kind
          value: task

Remote URL Tasks

通过 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  # 通过名称引用任务

Pipeline Examples

Simple Build 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 ./...

Test Pipeline for PRs

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 ./...

Multi-Stage Pipeline

此示例展示了一个包含 clone、test 和 build 阶段的完整 CI 流水线,使用真实仓库:

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

Conditional 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

Best Practices

1. Version Control

  • 将所有流水线定义保存在 Git 中
  • 通过合并请求审查流水线变更
  • 为流水线版本打标签以保证可复现性

2. Organization

  • 使用描述性流水线名称
  • 将相关任务分组
  • 不同流水线类型使用不同文件

3. Security

  • 不要在流水线文件中硬编码 Secret
  • 使用 Kubernetes Secret 存储敏感数据
  • 通过 RBAC 限制流水线权限

4. Reusability

  • 创建可复用的任务定义
  • 尽可能使用 Tekton Hub 任务
  • 在仓库间共享常用任务

5. Testing

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

Troubleshooting

Pipeline Not Triggering

  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)

Variables Not Resolving

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

Tasks Not Found

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

Next Steps