Stitch any CI into Tangled
1# Tekton
2
3The Tekton provider runs only in Kubernetes. Tack receives Tangled
4pipeline triggers, creates a Tekton `PipelineRun` for an existing
5in-cluster `Pipeline`, watches that `PipelineRun`, and publishes
6`sh.tangled.pipeline.status` records back to Tangled.
7
8Tekton Triggers are intentionally not used. Tack already performs the
9event-to-run translation, and Tekton's native execution object is the
10`PipelineRun`.
11
12> [!IMPORTANT]
13>
14> **This is a community-contributed provider.** I (mitchellh) haven't
15> verified its functionality beyond what others have said worked. I've
16> only reviewed the code for obvious issues and to ensure it doesn't do
17> anything to jeopardize the rest of Tack.
18
19## Required cluster setup
20
21- Tekton Pipelines is installed in the cluster.
22- Tack is deployed inside the same cluster.
23- The target Tekton `Pipeline` objects already exist in the namespace
24 tack is configured to use.
25- Tack's Kubernetes service account has RBAC to:
26 - create, get, list, and watch `tekton.dev` `pipelineruns`
27 - get, list, and watch `tekton.dev` `taskruns`
28 - get and list pods
29 - get pod logs via `pods/log`
30
31Example RBAC:
32
33```yaml
34apiVersion: rbac.authorization.k8s.io/v1
35kind: Role
36metadata:
37 name: tack-tekton
38 namespace: ci
39rules:
40 - apiGroups: ["tekton.dev"]
41 resources: ["pipelineruns"]
42 verbs: ["create", "get", "list", "watch"]
43 - apiGroups: ["tekton.dev"]
44 resources: ["taskruns"]
45 verbs: ["get", "list", "watch"]
46 - apiGroups: [""]
47 resources: ["pods"]
48 verbs: ["get", "list"]
49 - apiGroups: [""]
50 resources: ["pods/log"]
51 verbs: ["get"]
52```
53
54## Configure Tack
55
56| Env var | Description |
57| ----------------------- | -------------------------------------------------------- |
58| `TACK_TEKTON_ENABLED` | Set to `1` to enable the Tekton provider |
59| `TACK_TEKTON_NAMESPACE` | Namespace for created `PipelineRun`s (default `default`) |
60
61The provider uses Kubernetes in-cluster service account credentials.
62It will not run from a local kubeconfig.
63
64## Naming
65
66There are three separate names:
67
68- Tack workflow name: the Tangled workflow filename/name, e.g. `ci.yml`.
69 This remains the Tangled-facing workflow identity in status records.
70- Tekton `Pipeline` name: the existing in-cluster pipeline definition,
71 e.g. `repo-ci`. This is written to `spec.pipelineRef.name`.
72- Tekton `PipelineRun` name: generated by tack per trigger/workflow,
73 e.g. `tack-ci-yml-<short-hash>`. This is the concrete execution
74 object tack watches and stores.
75
76## Workflow YAML
77
78Only the provider and target pipeline are required:
79
80```yaml
81tack:
82 tekton:
83 pipeline: repo-ci
84```
85
86Optional fields:
87
88```yaml
89tack:
90 tekton:
91 pipeline: repo-ci
92 service_account: pipeline-runner
93 params:
94 image: example/app
95 workspaces:
96 - name: repo-data
97 access_modes: ["ReadWriteOnce"]
98 storage: 1Gi
99 - name: go-mod-cache
100 pvc: go-mod-cache
101```
102
103`params` are forwarded as string Tekton params. Tack also stores the
104knot, pipeline rkey, workflow name, actor DID, commit, and branch as
105`PipelineRun` annotations, so operators can inspect the Kubernetes
106object and connect it back to the Tangled trigger.
107
108Workspaces correlate to
109[Tekton workspaces](https://tekton.dev/docs/pipelines/workspaces/) and
110are useful for creating a temporary PVC with git clones, intermediate
111build products, or other build artifacts.
112
113## Example Pipeline
114
115```yaml
116apiVersion: tekton.dev/v1
117kind: Pipeline
118metadata:
119 name: repo-ci
120 namespace: ci
121spec:
122 params:
123 - name: image
124 type: string
125 tasks:
126 - name: test
127 taskSpec:
128 params:
129 - name: image
130 type: string
131 steps:
132 - name: test
133 image: golang:1.25
134 script: |
135 set -eu
136 echo "building $(params.image)"
137 go test ./...
138 workspaces: []
139 params:
140 - name: image
141 value: $(params.image)
142```
143
144Detailed CI behavior belongs in the in-cluster `Pipeline`. The Tangled
145workflow YAML should stay small: select `tekton`, pick the target
146pipeline, and pass only the small set of params that pipeline expects.