Skip to main content

Core concepts

This guide explains the architecture, components, and key concepts of Pipelines as Code to help you understand how it works and how to use it effectively.

Architecture overview

Pipelines as Code consists of three main components that work together to provide a complete CI/CD solution for Tekton:

Controller

Receives webhook events from Git providers and orchestrates pipeline execution

Watcher

Monitors PipelineRun execution and reports status back to Git providers

Webhook

Validates Repository CRDs and enforces security policies via admission webhook

Component diagram

Key components

Controller

The controller (pipelines-as-code-controller) is the main component that:
  • Receives webhook events from Git providers (push, pull request, etc.)
  • Matches events to Repository CRDs in the cluster
  • Fetches pipeline definitions from the .tekton/ directory in your repository
  • Resolves remote tasks from Tekton Hub or Artifact Hub
  • Validates pipeline YAML before submission
  • Creates PipelineRuns in the appropriate namespace
  • Injects authentication tokens and secrets
  • Handles authorization checks (OWNERS files, permissions)
Location: /home/daytona/workspace/source/cmd/pipelines-as-code-controller/main.go:1
The controller uses the Knative eventing adapter pattern to handle events efficiently and scale based on load.

Watcher

The watcher (pipelines-as-code-watcher) monitors PipelineRun execution and:
  • Watches for PipelineRun status changes in real-time
  • Collects task logs and error information
  • Posts status updates to Git providers (GitHub Checks, GitLab pipelines, etc.)
  • Creates comments on pull requests with execution details
  • Extracts error snippets and matches them to source code lines
  • Updates Repository CR status with recent PipelineRun history
Location: /home/daytona/workspace/source/cmd/pipelines-as-code-watcher/main.go:1
The watcher runs as a separate process with multiple reconcilers for efficient status reporting across many repositories.

Webhook

The webhook (pipelines-as-code-webhook) is a Kubernetes admission webhook that:
  • Validates Repository CRDs before they’re created or updated
  • Enforces that each repository URL is unique across the cluster
  • Validates that repository URLs are well-formed and non-empty
  • Prevents security issues from duplicate or invalid repositories
Location: /home/daytona/workspace/source/cmd/pipelines-as-code-webhook/main.go:1
Disabling this webhook is not supported and may pose a security risk in clusters with untrusted users, as it could allow one user to hijack another’s repository.

Repository Custom Resource Definition (CRD)

The Repository CRD is the core configuration object in Pipelines as Code. It serves several purposes:

Purpose

  • Informs Pipelines as Code that events from a specific URL should be handled
  • Specifies the namespace where PipelineRuns will be executed
  • References API secrets, usernames, or API URLs for Git provider authentication
  • Stores the last PipelineRun statuses (5 by default)
  • Allows declaring custom parameters that can be expanded in PipelineRuns

Example

apiVersion: "pipelinesascode.tekton.dev/v1alpha1"
kind: Repository
metadata:
  name: my-project
  namespace: my-project-ci
spec:
  url: "https://github.com/myorg/my-project"
  settings:
    pipelinerun_provenance: "source"
    policy:
      ok_to_test:
        - "maintainer1"
        - "maintainer2"
  concurrency_limit: 2
Location: /home/daytona/workspace/source/pkg/apis/pipelinesascode/v1alpha1/types.go:11

Key fields

The Git repository URL that this CR manages. Must be a valid HTTP/HTTPS URL.
spec:
  url: "https://github.com/myorg/my-project"
You cannot create a Repository CR in the same namespace where Pipelines as Code is deployed (e.g., pipelines-as-code namespace).

Event flow

Understanding how events flow through Pipelines as Code helps you troubleshoot issues and optimize your pipelines.
1

Git event occurs

A developer performs an action like:
  • Pushing code to a branch
  • Opening a pull request
  • Commenting on a pull request
  • Creating a tag
  • Merging a pull request
2

Webhook sent to controller

The Git provider sends a webhook payload to the Pipelines as Code controller endpoint. Authentication is verified using:
  • GitHub App JWT signature (for GitHub Apps)
  • Webhook secret (for webhook-based integrations)
3

Repository lookup

The controller:
  • Extracts the repository URL from the webhook payload
  • Searches for a matching Repository CRD across all namespaces
  • If target-namespace annotation exists in the pipeline, only searches that namespace
  • Validates that exactly one Repository CR matches
4

Authorization check

The controller verifies the user has permission to trigger pipelines by checking:
  • Repository ownership
  • Collaborator status
  • Organization membership
  • OWNERS file in the repository
  • Policy configuration in the Repository CR
5

Fetch pipeline definitions

The controller:
  • Clones the repository (or fetches from the default branch based on provenance settings)
  • Looks for .tekton/*.yaml files in the repository
  • Parses and validates the YAML syntax
6

Match pipelines to event

For each pipeline definition, the controller checks if:
  • The pipelinesascode.tekton.dev/on-event annotation matches the event type
  • The pipelinesascode.tekton.dev/on-target-branch annotation matches the branch
  • Any CEL expressions in pipelinesascode.tekton.dev/on-cel-expression evaluate to true
  • Path filters match the changed files
7

Resolve remote tasks

The controller:
  • Identifies tasks referenced via resolver: hub or resolver: bundles
  • Fetches task definitions from Tekton Hub, Artifact Hub, or OCI bundles
  • Inlines remote tasks into the pipeline definition
  • Validates the complete pipeline
8

Variable substitution

The controller replaces template variables like:
  • {{ repo_url }} - Full repository URL
  • {{ revision }} - Git commit SHA
  • {{ target_branch }} - Target branch name
  • {{ source_branch }} - Source branch name
  • Custom parameters from the Repository CR
9

Create PipelineRuns

The controller:
  • Creates PipelineRun resources in the namespace where the Repository CR exists
  • Injects Git provider tokens as secrets
  • Applies concurrency limits if configured
  • Queues PipelineRuns if needed
10

Monitor execution

The watcher:
  • Watches the created PipelineRuns for status changes
  • Collects logs from each task as they execute
  • Detects task failures and extracts error messages
11

Report status

The watcher:
  • Posts status checks to the Git provider (GitHub Checks, GitLab pipeline status)
  • Creates or updates comments on pull requests
  • Links to dashboard or logs for detailed information
  • Annotates source code lines with error messages (GitHub only)
12

Update Repository CR

The watcher:
  • Updates the Repository CR status with PipelineRun completion information
  • Stores the last 5 PipelineRun statuses by default
  • Includes commit SHA, title, status, and log URL

Pipeline definitions

Pipeline definitions in Pipelines as Code are standard Tekton PipelineRuns with special annotations.

Annotations

Annotations control when and how pipelines are executed:
Specifies which Git events trigger this pipeline.
annotations:
  pipelinesascode.tekton.dev/on-event: "[pull_request, push]"
Supported events:
  • pull_request - PR opened, synchronized, or reopened
  • push - Code pushed to a branch
  • incoming - Manual trigger via incoming webhook

Template variables

Pipelines as Code provides template variables that are substituted at runtime:
VariableDescriptionExample
{{ repo_url }}Full repository URLhttps://github.com/myorg/myrepo
{{ revision }}Git commit SHAa1b2c3d4e5f6...
{{ target_branch }}Target branch (for PRs)main
{{ source_branch }}Source branch (for PRs)feature-123
{{ sender }}User who triggered the eventdeveloper123
{{ event_type }}Type of eventpull_request

Example pipeline

.tekton/pr-build.yaml
apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
  name: pr-build
  annotations:
    pipelinesascode.tekton.dev/on-event: "[pull_request]"
    pipelinesascode.tekton.dev/on-target-branch: "[main]"
    pipelinesascode.tekton.dev/on-path-change: "[src/**, tests/**]"
spec:
  pipelineSpec:
    tasks:
    - name: fetch-repository
      taskRef:
        name: git-clone
        resolver: hub
      workspaces:
      - name: output
        workspace: source
      params:
      - name: url
        value: "{{ repo_url }}"
      - name: revision
        value: "{{ revision }}"
    - name: run-tests
      runAfter: [fetch-repository]
      taskRef:
        name: golang-test
        resolver: hub
      workspaces:
      - name: source
        workspace: source
  workspaces:
  - name: source
    volumeClaimTemplate:
      spec:
        accessModes:
        - ReadWriteOnce
        resources:
          requests:
            storage: 1Gi

Authentication and authorization

GitHub App authentication

When using GitHub Apps, Pipelines as Code:
  • Authenticates as a GitHub App installation
  • Generates short-lived tokens for each repository
  • Scopes tokens to specific repositories (configurable)
  • Injects tokens into PipelineRuns as secrets
  • Automatically refreshes expired tokens

Webhook authentication

For webhook-based integrations (GitLab, Bitbucket, etc.), you configure:
  • A personal access token or API token
  • A webhook secret for validating incoming requests
  • Stored in Kubernetes secrets referenced by the Repository CR

Authorization policies

Pipelines as Code enforces authorization to prevent untrusted users from running pipelines:
approvers:
  - maintainer1
  - maintainer2
reviewers:
  - developer1
  - developer2

Advanced features

Provenance control

Control where pipeline definitions are fetched from:
  • source (default): Fetch from the event source (the branch/SHA that triggered the event)
  • default_branch: Always fetch from the repository’s default branch (e.g., main)
spec:
  settings:
    pipelinerun_provenance: "default_branch"
Using default_branch provenance ensures only users who can merge to the default branch can modify pipelines, adding an extra security layer.

Concurrency control

Limit how many PipelineRuns can execute simultaneously:
spec:
  concurrency_limit: 2
When the limit is reached, additional PipelineRuns are queued and executed in alphabetical order by name.

Automatic cleanup

Configure automatic cleanup of completed PipelineRuns:
metadata:
  annotations:
    pipelinesascode.tekton.dev/max-keep-runs: "5"
Older PipelineRuns are automatically deleted, keeping your namespace clean.

Auto-cancellation

When a new commit is pushed to a PR, Pipelines as Code can automatically cancel in-progress PipelineRuns for the same PR and event type, saving compute resources.

What’s next?

Quickstart

Get your first pipeline running in 5 minutes

Repository CRD

Configure repositories using the Repository custom resource

Writing pipelines

Create PipelineRun definitions with annotations and template variables

GitOps commands

Control pipeline execution with ChatOps-style comments

Writing pipelines

Deep dive into writing effective pipeline definitions

GitOps commands

Control pipelines with /test, /retest, and /cancel

Build docs developers (and LLMs) love