apiVersion: tekton.dev/v1beta1
kind: Task (1)
metadata: (2)
  name: git-clone
  labels:
    app.kubernetes.io/version: "0.4"
  annotation:
    tekton.dev/pipelines.minVersion: "0.21.0"
    tekton.dev/categories: Git
    tekton.dev/tags: git
    tekton.dev/displayName: "git clone"
spec:
  # […]
  workspaces: (3)
    - name: output
      description: The git repo will be cloned onto the volume backing this Workspace.
    # […]
  params: (4)
    - name: url
      description: Repository URL to clone from.
      type: string
    - name: revision
      description: Revision to checkout. (branch, tag, sha, ref, etc...)
      type: string
      default: ""
    # […]
  results: (5)
    - name: commit
      description: The precise commit SHA that was fetched by this Task.
    - name: url
      description: The precise URL that was fetched by this Task.
  steps: (6)
    - name: clone
      image: gcr.io/tekton-releases/github.com/tektoncd/pipeline/cmd/git-init:v0.27.3
      env: (7)
      # […]
      - name: PARAM_URL
        value: $(params.url)
      - name: PARAM_REVISION
        value: $(params.revision)
      # […]
      script: | (8)
        #!/usr/bin/env sh
        # […]
        /ko-app/git-init \
          -url="${params.url}" \
          -revision="${PARAM_REVISION}" \
          -refspec="${PARAM_REFSPEC}" \
          -path="${CHECKOUT_DIR}" \
          -sslVerify="${PARAM_SSL_VERIFY}" \
          -submodules="${PARAM_SUBMODULES}" \
          -depth="${PARAM_DEPTH}" \
          -sparseCheckoutDirectories="${PARAM_SPARSE_CHECKOUT_DIRECTORIES}"
        cd "${CHECKOUT_DIR}"
        RESULT_SHA="$(git rev-parse HEAD)"
        # […] (9)
        printf "%s" "${RESULT_SHA}" > "$(results.commit.path)"
        printf "%s" "${PARAM_URL}" > "$(results.url.path)"

---
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: buildah
  # […]
spec:
  # […]
  params:
  - name: IMAGE
    description: Reference of the image buildah will produce.
  - name: BUILDER_IMAGE
    description: The location of the buildah builder image.
    default: quay.io/buildah/stable:v1.18.0
  # […]
  - name: DOCKERFILE
    description: Path to the Dockerfile to build.
    default: ./Dockerfile
  - name: CONTEXT
    description: Path to the directory to use as context.
    default: .
  # […]
  workspaces: (1)
  - name: source
  - name: sslcertdir
    optional: true
  results:
  - name: IMAGE_DIGEST
    description: Digest of the image just built.
  steps: (2)
  - name: build (3)
    image: $(params.BUILDER_IMAGE)
    workingDir: $(workspaces.source.path)
    script: |
      [[ "$(workspaces.sslcertdir.bound)" == "true" ]] && CERT_DIR_FLAG="--cert-dir $(workspaces.sslcertdir.path)"
      buildah ${CERT_DIR_FLAG} --storage-driver=$(params.STORAGE_DRIVER) bud \
        $(params.BUILD_EXTRA_ARGS) --format=$(params.FORMAT) \
        --tls-verify=$(params.TLSVERIFY) --no-cache \
        -f $(params.DOCKERFILE) -t $(params.IMAGE) $(params.CONTEXT)
    # […]
  - name: push
    image: $(params.BUILDER_IMAGE)
    workingDir: $(workspaces.source.path)
    script: |
      [[ "$(workspaces.sslcertdir.bound)" == "true" ]] && CERT_DIR_FLAG="--cert-dir $(workspaces.sslcertdir.path)"
      buildah ${CERT_DIR_FLAG} --storage-driver=$(params.STORAGE_DRIVER) push \
        $(params.PUSH_EXTRA_ARGS) --tls-verify=$(params.TLSVERIFY) \
        --digestfile $(workspaces.source.path)/image-digest $(params.IMAGE) \
        docker://$(params.IMAGE)
  # […]
  - name: digest-to-results
    image: $(params.BUILDER_IMAGE)
    script: cat $(workspaces.source.path)/image-digest | tee /tekton/results/IMAGE_DIGEST
  # […]

kubectl apply -f https://raw.githubusercontent.com/tektoncd/catalog/main/task/kubernetes-actions/0.2/kubernetes-actions.yaml
# […]
spec:
  # […]
  workspaces:
    - name: manifest-dir (1)
      optional: true
    - name: kubeconfig-dir (2)
      optional: true
  results:
    - name: output-result
      description: some result can be emitted if someone wants to.
  params:
    - name: script (4)
      description: The Kubernetes CLI script to run
      type: string
      default: "kubectl $@"
    - name: args (5)
      description: The Kubernetes CLI arguments to run
      type: array
      default:
        - "help"
    # […]
  steps:
    # […]

apiVersion: tekton.dev/v1beta1
kind: Pipeline (1)
metadata:
  name: build-and-deploy
spec:
  workspaces:
  - name: shared-workspace (2)
  params: (3)
  - name: git-url
    type: string
  - name: git-revision
    type: string
    default: "main"
  - name: image
    type: string
  tasks: (4)
  - name: fetch-repository
    taskRef:
      name: git-clone
    workspaces:
    - name: output
      workspace: shared-workspace
    params:
    - name: url
      value: $(params.git-url)
  - name: build-image
    taskRef:
      name: buildah
    params:
    - name: IMAGE
      value: $(params.image)
    workspaces:
    - name: source
      workspace: shared-workspace
    runAfter: (5)
    - fetch-repository
  - name: deploy-app
    taskRef:
      name: kubernetes-actions
    workspaces:
    - name: manifest-dir
      workspace: shared-workspace
    params:
    - name: script
      value: |
        kubectl apply -f manifests/
    runAfter:
    - build-image

apiVersion: tekton.dev/v1beta1
kind: PipelineRun (1)
metadata:
  generateName: build-deploy-pipelinerun- (2)
spec:
  pipelineRef: (3)
    name: build-and-deploy
  params: (4)
  - name: git-url
    value: https://github.com/vdemeester/go-helloworld-app.git
  - name: image
    value: quay.io/vdemeest/go-helloworld
  serviceAccountName: sa-hub-vdemeester-foo (5)
  workspaces:
  - name: shared-workspace (6)
    volumeClaimTemplate:
      spec:
        accessModes:
          - ReadWriteOnce
        resources:
          requests:
            storage: 500Mi

$ tkn pipelinerun logs -f build-deploy-pipelinerun-jj59z
# […]
[fetch-repository : clone] + /ko-app/git-init '-url=https://github.com/vdemeester/go-helloworld-app.git' '-revision=' '-refspec=' '-path=/workspace/output/' '-sslVerify=true' '-submodules=true' '-depth=1' '-sparseCheckoutDirectories='
[fetch-repository : clone] {"level":"info","ts":1631694832.8834538,"caller":"git/git.go:169","msg":"Successfully cloned https://github.com/vdemeester/go-helloworld-app.git @ dd9473987aa399172626520ed6e837e0de7b4569 (grafted, HEAD) in path /workspace/output/"}
[fetch-repository : clone] {"level":"info","ts":1631694832.900327,"caller":"git/git.go:207","msg":"Successfully initialized and updated submodules in path /workspace/output/"}
# […]
[build-image : build] + buildah --storage-driver=overlay bud --format=oci --tls-verify=true --no-cache -f ./Dockerfile -t quay.io/vdemeest/go-helloworld .
[build-image : build] STEP 1: FROM docker.io/library/golang:1.16 AS builder
[build-image : build] Getting image source signatures
[build-image : build] Copying blob sha256:911ea9f2bd51e53a455297e0631e18a72a86d7e2c8e1807176e80f991bde5d64
# […]
[build-image : build] STEP 7: ENTRYPOINT ["/helloworld"]
[build-image : build] STEP 8: COMMIT quay.io/vdemeest/go-helloworld
[build-image : build] --> aade6b0f8ed
[build-image : build] aade6b0f8ed34111cab39f981440b9fcd6cdc658bddb15c8407780e67c4d5d09
# […]
[build-image : push] + buildah --storage-driver=overlay push --tls-verify=true --digestfile /workspace/source/image-digest quay.io/vdemeest/go-helloworld docker://quay.io/vdemeest/go-helloworld
# […]
[build-image : push] Storing signatures
[build-image : digest-to-results] + cat /workspace/source/image-digest
[build-image : digest-to-results] + tee /tekton/results/IMAGE_DIGEST
[build-image : digest-to-results] sha256:1c43f2938af866b9caa1c56cbedaa49847be71392a4b1b498cc8f902d69ace77
[deploy-app : kubectl] service/helloworld created
[deploy-app : kubectl] deployment.apps/helloworld created