Tekton sits somewhere on the spectrum between a building block and a product of a CI system. Or maybe not a CI system, a generalized graph of arbitrary code execution.
There was a build task I wanted to move over from Google Cloud Build: a nightly build of Go (plus some extra tools). This was setup as a Dockerfile in a git repo subdirectory, a Cloud Build config file, and a Google Cloud Scheduler to trigger the build.
Dockerfile:
1FROM golang:alpine AS build
2ENV CGO_ENABLED=0 \
3 GOFLAGS=-trimpath
4RUN apk add --no-cache bash curl gcc git musl-dev && \
5 go install golang.org/dl/gotip@latest && \
6 gotip download && \
7 rm -rf /root/sdk/gotip/pkg/linux_* && \
8 curl -Lo /usr/local/bin/skaffold https://storage.googleapis.com/skaffold/builds/latest/skaffold-linux-amd64 && \
9 chmod +x /usr/local/bin/skaffold
10
11FROM alpine
12RUN apk add --no-cache git
13ENV CGO_ENABLED=0 \
14 GOFLAGS=-trimpath
15ENV PATH=/root/sdk/gotip/bin:/root/go/bin:$PATH
16COPY --from=build /usr/local/bin/skaffold /usr/local/bin/skaffold
17COPY --from=build /root/sdk/gotip /root/sdk/gotip
18WORKDIR /workspace
19ENTRYPOINT [ "go" ]
cloudbuild.yaml:
1steps:
2 - id: build-push-gotip
3 name: "gcr.io/kaniko-project/executor"
4 args:
5 - "--context=gotip"
6 - "--destination=${_REGISTRY}/gotip:latest"
7 - "--image-name-with-digest-file=.image.gotip.txt"
8 - "--reproducible"
9 - "--single-snapshot"
10 - "--snapshot-mode=redo"
11 - "--ignore-var-run"
12
13 - id: sign-gotip
14 name: "gcr.io/projectsigstore/cosign"
15 entrypoint: sh
16 env:
17 - "TUF_ROOT=/tmp" # cosign tries to create $HOME/.sigstore
18 - "COSIGN_EXPERIMENTAL=1"
19 - "GOOGLE_SERVICE_ACCOUNT_NAME=cosign-signer@com-seankhliao.iam.gserviceaccount.com"
20 args:
21 - "-c"
22 - "cosign sign --force $(head -n 1 .image.gotip.txt)"
23
24substitutions:
25 _REGISTRY: us-central1-docker.pkg.dev/com-seankhliao/build
26
27options:
28 env:
29 - GOGC=400
30
31timeout: "1800s" # 30m gotip build is slow
Moving over to Tekton, I went with inlining the entire build config into a TriggerTemplate. No more cloning a repo first just for a file. I think I could have done this with Cloud Build too, but I haven't been consistent in managing my config as code consistently...
1apiVersion: triggers.tekton.dev/v1beta1
2kind: TriggerTemplate
3metadata:
4 name: gotip-trigger
5spec:
6 resourcetemplates:
7 - apiVersion: tekton.dev/v1beta1
8 kind: TaskRun
9 metadata:
10 generateName: build-gotip-tr-
11 spec:
12 taskSpec:
13 params:
14 - name: image-ref
15 type: string
16 default: us-central1-docker.pkg.dev/com-seankhliao/build/gotip:latest
17 results:
18 - name: image-digest
19 steps:
20 - name: write-dockerfile
21 image: busybox
22 script: |
23 cat << EOF > /workspace/src/Dockerfile
24 FROM golang:alpine AS build
25 ENV CGO_ENABLED=0 \
26 GOFLAGS=-trimpath
27 RUN apk add --no-cache bash curl gcc git musl-dev && \
28 go install golang.org/dl/gotip@latest && \
29 gotip download && \
30 rm -rf /root/sdk/gotip/pkg/linux_* && \
31 curl -Lo /usr/local/bin/skaffold https://storage.googleapis.com/skaffold/builds/latest/skaffold-linux-amd64 && \
32 chmod +x /usr/local/bin/skaffold
33
34 FROM alpine
35 RUN apk add --no-cache git
36 ENV CGO_ENABLED=0 \
37 GOFLAGS=-trimpath
38 ENV PATH=/root/sdk/gotip/bin:/root/go/bin:$PATH
39 COPY --from=build /usr/local/bin/skaffold /usr/local/bin/skaffold
40 COPY --from=build /root/sdk/gotip /root/sdk/gotip
41 WORKDIR /workspace
42 ENTRYPOINT [ "go" ]
43 EOF
44 volumeMounts:
45 - name: src
46 mountPath: /workspace/src
47 - name: build-gotip
48 image: "gcr.io/kaniko-project/executor"
49 args:
50 - "--context=/workspace/src"
51 - "--destination=$(params.image-ref)"
52 - "--image-name-with-digest-file=$(results.image-digest.path)"
53 - "--reproducible"
54 - "--single-snapshot"
55 - "--snapshot-mode=redo"
56 - "--ignore-var-run"
57 - "--ignore-path=/product_uuid" # kind specific? https://github.com/GoogleContainerTools/kaniko/issues/2164
58 volumeMounts:
59 - name: src
60 mountPath: /workspace/src
61 - name: docker-auth
62 mountPath: /kaniko/.docker/config.json
63 subPath: .dockerconfigjson
64 volumes:
65 - name: src
66 emptyDir: {}
67 - name: docker-auth
68 secret:
69 secretName: gcp-ar-docker
Next up, an EventListener to turn HTTP requests into TaskRuns:
1apiVersion: triggers.tekton.dev/v1beta1
2kind: EventListener
3metadata:
4 name: gotip-event
5spec:
6 serviceAccountName: tekton-triggers
7 triggers:
8 - name: default
9 template:
10 ref: gotip-trigger
And a CronJob to make the HTTP requests:
1apiVersion: batch/v1
2kind: CronJob
3metadata:
4 name: trigger-gotip
5spec:
6 schedule: "*/30 * * * *"
7 jobTemplate:
8 spec:
9 template:
10 spec:
11 containers:
12 - name: trigger
13 image: curlimages/curl:latest
14 args:
15 - --data
16 - "{}"
17 - http://el-gotip-event.default.svc.cluster.local:8080
18 restartPolicy: OnFailure