Core Concepts

This page covers the resources, runtime components and trigger model that PAC introduces on top of Tekton. For a quick overview and audience map, see Introduction.

Architecture

PAC runs three controllers in the cluster and reacts to events delivered by the Git provider:

  • PAC Webhook is the HTTP listener exposed to the Git provider. It verifies each incoming request against the shared webhook secret and forwards verified payloads to the controller. Anything that fails verification is dropped before it ever touches Tekton.
  • PAC Controller owns the logic of "what should run on this event". It looks up the matching Repository resource, fetches the .tekton/ manifests from the ref the event refers to, filters them through the trigger annotations, expands variables, and creates PipelineRuns.
  • PAC Watcher follows the PipelineRuns that PAC created and reports their state back to the Git provider — as a GitHub Check Run, a commit status, or a comment, depending on the provider.

All three components live in the PAC namespace (default: tekton-pipelines) and are deployed by the Tekton Operator from the OpenShiftPipelinesAsCode CR.

The Repository resource

Repository is the only resource you maintain per Git repository. It binds one Git URL to one Kubernetes namespace: events from that URL produce PipelineRuns in this namespace, and only in this namespace. Multiple Repository resources can point at the same Git URL only in different namespaces — typical for a "team namespace per environment" layout.

A Repository does not carry any pipeline definition. The pipeline definitions live in the Git repository itself, under .tekton/. Deleting the Repository only stops PAC from creating new PipelineRuns; the runs already created are left in place.

Key spec fields

FieldPurpose
spec.urlThe Git repository URL. PAC matches incoming events to this value.
spec.git_provider.typeProvider type, for example github or gitlab. Can be omitted for GitHub.com — PAC detects it from the payload.
spec.git_provider.urlProvider API base URL. Required for self-hosted GitLab; optional elsewhere.
spec.git_provider.secretReference to the Secret holding the Git access token under provider.token.
spec.git_provider.webhook_secretReference to the Secret holding the webhook signing secret under webhook.secret.
spec.concurrency_limitOptional cap on the number of PipelineRuns from this repository that may execute concurrently.
spec.paramsRepository-scoped parameters that any PipelineRun from this repo can read with {{ name }} placeholders.
spec.settingsAuthorization policies and provider-specific options, for example which users may trigger via comment.

Example (GitLab over Webhook):

apiVersion: pipelinesascode.tekton.dev/v1alpha1
kind: Repository
metadata:
  name: my-repo
  namespace: project-pipelines
spec:
  url: https://gitlab.com/group/project
  git_provider:
    type: gitlab
    secret:
      name: my-repo-auth
    webhook_secret:
      name: my-repo-auth

In the GitHub App mode the entire git_provider block is omitted; PAC authenticates with the cluster-wide App credentials, so per-repository tokens and webhook secrets are not needed.

Two integration modes

The Git provider has two ways to deliver events to PAC, and the Repository spec changes shape with each.

  • GitHub App mode — a GitHub App is installed once on the GitHub organization or user. The App owns the webhook and the credentials at the organization level. Every repository covered by the installation can be onboarded with a minimal Repository (spec.url only). Status is reported through the GitHub Checks API. Available only on GitHub.
  • Webhook mode — a Personal Access Token and a webhook are configured per repository. The Repository references a Kubernetes Secret carrying the token and the webhook secret. Status is reported as a commit status. This documentation covers GitHub Webhook mode and GitLab Webhook mode.

The two modes are mutually exclusive on a given Repository. The end-to-end procedures for each provider are in Guides.

.tekton/ directory convention

PAC reads PipelineRun manifests from a .tekton/ directory at the root of the Git repository. The convention:

  • Any .yaml or .yml file under .tekton/ is scanned. There can be more than one PipelineRun per file and more than one file per repository.
  • Manifests are read from the ref the event was raised on — a pull request reads the source branch, a push reads the pushed branch, a tag push reads the tag's ref.
  • Each PipelineRun is evaluated independently. A single event can produce zero, one, or several PipelineRuns depending on how many manifests match.
  • The standard PipelineRun shape applies; PAC simply adds annotations and variables on top. Tasks can be inline (pipelineSpec), referenced from an existing Pipeline in the cluster (pipelineRef), or resolved at submission time from Tekton Hub or a remote URL.

Event lifecycle

A few properties worth keeping in mind:

  • The verification step at the webhook is fail-closed: an event with an invalid signature does not reach the controller, the Repository controller, or the cluster.
  • The controller does the filtering and the variable expansion before any Kubernetes object is created, so a non-matching event produces no PipelineRun and leaves no trace beyond a log line.
  • Status reporting is asynchronous and happens whenever the PipelineRun state changes, including completion and individual step failures (where the provider supports per-step reporting).

Trigger model

PipelineRun manifests advertise the events they care about through annotations on metadata.annotations. The controller filters manifests against the event using these annotations.

Event types

EventMeaningNotes
pushA commit was pushed to a branchIncludes tag pushes when the ref is a tag
pull_requestA pull request / merge request was opened, updated or synchronizedManifests are read from the PR source branch
pull_request_labeledA label was applied to a pull requestUseful to gate runs on a reviewer label
pull_request_closedA pull request was closed (merged or not)
commentA comment was posted on a PR / commitCombined with on-comment for custom commands
incomingAn external incoming webhook fired the runSee Incoming Webhooks

Annotation grammar

AnnotationPurpose
pipelinesascode.tekton.dev/on-eventEvent kinds the run applies to, e.g. [push, pull_request].
pipelinesascode.tekton.dev/on-target-branchTarget branch filter; supports plain names, full refs and glob patterns, e.g. [refs/heads/main], [refs/tags/*].
pipelinesascode.tekton.dev/on-cel-expressionA CEL expression. When set, it replaces on-event and on-target-branch.
pipelinesascode.tekton.dev/on-commentA regular expression matched against PR / MR comments — the basis for /retest and similar commands.
pipelinesascode.tekton.dev/on-path-changeOnly run when changed files match a glob, e.g. [backend/***].
pipelinesascode.tekton.dev/on-path-change-ignoreSkip when changed files match a glob — useful to ignore documentation-only changes.

A pair of simple matchers (on-event + on-target-branch) is enough for most cases. For composite conditions ("only when the PR head matches feature/* AND the changed files include api/**") use a CEL expression instead:

annotations:
  pipelinesascode.tekton.dev/on-cel-expression: |
    event == "pull_request" &&
    source_branch.startsWith("feature/") &&
    files.modified.exists(f, f.startsWith("api/"))

CEL programs receive event, event_title, target_branch, source_branch, body, headers, and a files object with all, added, deleted, modified and renamed lists.

The full annotation grammar, more CEL examples and the conflict-resolution rules are in Define PipelineRuns in Git.

Variables and resolution

At the moment the PipelineRun is created, PAC expands a small set of placeholders against the event payload. The values stick to the PipelineRun after creation; they are not re-evaluated.

VariableValue
{{ repo_url }}The repository URL on the Git provider
{{ revision }}The commit SHA of the event
{{ source_branch }}Branch where the event originated (PR head)
{{ target_branch }}Branch the event targets (PR base)
{{ repo_owner }}, {{ repo_name }}Repository owner and name
{{ sender }}Username or account ID of the event sender
{{ pull_request_number }}PR / MR number, for pull request events
{{ git_auth_secret }}Name of the auto-created Secret carrying clone credentials for the run

PAC can also inline Task and Pipeline manifests at submission time — local files referenced through paths, Tekton Hub references via short names, or remote URLs. The resolver runs before the PipelineRun is created, so the resulting object is self-contained. See PAC Resolver for the syntax and the supported sources.

Status reporting

PAC reports PipelineRun state back to the Git provider through three channels, picked automatically based on the provider and the integration mode:

  • GitHub Checks API — used in GitHub App mode. Each PipelineRun shows up as a Check Run with per-step output and an "in progress / success / failure" badge attached to the commit.
  • Commit statuses — used in GitHub Webhook mode and GitLab. A short status line is posted against the commit and (where relevant) the PR / MR.
  • Comment — for failures, a comment containing the PipelineRun name and a link to the cluster is added to the PR / MR. The exact format depends on the provider.

The cluster-side URL embedded in those status reports can be customized through the custom-console-url-* settings in OpenShiftPipelinesAsCode; see Manage PAC Component.

Concurrency and cancellation

By default every matching event creates its PipelineRun immediately. Two settings shape that behaviour:

  • Repository.spec.concurrency_limit caps the number of PipelineRuns from this repository that run in parallel. Excess runs are queued and start when older ones finish.
  • The pipelinesascode.tekton.dev/cancel-in-progress annotation on a PipelineRun instructs PAC to cancel any older run that matches the same event group (for example, the same PR) before starting the new one — useful when a new push to a PR should invalidate the previous CI build.

These are the basic knobs; the full set of advanced fields is documented in Advanced Repository Configuration.

Security and access

  • Webhook payloads are verified against webhook.secret; the value lives only in the cluster Secret and never appears in events or logs.
  • The Git access token (Webhook mode) or the GitHub App private key (App mode) is also stored as a Kubernetes Secret; tokens never appear in PipelineRun specs.
  • Repository is a namespaced resource; standard Kubernetes RBAC governs who can create or modify it. Granting "read repositories" without "create" lets a user inspect what is integrated without changing it.
  • Status reporting back to the Git provider always uses the cluster-side identity (the App in App mode, the configured token in Webhook mode). Individual event senders are not delegated permissions.

Next steps