$ kubectl apply -f https://github.com/tektoncd/pipeline/releases/download/v0.18.1/release.yaml
$ kubectl apply -f https://github.com/tektoncd/triggers/releases/download/v0.10.1/release.yaml
$ kubectl apply -f https://github.com/tektoncd/dashboard/releases/download/v0.11.1/tekton-dashboard-release.yaml
https://github.com/tektoncd/cli#installing-tkn
hello-world-task.yaml
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: hello-world-task
spec:
steps:
- name: say-hello
image: alpine
script: |
set +x
echo "Hello, World!"
$ kubectl create -f hello-world-task.yaml
hello-world-task-run.yaml
apiVersion: tekton.dev/v1beta1
kind: TaskRun
metadata:
generateName: hello-world-
spec:
taskRef:
name: hello-world-task
$ kubectl create -f hello-world-task-run.yaml
Getting the results of the TaskRun
$ kubectl get taskrun/<insert taskrun>
NAME SUCCEEDED REASON STARTTIME COMPLETIONTIME
hello-world-d6l84 True Succeeded 30s 13s
$ kubectl get taskrun/<insert taskrun> -o yaml | yq r - 'status.podName'
$ kubectl logs pod/<task run pod>
Or alternatively...
$ tkn taskrun logs --last
$ tkn task start hello-world-task
Expose the Tekton Dashboard service
$ kubectl port-forward svc/tekton-dashboard 9097 -n tekton-pipelines
Or alternatively, use kube proxy...
$ kubectl proxy
Update the hello-world-task.yaml
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: hello-world-task
spec:
params:
- name: name
type: string
default: World
description: Name of the user to greet
steps:
- name: say-hello
image: alpine
script: |
set +x
echo "Hello, $(params.name)!"
$ kubectl replace -f hello-world-task.yaml
Update the hello-world-task-run.yaml
apiVersion: tekton.dev/v1beta1
kind: TaskRun
metadata:
generateName: hello-world-
spec:
taskRef:
name: hello-world-task
params:
- name: name
value: universe
$ kubectl create -f hello-world-task-run.yaml
$ tkn taskrun logs --last
$ tkn task start hello-world-task
Update the hello-world-task.yaml
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: hello-world-task
spec:
params:
- name: name
type: string
default: world
steps:
- name: say-hello
image: alpine
script: |
set +x
echo "Hello, $(params.name)"
- name: say-goodbye
image: alpine
script: |
set +x
echo "Goodbye, $(params.name)"
$ kubectl replace -f hello-world-task.yaml
$ tkn task start hello-world-task
execute-ls-task.yaml
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: execute-ls
spec:
params:
- name: path
type: string
default: "."
steps:
- name: ls-dir
image: alpine
command:
- ls
args:
- $(params.path)
$ kubectl create -f execute-ls-task.yaml
$ tkn task start execute-ls
top-language-task.yaml
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: top-language-task
spec:
params:
- name: repo
type: string
description: The repository full-name to query e.g. tektoncd/pipeline
results:
- name: top-language
description: Top language for repo
steps:
- name: top-language
image: bigkevmcd/jq-curl:latest
script: |
set +x
echo -n `curl -s https://api.github.com/repos/$(params.repo)/languages | jq 'to_entries|sort_by(.value)[-1].key'` > $(results.top-language.path)
$ tkn task start top-language-task -p repo=bigkevmcd/go-demo
$ tkn taskrun describe --last
$ kubectl get taskrun/<task run> -o yaml | yq r - 'status.taskResults.(name==top-language).value'
demo-pipeline.yaml
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: demo-pipeline
spec:
params:
- name: message
description: incoming notification message
type: string
tasks:
- name: task-echo-message
taskRef:
name: hello-world-task
kind: Task
params:
- name: name
value: $(params.message)
$ tkn pipeline start demo-pipeline
Install the git-clone task.
https://github.com/tektoncd/catalog/tree/master/task/git-clone/0.2
$ kubectl apply -f https://raw.githubusercontent.com/tektoncd/catalog/master/task/git-clone/0.2/git-clone.yaml
build-source-pipeline.yaml
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: build-source-pipeline
spec:
params:
- name: GIT_REPO
type: string
description: the clonable repo source e.g. https://github.com/tektoncd/pipeline.git
- name: GIT_REF
type: string
description: git revision to checkout (branch, tag, sha, ref…)
tasks:
- name: clone-source
params:
- name: url
value: $(params.GIT_REPO)
- name: revision
value: $(params.GIT_REF)
taskRef:
kind: Task
name: git-clone
workspaces:
- name: output
workspace: shared-data
workspaces:
- description: This workspace will receive the cloned git repo.
name: shared-data
$ kubectl create -f build-source-pipeline.yaml
$ tkn pipeline start build-source-pipeline -p GIT_REF=refs/heads/master -p GIT_REPO=https://github.com/bigkevmcd/go-demo
$ tkn pipelinerun logs --last
build-source-pipeline.yaml
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: build-source-pipeline
spec:
params:
- name: GIT_REPO
type: string
description: the clonable repo source e.g. https://github.com/tektoncd/pipeline.git
- name: GIT_REF
type: string
description: git revision to checkout (branch, tag, sha, ref…)
tasks:
- name: clone-source
params:
- name: url
value: $(params.GIT_REPO)
- name: revision
value: $(params.GIT_REF)
taskRef:
kind: Task
name: git-clone
workspaces:
- name: output
workspace: shared-data
- name: echo-results
runAfter:
- clone-source
taskSpec:
params:
- name: commit
type: string
- name: url
type: string
steps:
- name: echo-git-result
image: alpine
script: |
echo $(params.commit)
echo $(params.url)
params:
- name: commit
value: $(tasks.clone-source.results.commit)
- name: url
value: $(tasks.clone-source.results.url)
workspaces:
- description: This workspace will receive the cloned git repo.
name: shared-data
$ kubectl replace -f build-source-pipeline.yaml
And execute it with a PipelineRun.
build-source-pipelinerun.yaml
apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
generateName: build-source-pipeline-
spec:
params:
- name: GIT_REPO
value: https://github.com/bigkevmcd/go-demo.git
- name: GIT_REF
value: master
pipelineRef:
name: build-source-pipeline
workspaces:
- name: shared-data
volumeClaimTemplate:
metadata:
creationTimestamp: null
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
$ kubectl create -f build-source-pipeline.yaml
Install the Buildah task, it builds an image from a source repository with a Dockerfile.
https://github.com/tektoncd/catalog/tree/master/task/buildah/0.2
$ kubectl apply -f https://raw.githubusercontent.com/tektoncd/catalog/master/task/buildah/0.2/buildah.yaml
We need a secret ...
$ kubectl create secret generic regcred \
--from-file=.dockerconfigjson=$HOME/.docker/config.json \
--type=kubernetes.io/dockerconfigjson
And grant access to that secret from the default serviceaccount
$ kubectl patch serviceaccount default \
-p '{"secrets": [{"name": "regcred"}]}'
build-source-pipeline.yaml
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: build-source-pipeline
spec:
params:
- name: GIT_REPO
type: string
description: the clonable repo source e.g. https://github.com/tektoncd/pipeline.git
- name: GIT_REF
type: string
description: git revision to checkout (branch, tag, sha, ref…)
- name: IMAGE
type: string
description: image repository to push the completed build to
tasks:
- name: clone-source
params:
- name: url
value: $(params.GIT_REPO)
- name: revision
value: $(params.GIT_REF)
taskRef:
kind: Task
name: git-clone
workspaces:
- name: output
workspace: shared-data
- name: build-image
runAfter:
- clone-source
taskRef:
kind: Task
name: buildah
params:
- name: IMAGE
value: $(params.IMAGE)
workspaces:
- name: source
workspace: shared-data
workspaces:
- description: This workspace will receive the cloned git repo.
name: shared-data
build-source-pipelinerun.yaml
apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
generateName: build-source-pipeline-
spec:
params:
- name: GIT_REPO
value: https://github.com/bigkevmcd/go-demo.git
- name: GIT_REF
value: master
- name: IMAGE
value: quay.io/kmcdermo/demo:latest
pipelineRef:
name: build-source-pipeline
workspaces:
- name: shared-data
volumeClaimTemplate:
metadata:
creationTimestamp: null
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
$ kubectl create -f build-source-pipelinerun.yaml
go-test-task.yaml
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: go-test-task
spec:
params:
- name: lint-version
description: the version of golangci-lint to run
default: v1.33.0
workspaces:
- name: source
description: the git source to execute on
steps:
- name: go-mod-setup
image: golang:latest
workingDir: $(workspaces.source.path)
command: ["go", "mod", "download"]
- name: go-vet
image: golang:latest
workingDir: $(workspaces.source.path)
command: ["go", "vet", "./..."]
- name: ci-lint
image: golangci/golangci-lint:$(params.lint-version)
workingDir: $(workspaces.source.path)
command: ["golangci-lint", "run"]
- name: go-test
image: golang:latest
workingDir: $(workspaces.source.path)
command: ["go", "test", "./..."]
Insert this task into build-source-pipeline.yaml
- name: check-source
runAfter:
- clone-source
taskRef:
kind: Task
name: go-test-task
workspaces:
- name: source
workspace: shared-data
Update the set of tasks, so that the tests run (and fail) after check-source.
$ kubectl create -f build-source-pipelinerun.yaml
demo-event-listener.yaml
Need to grant permissions for Tekton to execute in the default namespace.
$ kubectl apply -f https://gist.github.com/bigkevmcd/cf2413ff0fd47191401181891cab9104/raw/89979a254625958431ff1551a94b851e3a724c77/permissions.yaml
apiVersion: triggers.tekton.dev/v1alpha1
kind: EventListener
metadata:
name: demo-event-listener
spec:
serviceAccountName: demo-sa
triggers:
- name: demo-trigger
template:
name: demo-template
bindings:
- ref: demo-binding
demo-binding.yaml
apiVersion: triggers.tekton.dev/v1alpha1
kind: TriggerBinding
metadata:
name: demo-binding
spec:
params:
- name: message
value: $(body.message)
demo-template.yaml
apiVersion: triggers.tekton.dev/v1alpha1
kind: TriggerTemplate
metadata:
name: demo-template
spec:
params:
- description: message
name: message
resourcetemplates:
- apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
annotations:
name: demo-run-$(uid)
spec:
params:
- name: message
value: $(tt.params.message)
pipelineRef:
name: demo-pipeline
$ kubectl apply -f demo-template.yaml
$ kubectl apply -f demo-binding.yaml
$ kubectl apply -f demo-event-listener.yaml
Trigger a PipelineRun:
$ kubectl port-forward svc/el-demo-event-listener 8080
$ curl -H "Content-Type: application/json" -d '{"message": "from JSON"}' http://localhost:8080/
$ kubectl create secret generic github-secret --from-literal=secretToken=abcdefghihj
The documentation for the GitHub Push event:
github-event-listener.yaml
apiVersion: triggers.tekton.dev/v1alpha1
kind: EventListener
metadata:
name: github-event-listener
spec:
serviceAccountName: demo-sa
triggers:
- name: demo-trigger
interceptors:
- github:
secretRef:
secretName: github-secret
secretKey: secretToken
eventTypes:
- push
template:
name: build-code-template
bindings:
- ref: github-push-binding
github-push-binding.yaml
apiVersion: triggers.tekton.dev/v1alpha1
kind: TriggerBinding
metadata:
name: github-push-binding
spec:
params:
- name: gitref
value: $(body.head_commit.id)
- name: gitrepositoryurl
value: $(body.repository.clone_url)
build-code-template.yaml
apiVersion: triggers.tekton.dev/v1alpha1
kind: TriggerTemplate
metadata:
name: build-code-template
spec:
params:
- name: gitref
description: The specific ref to build from the repo.
- name: gitrepositoryurl
description: The repo to build from.
resourcetemplates:
- apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
name: build-source-pipeline-$(uid)
spec:
params:
- name: GIT_REPO
value: $(tt.params.gitrepositoryurl)
- name: GIT_REF
value: $(tt.params.gitref)
- name: IMAGE
value: bigkevmcd/tekton-demo:$(tt.params.gitref)
pipelineRef:
name: build-source-pipeline
workspaces:
- name: shared-data
volumeClaimTemplate:
metadata:
creationTimestamp: null
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
github-event-listener.yaml
apiVersion: triggers.tekton.dev/v1alpha1
kind: EventListener
metadata:
name: github-event-listener
spec:
serviceAccountName: demo-sa
triggers:
- name: demo-trigger
interceptors:
- github:
secretRef:
secretName: github-secret
secretKey: secretToken
eventTypes:
- push
- cel:
filter: body.repository.full_name == 'bigkevmcd/no-demo'
overlays:
- key: intercepted.short_sha
expression: body.head_commit.id.truncate(7)
template:
name: build-code-template
bindings:
- ref: github-push-binding
github-push-binding.yaml
apiVersion: triggers.tekton.dev/v1alpha1
kind: TriggerBinding
metadata:
name: github-push-binding
spec:
params:
- name: gitref
value: $(body.head_commit.id)
- name: gitrepositoryurl
value: $(body.repository.clone_url)
- name: shortsha
value: $(extensions.intercepted.short_sha)
build-code-template.yaml
apiVersion: triggers.tekton.dev/v1alpha1
kind: TriggerTemplate
metadata:
name: build-code-template
spec:
params:
- name: gitref
description: The specific ref to build from the repo.
- name: gitrepositoryurl
description: The repo to build from.
- name: shortsha
description: shortened version of the SHA useful for tagging.
resourcetemplates:
- apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
name: build-source-pipeline-$(uid)
spec:
params:
- name: GIT_REPO
value: $(tt.params.gitrepositoryurl)
- name: GIT_REF
value: $(tt.params.gitref)
- name: IMAGE
value: bigkevmcd/demo:$(tt.params.shortsha)
pipelineRef:
name: build-source-pipeline
workspaces:
- name: shared-data
volumeClaimTemplate:
metadata:
creationTimestamp: null
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
finally:
# Cleanup workspace
- name: cleanup
taskSpec:
name: cleanup-workspace
image: alpine
command: ["echo", "cleaning up"]
$ kubectl get events
https://github.com/tektoncd/pipeline/blob/master/docs/events.md