Simplified Tekton
My simplified DSL for Tekton is coming along nicely, I’ve spent a fair bit of time in the evenings and at the weekends exploring how to integrate a script-based DSL with Tekton Tasks and I’ve made some progress.
This is a minimal .tekton_ci.yaml
file that will use a buildah
Task in
Tekton to build and push an image to Quay.io (or any Image Repository).
This service is still alpha quality, and not for use in production.
The pipeline definition
build-image:
rules:
- if: vars.CI_COMMIT_BRANCH != 'master'
when: never
tekton:
taskRef: buildah
params:
- name: IMAGE
expr: "'quay.io/bigkevmcd/github-tool:master-' + vars.CI_COMMIT_SHORT_SHA"
This is executed with the default ServiceAccount parameter passed to the
container, this ServiceAccount needs to have a DockerConfigJSON type secret
available to it, to authenticate the buildah
image push.
$ kubectl create secret generic regcred \
--from-file=.dockerconfigjson=<path/to/.docker/config.json> \
--type=kubernetes.io/dockerconfigjson
You can provide the serviceAccountName for a PipelineRun explicitly in the configuration:
tekton:
serviceAccountName: my-test-account
build-image:
tekton:
taskRef: buildah
params:
- name: IMAGE
expr: "'quay.io/bigkevmcd/github-tool:master-' + vars.CI_COMMIT_SHORT_SHA"
The rules
indicate that this should only build on pushes to the master
branch (the syntax for rules is probably going to diverge1 further from GitLab’s
CI rules).
The rules are implemented at PipelineRun generation time, so the build-image
task would not be included in the PipelineRun
when the code is building the
Pipeline
if the expression didn’t match.
The tekton
key in the build-image
task can replace a script
element, and
this is referencing a Task
named buildah
.
Finally, the IMAGE
is dynamically calculated based on the commit.
"'quay.io/bigkevmcd/github-tool:master-' + vars.CI_COMMIT_SHORT_SHA"
This is a CEL expression, the CEL context
has some keys which can be used and this is using a trimmed version of the
commit SHA, the image tag will look like master-4b84d50
.
While this is fairly simple, in practice, running tests before build is more normal.
Running the tests before building an image
image: golang:latest
before_script:
- wget -O- -nv https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s v1.24.0
stages:
- test
- update-image
test-go:
stage: test
script:
- go mod download
- go fmt ./...
- go vet ./...
- ./bin/golangci-lint run
- go test -race ./...
build-image:
stage: update-image
rules:
- if: vars.CI_COMMIT_BRANCH != 'master'
when: never
tekton:
taskRef: buildah
params:
- name: IMAGE
expr: "'quay.io/bigkevmcd/github-tool:master-' + vars.CI_COMMIT_SHORT_SHA"
In this case, I’ve sequenced the test
stage before the update-image
, which
means that the build-image
task will not execute unless the test-go
task is
successful, for pushes to master, no image will be built if the test stage
fails.
The buildah task
This is using the standard Tekton catalog buildah
task straight from the catalog with:
$ kubectl apply -f https://raw.githubusercontent.com/tektoncd/catalog/v1beta1/buildah/buildah.yaml
Splitting the Go tests out to a task
If you want to standardise your Go tests, it’s easy to extract the script out
into a Task
.
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: go-test-task
spec:
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:v1.24.0
workingDir: $(workspaces.source.path)
command: ["golangci-lint", "run"]
- name: go-test
image: golang:latest
workingDir: $(workspaces.source.path)
command: ["go", "test", "./..."]
This means that the .tekton_ci.yaml
file can be simplified to just.
stages:
- test
- update-image
test-go:
stage: test
tekton:
taskRef: go-test-task
build-image:
stage: update-image
rules:
- if: vars.CI_COMMIT_BRANCH != 'master'
when: never
tekton:
taskRef: buildah
params:
- name: IMAGE
expr: "'quay.io/bigkevmcd/github-tool:master-' + vars.CI_COMMIT_SHORT_SHA"
-
The Tekton-CI implementation uses
CEL
syntax, the GitLab-CI implementation uses Ruby, refer to the CEL context documentation for more information. ↩