Overview
The Pipelines-as-Code resolver automatically bundles your PipelineRuns with all their dependencies (Tasks and Pipelines) into a single, self-contained PipelineRun before execution. This ensures reproducibility and eliminates external dependencies at runtime.
The PAC resolver is different from Tekton Resolvers . Both are compatible and can be used together.
How Resolution Works
PAC scans all .yaml and .yml files in .tekton/ and subdirectories.
Identifies Tekton resources: PipelineRun, Pipeline, Task.
Inline referenced Tasks from annotations or .tekton/
Fetch remote Tasks from URLs or hubs
Bundle Pipeline if using pipelineRef
Converts metadata.name to metadata.generateName for uniqueness.
Creates the complete, self-contained PipelineRun.
What Gets Resolved
PAC resolves:
Tasks referenced by taskRef.name in .tekton/
Tasks from remote URLs (annotations)
Tasks from Artifact Hub / Tekton Hub
Pipelines from remote URLs (annotations)
Pipelines from Artifact Hub
Tasks in subdirectories of .tekton/
ClusterTasks
Tekton Bundles
Tekton Resolvers (resolver: hub, resolver: git, etc.)
Custom Tasks (non-tekton.dev apiVersion)
Embedded taskSpec
If PAC cannot resolve a referenced task, the run fails before submission to the cluster. Check namespace events and PAC controller logs.
Remote Task Annotations
Fetch tasks from remote sources using annotations on PipelineRuns or Pipelines.
Artifact Hub (Default)
Fetch tasks from Artifact Hub :
annotations :
pipelinesascode.tekton.dev/task : "git-clone"
Multiple tasks :
annotations :
pipelinesascode.tekton.dev/task : "[git-clone, golang-test, tkn]"
Multiple lines :
annotations :
pipelinesascode.tekton.dev/task : "git-clone"
pipelinesascode.tekton.dev/task-1 : "golang-test"
pipelinesascode.tekton.dev/task-2 : "tkn"
Specific version :
annotations :
pipelinesascode.tekton.dev/task : "git-clone:0.9.0"
Custom Hub Catalogs
Cluster admins can configure custom hubs. Reference them with the catalog name:
annotations :
pipelinesascode.tekton.dev/task : "[customcatalog://curl]"
No fallback between hubs. If a task isn’t found in the specified hub, the run fails.
Remote HTTP URLs
Fetch tasks from any HTTP/HTTPS URL:
annotations :
pipelinesascode.tekton.dev/task : "[https://example.com/tasks/my-task.yaml]"
Private Repository URLs
Use GitHub blob URLs: annotations :
pipelinesascode.tekton.dev/task : "[https://github.com/org/repo/blob/main/tasks/task.yaml]"
PAC uses the GitHub App token or webhook token to fetch the file. Branch with slash : HTML-encode / as %2F:annotations :
pipelinesascode.tekton.dev/task : "[https://github.com/org/repo/blob/feature%2Fbranch/tasks/task.yaml]"
Token Scoping :
GitHub App : Scoped to the owner/organization by default
Webhook : Token permissions from the personal access token
Configure secret-github-app-token-scoped and secret-github-app-scope-extra-repos in ConfigMap to extend scope
See Repository CRD - GitHub Token Scoping for details. Use GitLab blob or raw URLs: annotations :
# Blob URL
pipelinesascode.tekton.dev/task : "[https://gitlab.com/org/repo/-/blob/main/tasks/task.yaml]"
# Raw URL
pipelinesascode.tekton.dev/task : "[https://gitlab.com/org/repo/-/raw/main/tasks/task.yaml]"
PAC uses the GitLab token from the Repository CR.
Tasks from Current Repository
Reference tasks within your repository by path:
annotations :
pipelinesascode.tekton.dev/task : "[.tekton/tasks/custom-task.yaml]"
pipelinesascode.tekton.dev/task-1 : "[shared/tasks/build.yaml]"
Paths are relative to the repository root and fetched from the event’s SHA.
Remote Pipeline Annotations
Share pipelines across repositories using remote pipeline annotations.
Only one pipelinesascode.tekton.dev/pipeline annotation is allowed per PipelineRun. Suffixes like pipeline-1 are not supported.
Remote URL
annotations :
pipelinesascode.tekton.dev/pipeline : "https://git.example.com/raw/pipeline.yaml"
Artifact Hub
annotations :
pipelinesascode.tekton.dev/pipeline : "buildpacks"
# Or with version
pipelinesascode.tekton.dev/pipeline : "buildpacks:0.1"
Custom Hub
annotations :
pipelinesascode.tekton.dev/pipeline : "[customcatalog://buildpacks:0.1]"
Pipeline from Current Repository
annotations :
pipelinesascode.tekton.dev/pipeline : "pipelines/my-pipeline.yaml"
Relative Task Resolution
When a remote pipeline references tasks, PAC resolves them relative to the pipeline’s location.
Example Setup :
Repository A (event source):
apiVersion : tekton.dev/v1
kind : PipelineRun
metadata :
name : hello-world
annotations :
pipelinesascode.tekton.dev/on-target-branch : "[main]"
pipelinesascode.tekton.dev/on-event : "[push]"
pipelinesascode.tekton.dev/pipeline : "https://github.com/user/repo-b/blob/main/pipeline.yaml"
spec :
pipelineRef :
name : hello-world
Repository B :
apiVersion : tekton.dev/v1beta1
kind : Pipeline
metadata :
name : hello-world
annotations :
pipelinesascode.tekton.dev/task : "./task.yaml" # Relative to pipeline.yaml
spec :
tasks :
- name : say-hello
taskRef :
name : hello
apiVersion : tekton.dev/v1beta1
kind : Task
metadata :
name : hello
spec :
steps :
- name : echo
image : alpine
script : |
#!/bin/sh
echo "Hello, World!"
Resolution :
PAC fetches pipeline.yaml from Repository B
Sees ./task.yaml annotation
Resolves relative to pipeline.yaml location: https://github.com/user/repo-b/blob/main/task.yaml
Fetches and inlines the task
Relative paths like ../task.yaml are supported. If the pipeline is at /foo/bar/pipeline.yaml and the task path is ../task.yaml, PAC assembles /foo/task.yaml.
Task Override from Remote Pipeline
Override tasks from a remote pipeline by defining a task with the same name in the PipelineRun annotations.
Remote Pipeline at https://example.com/pipeline.yaml:
apiVersion : tekton.dev/v1beta1
kind : Pipeline
metadata :
name : shared-pipeline
annotations :
pipelinesascode.tekton.dev/task : "git-clone" # From Artifact Hub
spec :
tasks :
- name : clone
taskRef :
name : git-clone
User PipelineRun :
.tekton/pull-request.yaml
apiVersion : tekton.dev/v1beta1
kind : PipelineRun
metadata :
name : my-run
annotations :
pipelinesascode.tekton.dev/pipeline : "https://example.com/pipeline.yaml"
pipelinesascode.tekton.dev/task : "./my-custom-git-clone.yaml" # Overrides git-clone
spec :
pipelineRef :
name : shared-pipeline
./my-custom-git-clone.yaml :
apiVersion : tekton.dev/v1beta1
kind : Task
metadata :
name : git-clone # Same name as the remote task
spec :
# Custom implementation
Result : PAC uses ./my-custom-git-clone.yaml instead of the Artifact Hub git-clone task.
Only tasks referenced by taskRef.name can be overridden. Tasks embedded with taskSpec cannot be overridden.
Task and Pipeline Precedence
When multiple sources define the same task/pipeline name, PAC uses this precedence:
Task Precedence
PipelineRun annotations : pipelinesascode.tekton.dev/task
Remote Pipeline annotations : pipelinesascode.tekton.dev/task on the pipeline
.tekton/ directory : Tasks automatically fetched from .tekton/ and subdirectories
Pipeline Precedence
PipelineRun annotations : pipelinesascode.tekton.dev/pipeline
.tekton/ directory : Pipelines automatically fetched from .tekton/ and subdirectories
Testing Resolution Locally
Test your PipelineRun resolution before pushing to Git:
tkn pac resolve -f .tekton/pull-request.yaml
This simulates the resolution process and shows:
Resolved tasks
Fetched remote resources
Final bundled PipelineRun YAML
Example output :
$ tkn pac resolve -f .tekton/pull-request.yaml
Resolving PipelineRun: pull-request
✓ Fetched task 'git-clone' from Artifact Hub
✓ Fetched task 'golang-test' from https://example.com/tasks/test.yaml
✓ Resolved PipelineRun with 2 tasks
---
apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
generateName: pull-request-
spec:
pipelineSpec:
tasks:
- name: fetch-repository
taskSpec:
# Inlined git-clone task
Complete Examples
Multi-Source Task Resolution
apiVersion : tekton.dev/v1beta1
kind : PipelineRun
metadata :
name : multi-source
annotations :
pipelinesascode.tekton.dev/on-event : "[pull_request]"
pipelinesascode.tekton.dev/on-target-branch : "[main]"
# Task from Artifact Hub
pipelinesascode.tekton.dev/task : "git-clone:0.9.0"
# Task from custom catalog
pipelinesascode.tekton.dev/task-1 : "[customcatalog://security-scan]"
# Task from remote URL
pipelinesascode.tekton.dev/task-2 : "[https://example.com/tasks/notify.yaml]"
# Task from current repo
pipelinesascode.tekton.dev/task-3 : "[.tekton/tasks/custom-build.yaml]"
spec :
pipelineSpec :
tasks :
- name : fetch
taskRef :
name : git-clone
- name : scan
taskRef :
name : security-scan
- name : build
taskRef :
name : custom-build
- name : notify
taskRef :
name : notify
workspaces :
- name : source
emptyDir : {}
Remote Pipeline with Local Override
apiVersion : tekton.dev/v1beta1
kind : PipelineRun
metadata :
name : custom-run
annotations :
pipelinesascode.tekton.dev/on-event : "[push]"
pipelinesascode.tekton.dev/on-target-branch : "[main]"
# Use shared pipeline from another repo
pipelinesascode.tekton.dev/pipeline : "https://github.com/org/shared-pipelines/blob/main/ci.yaml"
# Override the 'test' task with local version
pipelinesascode.tekton.dev/task : "[.tekton/tasks/test.yaml]"
spec :
pipelineRef :
name : ci # Name from the remote pipeline
params :
- name : repo-url
value : "{{ repo_url }}"
- name : revision
value : "{{ revision }}"
Monorepo with Shared Tasks
monorepo/
├── .tekton/
│ ├── tasks/ # Shared tasks
│ │ ├── build.yaml
│ │ ├── test.yaml
│ │ └── deploy.yaml
│ ├── service-a.yaml # PipelineRun for service A
│ └── service-b.yaml # PipelineRun for service B
├── service-a/
└── service-b/
.tekton/service-a.yaml :
apiVersion : tekton.dev/v1beta1
kind : PipelineRun
metadata :
name : service-a-ci
annotations :
pipelinesascode.tekton.dev/on-event : "[pull_request]"
pipelinesascode.tekton.dev/on-path-change : "[service-a/**]"
# Automatically resolves from .tekton/tasks/
spec :
pipelineSpec :
tasks :
- name : build
taskRef :
name : build # Resolved from .tekton/tasks/build.yaml
- name : test
taskRef :
name : test # Resolved from .tekton/tasks/test.yaml
PAC automatically finds and inlines tasks from .tekton/tasks/.
Troubleshooting
Task not found
failed to resolve task 'my-task': task not found in annotations, remote pipeline, or .tekton directory
Solutions :
Verify task name matches exactly (case-sensitive)
Check task exists in .tekton/ or subdirectories
Ensure annotation syntax is correct: "[task-name]"
Test locally: tkn pac resolve -f .tekton/pr.yaml
Remote URL fetch failure
failed to fetch remote task from https://example.com/task.yaml: 404 Not Found
Solutions :
Verify URL is accessible
Check authentication (GitHub/GitLab tokens)
For private repos, ensure token has read permissions
For GitHub, use blob URLs: /blob/main/ not /tree/main/
Hub task version not found
task 'git-clone:9.9.9' not found in Artifact Hub
Solutions :
Check available versions: Artifact Hub - git-clone
Use latest version or omit version: "git-clone"
Verify custom hub catalog is configured correctly
Circular dependency
circular dependency detected: pipeline A references pipeline B, which references pipeline A
Solution : Restructure pipelines to avoid circular references.
Next Steps
Creating Pipelines Author PipelineRuns with dynamic variables
Event Matching Match pipelines to specific events and file changes
Running Pipelines Execute and monitor PipelineRuns
Repository CRD Configure GitHub token scoping for multi-repo access