Tekton Pipelines for Kubernetes-Native CI/CD Testing
Tekton is a Kubernetes-native CI/CD framework. If your team runs workloads on Kubernetes and wants CI/CD that uses the same primitives — pods, volumes, service accounts — Tekton is worth a serious look.
This guide covers setting up Tekton Pipelines for automated testing workflows, from installing the basics to running parallel test suites.
What Makes Tekton Different
Most CI/CD systems run on their own infrastructure and call into Kubernetes when needed. Tekton runs inside Kubernetes. Every pipeline step is a container. Every pipeline run is a set of pods. There's no separate server to maintain — Tekton installs as a set of CRDs (Custom Resource Definitions) in your cluster.
This means:
- Pipeline state lives in etcd alongside your workloads
- Steps use the same RBAC and network policies as your apps
- Scaling is handled by Kubernetes itself
- You can use kubectl to inspect pipeline runs
The tradeoff: Tekton has more setup overhead than hosted CI/CD. It's not a good fit for teams that want zero-infrastructure CI. But if you're already managing Kubernetes, the operational cost is low.
Core Concepts
Task — a reusable unit of work. A Task contains one or more Steps (containers that run sequentially). Tasks can declare Parameters and Workspaces (shared volumes).
Pipeline — an ordered sequence of Tasks. Tasks in a Pipeline can run sequentially or in parallel, share data via Workspaces, and pass results between each other.
TaskRun / PipelineRun — an execution instance of a Task or Pipeline. These are Kubernetes resources you can create manually, via triggers, or via the Tekton CLI (tkn).
Trigger — a component that listens for external events (webhooks from GitHub, GitLab, etc.) and creates PipelineRuns in response.
Installing Tekton
Install the Tekton Pipelines controller into your cluster:
kubectl apply --filename https://storage.googleapis.com/tekton-releases/pipeline/latest/release.yamlInstall the Tekton Dashboard (optional but useful):
kubectl apply --filename https://storage.googleapis.com/tekton-releases/dashboard/latest/release.yamlInstall the tkn CLI for local interaction:
# macOS
brew install tektoncd-cli
# Linux
curl -LO https://github.com/tektoncd/cli/releases/latest/download/tkn_Linux_x86_64.tar.gz
tar xvzf tkn_Linux_x86_64.tar.gz -C /usr/local/bin tknVerify the install:
kubectl get pods --namespace tekton-pipelines
tkn versionWriting a Test Task
Here's a Task that runs a Node.js test suite:
apiVersion: tekton.dev/v1
kind: Task
metadata:
name: run-tests
spec:
params:
- name: repo-url
type: string
- name: revision
type: string
default: main
workspaces:
- name: source
steps:
- name: clone
image: alpine/git
script: |
git clone $(params.repo-url) $(workspaces.source.path)
cd $(workspaces.source.path)
git checkout $(params.revision)
- name: install
image: node:20-alpine
workingDir: $(workspaces.source.path)
script: |
npm ci
- name: test
image: node:20-alpine
workingDir: $(workspaces.source.path)
script: |
npm testApply it:
kubectl apply -f run-tests-task.yamlCreating a Test Pipeline
A Pipeline that clones, lints, and tests in sequence — with the option to run lint and unit tests in parallel:
apiVersion: tekton.dev/v1
kind: Pipeline
metadata:
name: test-pipeline
spec:
params:
- name: repo-url
- name: revision
default: main
workspaces:
- name: shared-workspace
tasks:
- name: fetch-source
taskRef:
name: git-clone
kind: ClusterTask
workspaces:
- name: output
workspace: shared-workspace
params:
- name: url
value: $(params.repo-url)
- name: revision
value: $(params.revision)
- name: lint
runAfter: [fetch-source]
taskRef:
name: run-lint
workspaces:
- name: source
workspace: shared-workspace
- name: unit-tests
runAfter: [fetch-source]
taskRef:
name: run-tests
workspaces:
- name: source
workspace: shared-workspace
- name: integration-tests
runAfter: [unit-tests]
taskRef:
name: run-integration-tests
workspaces:
- name: source
workspace: shared-workspacelint and unit-tests both depend on fetch-source but not on each other, so Tekton runs them in parallel.
Running the Pipeline
Create a PipelineRun:
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
name: test-pipeline-run-1
spec:
pipelineRef:
name: test-pipeline
params:
- name: repo-url
value: https://github.com/your-org/your-repo
- name: revision
value: main
workspaces:
- name: shared-workspace
volumeClaimTemplate:
spec:
accessModes: [ReadWriteOnce]
resources:
requests:
storage: 1GiApply it and watch:
kubectl apply -f pipeline-run.yaml
tkn pipelinerun logs test-pipeline-run-1 --followOr via the CLI directly:
tkn pipeline start test-pipeline \
--param repo-url=https://github.com/your-org/your-repo \
--workspace name=shared-workspace,claimName=pipeline-pvc \
--showlogSetting Up GitHub Triggers
Install Tekton Triggers:
kubectl apply --filename https://storage.googleapis.com/tekton-releases/triggers/latest/release.yaml
kubectl apply --filename https://storage.googleapis.com/tekton-releases/triggers/latest/interceptors.yamlCreate an EventListener that responds to GitHub push events:
apiVersion: triggers.tekton.dev/v1beta1
kind: EventListener
metadata:
name: github-listener
spec:
serviceAccountName: tekton-triggers-sa
triggers:
- name: github-push
interceptors:
- ref:
name: github
params:
- name: secretRef
value:
secretName: github-webhook-secret
secretKey: secretToken
- name: eventTypes
value: [push]
bindings:
- ref: github-push-binding
template:
ref: pipeline-trigger-templateExpose the EventListener with a Service and configure your GitHub repo's webhook to point to it. On push, Tekton creates a PipelineRun automatically.
Parallel Test Sharding
For large test suites, split tests across multiple TaskRuns using a matrix:
- name: test-shards
taskRef:
name: run-test-shard
matrix:
params:
- name: shard-index
value: ["0", "1", "2", "3"]
params:
- name: total-shards
value: "4"Each shard runs in its own pod. Total test time drops by roughly 1/n for n shards (minus startup overhead).
Integrating HelpMeTest
Tekton handles your build and unit test pipeline well. For end-to-end and browser tests, HelpMeTest complements it with zero-configuration monitoring.
Add a Tekton Task that triggers HelpMeTest after your build:
- name: run-e2e-tests
runAfter: [deploy-staging]
taskRef:
name: helpmetest-trigger
params:
- name: api-key
value: $(params.helpmetest-api-key)
- name: test-suite
value: smoke-testsOr skip the pipeline integration entirely — HelpMeTest can run your end-to-end tests on a schedule (every 5 minutes, usage-based pricing at $0.003/run) independent of your Tekton pipeline. When Tekton handles the build and unit tests, HelpMeTest handles continuous production monitoring.
Observability
Tekton exports metrics to Prometheus. Key metrics for testing pipelines:
tekton_pipelines_controller_pipelinerun_duration_seconds— pipeline execution timetekton_pipelines_controller_taskrun_duration_seconds— individual task timetekton_pipelines_controller_pipelinerun_count— total runs
Add a Grafana dashboard to visualize test pass rates and flakiness over time. The Tekton Dashboard (kubectl port-forward -n tekton-pipelines svc/tekton-dashboard 9097:9097) gives a visual view of recent runs without Grafana setup.
Common Issues
PVC not releasing between runs: Use volumeClaimTemplate in PipelineRuns instead of a persistent PVC — Tekton creates and deletes the volume automatically per run.
Steps sharing data: Use Workspaces. Tekton Steps in the same Task share a filesystem, but Tasks in a Pipeline need an explicit Workspace to share files.
Secrets in steps: Mount Kubernetes Secrets as environment variables or volumes. Never hardcode credentials in Task specs.
Slow startup: Container image pulls dominate startup time for small tasks. Use slim images (node:20-alpine vs node:20) and configure an image pull policy of IfNotPresent for internal registries.
Summary
Tekton is the right CI/CD choice when you want Kubernetes-native pipelines with no external CI server. The learning curve is real — you're writing YAML for every concept — but the operational payoff is strong if you're already running Kubernetes.
For teams without Kubernetes, hosted CI (GitHub Actions, CircleCI) is less setup. For teams on Kubernetes who want full control over pipeline execution, Tekton fits well.
Pair it with HelpMeTest for continuous end-to-end test monitoring — Tekton handles your build pipeline, HelpMeTest handles your always-on test coverage.