Define PipelineRuns in Git

For Regular Users

This guide is for regular users who define PAC PipelineRun manifests in Git repositories.

PAC reads Tekton PipelineRun manifests from .tekton/, matches them against Git events, and creates the matching PipelineRun in the namespace of the Repository CR.

Pipeline File Location

PAC processes all .yaml and .yml files under .tekton/:

your-repo/
├── .tekton/
│   ├── pipelinerun.yaml
│   ├── test-pipeline.yaml
│   └── deploy-pipeline.yaml
└── src/

Each PipelineRun is evaluated independently. If multiple files match the same event, PAC creates multiple PipelineRuns.

Choose a Pipeline Definition Scenario

Choose how the PipelineRun defines the work to run: inline with pipelineSpec, or by referencing a reusable Pipeline with pipelineRef.

Define the Pipeline Inline with pipelineSpec

Use pipelineSpec when the pipeline logic should live directly in the same Git file as the trigger definition:

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

Reference a Pipeline with pipelineRef

Use pipelineRef when the PipelineRun should reuse a Pipeline definition.

Pipeline Defined in Git

With the default remote-tasks: "true", a plain pipelineRef.name should reference a Pipeline that PAC can resolve from Git. PAC checks the pipelinesascode.tekton.dev/pipeline annotation first, then Pipeline files under .tekton/ and its subdirectories.

Common layout:

.tekton/
├── pipelinerun.yaml
└── pipeline.yaml

pipeline.yaml:

apiVersion: tekton.dev/v1
kind: Pipeline
metadata:
  name: my-pipeline-resource
spec:
  tasks:
  - name: hello
    taskSpec:
      steps:
      - name: echo
        image: alpine:latest
        script: |
          echo "Hello from a Pipeline in Git"

pipelinerun.yaml:

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

For other Pipeline sources, use pipelinesascode.tekton.dev/pipeline. See PAC Resolver and PAC pipeline resolution documentation.

Pipeline Defined in the Cluster

If the Pipeline is already managed in the cluster, for example by the platform Pipeline product, use one of these approaches.

Keep remote-tasks: "true" and reference the namespaced Pipeline with the Tekton cluster 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:
    resolver: cluster
    params:
    - name: kind
      value: pipeline
    - name: name
      value: my-pipeline-resource
    - name: namespace
      value: my-namespace

Keep the namespace parameter unless the cluster resolver has a default namespace configured. If both this parameter and the resolver default namespace are empty, resolution fails.

Another option is for an administrator to set remote-tasks: "false" in the PAC component configuration. In that mode, a plain pipelineRef.name can reference a Pipeline in the same namespace as the generated PipelineRun:

spec:
  pipelineRef:
    name: my-pipeline-resource

PAC does not inline or resolve the Pipeline in this mode. Tekton resolves the reference after PAC creates the PipelineRun, so the Pipeline must already exist in the target namespace and the runtime ServiceAccount must have permission to use it.

Trigger Events

After you choose pipelineSpec or pipelineRef, add PAC annotations to control which Git events trigger the PipelineRun.

AnnotationPurpose
pipelinesascode.tekton.dev/on-eventMatch event types such as push or pull_request
pipelinesascode.tekton.dev/on-target-branchMatch the target branch or tag
pipelinesascode.tekton.dev/on-commentMatch custom pull request or merge request comments with a regular expression
pipelinesascode.tekton.dev/on-labelMatch pull request or merge request labels
pipelinesascode.tekton.dev/on-cel-expressionUse CEL for advanced matching

Matching a Pull Request Event

metadata:
  annotations:
    pipelinesascode.tekton.dev/on-target-branch: "[main]"
    pipelinesascode.tekton.dev/on-event: "[pull_request]"

Matching a Push Event

metadata:
  annotations:
    pipelinesascode.tekton.dev/on-target-branch: "[refs/heads/main]"
    pipelinesascode.tekton.dev/on-event: "[push]"

Matching a Custom Comment

Use on-comment for repository-specific pull request or merge request commands. The value is a regular expression matched against a new comment after PAC trims leading and trailing spaces and newlines:

metadata:
  annotations:
    pipelinesascode.tekton.dev/on-target-branch: "[main]"
    pipelinesascode.tekton.dev/on-event: "[pull_request]"
    pipelinesascode.tekton.dev/on-comment: "^/deploy-preview$"

on-comment is Technology Preview. Use built-in GitOps commands such as /test, /retest, and /cancel when you want PAC's native command behavior instead of a repository-specific trigger.

Matching Pull Request Labels

Use on-label when a PipelineRun should run only for pull requests or merge requests that have a matching label:

metadata:
  annotations:
    pipelinesascode.tekton.dev/on-target-branch: "[main]"
    pipelinesascode.tekton.dev/on-event: "[pull_request]"
    pipelinesascode.tekton.dev/on-label: "[ready-for-ci]"

on-label is Technology Preview. It still depends on on-event and on-target-branch. It is supported for GitHub, Gitea, and GitLab repositories, but not for Bitbucket repositories.

Branch Specification

on-target-branch accepts full refs, branch names, tags, globs, and comma-separated values.

MatchValue
Exact branch[main]
Multiple branches[main, release-nightly]
Full branch ref[refs/heads/main]
Branch glob[refs/heads/feature/*]
Tag glob[refs/tags/1.*]

Branch and Path Filtering

Use branch annotations for simple filtering:

metadata:
  annotations:
    pipelinesascode.tekton.dev/on-target-branch: "[main, develop]"
    pipelinesascode.tekton.dev/on-event: "[push, pull_request]"

Path-change annotations are Technology Preview. If on-cel-expression is set, PAC ignores on-path-change and on-path-change-ignore.

metadata:
  annotations:
    pipelinesascode.tekton.dev/on-target-branch: "[main]"
    pipelinesascode.tekton.dev/on-event: "[pull_request]"
    pipelinesascode.tekton.dev/on-path-change: "[docs/**.md]"
    pipelinesascode.tekton.dev/on-path-change-ignore: "[docs/generated/**]"

Advanced Event Matching

Use pipelinesascode.tekton.dev/on-cel-expression for complex conditions. When CEL is set, PAC uses the CEL expression and ignores on-target-branch, on-event, on-label, on-path-change, and on-path-change-ignore.

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

Common CEL fields include event, event_title, target_branch, source_branch, target_url, source_url, files.all, files.added, files.deleted, files.modified, files.renamed, body, and headers.

Cancellation in Progress

Use pipelinesascode.tekton.dev/cancel-in-progress: "true" to cancel an older matching run when a new one starts:

metadata:
  annotations:
    pipelinesascode.tekton.dev/on-target-branch: "[refs/heads/main]"
    pipelinesascode.tekton.dev/on-event: "[push]"
    pipelinesascode.tekton.dev/cancel-in-progress: "true"

Parameterizing Commits and URLs

PAC replaces dynamic variables in the {{ variable_name }} format before creating the PipelineRun. Tekton parameters such as $(params.name) are handled later by Tekton.

VariableDescriptionAvailability
{{ body }}Webhook payload bodyAll events
{{ event_type }}PAC event type, such as push or pull_requestAll events
{{ git_auth_secret }}Generated Git authentication Secret namePrivate repositories
{{ git_tag }}Git tag nameTag push events
{{ headers }}Webhook request headersAll events
{{ pull_request_labels }}Pull request or merge request labels separated by newlinesPull request events
{{ pull_request_number }}Pull or merge request numberPull request events
{{ repo_owner }}Repository ownerAll events
{{ repo_name }}Repository nameAll events
{{ repo_url }}Repository URLAll events
{{ revision }}Commit SHAAll events
{{ sender }}Event senderAll events
{{ source_branch }}Source branchAll events
{{ source_url }}Source repository URLAll events
{{ target_branch }}Target branchAll events
{{ target_namespace }}Namespace where PAC creates the PipelineRunAll events
{{ trigger_comment }}Comment that triggered the runGitOps command triggers

Example:

spec:
  params:
  - name: repo-url
    value: "{{ repo_url }}"
  - name: revision
    value: "{{ revision }}"

For private repositories, {{ git_auth_secret }} is available when the Repository references a Git access token.

Task Resolution

PAC can embed tasks referenced by PAC annotations, or you can use Tekton resolver syntax directly.

metadata:
  annotations:
    pipelinesascode.tekton.dev/task: "git-clone"
spec:
  pipelineSpec:
    tasks:
    - name: fetch
      taskRef:
        name: git-clone

See PAC Resolver for supported task and Pipeline sources.

Troubleshooting

IssueCheck
No PipelineRun is createdConfirm the file is under .tekton/ and the event annotations match the Git event
Namespace Pipeline is not foundWith default remote-tasks: "true", use pipelineRef.resolver: cluster or ask an administrator to set remote-tasks: "false"
Variables are not replacedCheck {{ variable_name }} syntax and event-specific availability
Remote tasks are not foundCheck task annotation names, resolver configuration, and PAC controller logs

Useful checks:

kubectl get pipelineruns -n <namespace>
kubectl logs -n <pac-namespace> -l app=pipelines-as-code-controller --tail=100

Next Steps