Add Tekton tasks, pipeline and test Dockerfile

- Add git-clone task for repository cloning
- Add kaniko-build task for container image builds
- Add container-build pipeline orchestrating clone + build
- Add harbor-credentials ExternalSecret for innoventions namespace
- Add test-app.Dockerfile for pipeline validation

Day 3 deliverables for Tekton Phase 2
This commit is contained in:
Hermes Agent service account
2026-06-06 15:53:57 -05:00
parent d5ce6ff96a
commit 76241e75a8
5 changed files with 387 additions and 0 deletions

View File

@@ -0,0 +1,38 @@
# ExternalSecret for Tekton robot account credentials
# Syncs from 1Password item: harbor-robot-accounts
# Creates a docker-registry type secret for Tekton pipeline authentication
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: harbor-tekton-robot
namespace: innoventions
spec:
refreshInterval: 1h
secretStoreRef:
name: onepassword-connect
kind: ClusterSecretStore
target:
name: harbor-credentials
creationPolicy: Owner
template:
type: kubernetes.io/dockerconfigjson
data:
.dockerconfigjson: |
{
"auths": {
"the-seas.local.mk-labs.cloud": {
"username": "{{ .tekton_username }}",
"password": "{{ .tekton_password }}",
"auth": "{{ printf "%s:%s" .tekton_username .tekton_password | b64enc }}"
}
}
}
data:
- secretKey: tekton_username
remoteRef:
key: harbor-robot-accounts
property: tekton-builder-username
- secretKey: tekton_password
remoteRef:
key: harbor-robot-accounts
property: tekton-builder-password

View File

@@ -0,0 +1,99 @@
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: container-build
namespace: innoventions
labels:
app.kubernetes.io/version: "0.1"
annotations:
tekton.dev/pipelines.minVersion: "0.29.0"
tekton.dev/categories: Container Build
tekton.dev/tags: git, kaniko, build
tekton.dev/displayName: "Container Build Pipeline"
spec:
description: >-
This pipeline clones a git repository and builds a container image from it using Kaniko.
The pipeline performs the following steps:
1. Clone the git repository to a shared workspace
2. Build and push the container image to Harbor registry
params:
- name: git-url
type: string
description: The git repository URL to clone
- name: git-revision
type: string
description: The git revision (branch, tag, sha) to checkout
default: "main"
- name: image-name
type: string
description: The complete image name including registry (e.g., the-seas.local.mk-labs.cloud/library/app)
- name: image-tag
type: string
description: The image tag to apply
default: "latest"
- name: dockerfile
type: string
description: Path to the Dockerfile relative to the repository root
default: "./Dockerfile"
- name: context
type: string
description: Path to the build context relative to the repository root
default: "./"
workspaces:
- name: shared-workspace
description: |
This workspace will hold the cloned git repository and is shared between tasks.
It should be backed by a PersistentVolumeClaim or VolumeClaimTemplate.
- name: docker-credentials
description: |
This workspace contains the docker config.json for authenticating to Harbor.
It should be backed by a Secret containing .dockerconfigjson
tasks:
- name: fetch-repository
taskRef:
name: git-clone
workspaces:
- name: output
workspace: shared-workspace
params:
- name: url
value: $(params.git-url)
- name: revision
value: $(params.git-revision)
- name: deleteExisting
value: "true"
- name: build-and-push
taskRef:
name: kaniko-build
runAfter:
- fetch-repository
workspaces:
- name: source
workspace: shared-workspace
- name: dockerconfig
workspace: docker-credentials
params:
- name: IMAGE
value: "$(params.image-name):$(params.image-tag)"
- name: DOCKERFILE
value: $(params.dockerfile)
- name: CONTEXT
value: $(params.context)
- name: EXTRA_ARGS
value:
- --skip-tls-verify
- --verbosity=info
- --skip-unused-stages=true
results:
- name: IMAGE_DIGEST
description: The digest of the built image
value: $(tasks.build-and-push.results.IMAGE_DIGEST)
- name: IMAGE_URL
description: The URL of the built image
value: $(tasks.build-and-push.results.IMAGE_URL)

View File

@@ -0,0 +1,175 @@
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: git-clone
namespace: innoventions
labels:
app.kubernetes.io/version: "0.1"
annotations:
tekton.dev/pipelines.minVersion: "0.29.0"
tekton.dev/categories: Git
tekton.dev/tags: git
tekton.dev/displayName: "git clone"
tekton.dev/platforms: "linux/amd64,linux/s390x,linux/ppc64le,linux/arm64"
spec:
description: >-
Clone a git repository to the output workspace.
This Task can be used to initialize a workspace by cloning a git repo.
It supports public repos and HTTPS authentication via basic auth credentials.
workspaces:
- name: output
description: The git repo will be cloned onto the volume backing this Workspace.
params:
- name: url
description: Repository URL to clone from.
type: string
- name: revision
description: Revision to checkout. (branch, tag, sha, ref, etc...)
type: string
default: "main"
- name: refspec
description: Refspec to fetch before checking out revision.
default: ""
- name: submodules
description: Initialize and fetch git submodules.
type: string
default: "false"
- name: depth
description: Perform a shallow clone, fetching only the most recent N commits.
type: string
default: "1"
- name: sslVerify
description: Set the `http.sslVerify` global git config. Setting this to `false` is not advised unless you are sure that you trust your git remote.
type: string
default: "true"
- name: subdirectory
description: Subdirectory inside the `output` workspace to clone the repo into.
type: string
default: ""
- name: deleteExisting
description: Clean out the contents of the destination directory if it already exists before cloning.
type: string
default: "true"
- name: httpProxy
description: HTTP proxy server for non-SSL requests.
type: string
default: ""
- name: httpsProxy
description: HTTPS proxy server for SSL requests.
type: string
default: ""
- name: noProxy
description: Opt out of proxying HTTP/HTTPS requests.
type: string
default: ""
- name: verbose
description: Log the commands that are executed during `git-clone`'s operation.
type: string
default: "false"
- name: gitInitImage
description: The image providing the git-init binary that this Task runs.
type: string
default: "gcr.io/tekton-releases/github.com/tektoncd/pipeline/cmd/git-init:v0.40.2"
- name: userHome
description: |
Absolute path to the user's home directory. Set this explicitly if you are running the image as a non-root user or have overridden
the gitInitImage param with an image containing custom user configuration.
type: string
default: "/tekton/home"
results:
- 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:
- name: clone
image: "$(params.gitInitImage)"
env:
- name: HOME
value: "$(params.userHome)"
- name: PARAM_URL
value: $(params.url)
- name: PARAM_REVISION
value: $(params.revision)
- name: PARAM_REFSPEC
value: $(params.refspec)
- name: PARAM_SUBMODULES
value: $(params.submodules)
- name: PARAM_DEPTH
value: $(params.depth)
- name: PARAM_SSL_VERIFY
value: $(params.sslVerify)
- name: PARAM_SUBDIRECTORY
value: $(params.subdirectory)
- name: PARAM_DELETE_EXISTING
value: $(params.deleteExisting)
- name: PARAM_HTTP_PROXY
value: $(params.httpProxy)
- name: PARAM_HTTPS_PROXY
value: $(params.httpsProxy)
- name: PARAM_NO_PROXY
value: $(params.noProxy)
- name: PARAM_VERBOSE
value: $(params.verbose)
- name: PARAM_USER_HOME
value: $(params.userHome)
- name: WORKSPACE_OUTPUT_PATH
value: $(workspaces.output.path)
script: |
#!/usr/bin/env sh
set -eu
if [ "${PARAM_VERBOSE}" = "true" ] ; then
set -x
fi
if [ "${PARAM_DELETE_EXISTING}" = "true" ] ; then
cleandir() {
# Delete any existing contents of the repo directory if it exists.
#
# We don't just "rm -rf ${CHECKOUT_DIR}" because ${CHECKOUT_DIR} might be "/"
# or the root of a mounted volume.
if [ -d "${CHECKOUT_DIR}" ] ; then
# Delete non-hidden files and directories
rm -rf "${CHECKOUT_DIR:?}"/*
# Delete files and directories starting with . but excluding ..
rm -rf "${CHECKOUT_DIR}"/.[!.]*
# Delete files and directories starting with .. plus any other character
rm -rf "${CHECKOUT_DIR}"/..?*
fi
}
if [ "${PARAM_SUBDIRECTORY}" != "" ] ; then
CHECKOUT_DIR="${WORKSPACE_OUTPUT_PATH}/${PARAM_SUBDIRECTORY}"
cleandir
else
CHECKOUT_DIR="${WORKSPACE_OUTPUT_PATH}"
cleandir
fi
fi
test -z "${PARAM_HTTP_PROXY}" || export HTTP_PROXY="${PARAM_HTTP_PROXY}"
test -z "${PARAM_HTTPS_PROXY}" || export HTTPS_PROXY="${PARAM_HTTPS_PROXY}"
test -z "${PARAM_NO_PROXY}" || export NO_PROXY="${PARAM_NO_PROXY}"
/ko-app/git-init \
-url="${PARAM_URL}" \
-revision="${PARAM_REVISION}" \
-refspec="${PARAM_REFSPEC}" \
-path="${CHECKOUT_DIR}" \
-sslVerify="${PARAM_SSL_VERIFY}" \
-submodules="${PARAM_SUBMODULES}" \
-depth="${PARAM_DEPTH}"
cd "${CHECKOUT_DIR}"
RESULT_SHA="$(git rev-parse HEAD)"
EXIT_CODE="$?"
if [ "${EXIT_CODE}" != 0 ] ; then
exit "${EXIT_CODE}"
fi
printf "%s" "${RESULT_SHA}" > "$(results.commit.path)"
printf "%s" "${PARAM_URL}" > "$(results.url.path)"

View File

@@ -0,0 +1,69 @@
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: kaniko-build
namespace: innoventions
labels:
app.kubernetes.io/version: "0.1"
annotations:
tekton.dev/pipelines.minVersion: "0.29.0"
tekton.dev/categories: Image Build
tekton.dev/tags: image-build, kaniko
tekton.dev/displayName: "kaniko build"
tekton.dev/platforms: "linux/amd64,linux/arm64"
spec:
description: >-
This Task builds source into a container image using Google's Kaniko tool.
Kaniko doesn't depend on a Docker daemon and executes each command within a Dockerfile
completely in userspace. This enables building container images in environments that
can't easily or securely run a Docker daemon, such as a standard Kubernetes cluster.
params:
- name: IMAGE
description: Name (reference) of the image to build.
- name: DOCKERFILE
description: Path to the Dockerfile to build.
default: ./Dockerfile
- name: CONTEXT
description: The build context used by Kaniko.
default: ./
- name: EXTRA_ARGS
type: array
default: []
- name: BUILDER_IMAGE
description: The image on which builds will run (default is v1.23.2)
default: gcr.io/kaniko-project/executor:v1.23.2@sha256:7f77bc1c6b96e5da7fdb56fb0dc1c16ba0f7fc8b5d1eeaa75fa5db39ec2f4a4d
workspaces:
- name: source
description: Holds the context and Dockerfile
- name: dockerconfig
description: Includes a docker `config.json`
optional: true
mountPath: /kaniko/.docker
results:
- name: IMAGE_DIGEST
description: Digest of the image just built.
- name: IMAGE_URL
description: URL of the image just built.
steps:
- name: build-and-push
workingDir: $(workspaces.source.path)
image: $(params.BUILDER_IMAGE)
args:
- $(params.EXTRA_ARGS)
- --dockerfile=$(params.DOCKERFILE)
- --context=$(workspaces.source.path)/$(params.CONTEXT)
- --destination=$(params.IMAGE)
- --digest-file=$(results.IMAGE_DIGEST.path)
# kaniko assumes it is running as root, which means this example fails on platforms
# that default to run containers as random uid (like OpenShift). Adding this securityContext
# makes it explicit that it needs to run as root.
securityContext:
runAsUser: 0
- name: write-url
image: docker.io/library/bash:5.1.4@sha256:c523c636b722339f41b6a431b44588ab2f762c5de5ec3bd7964420ff982fb1d9
script: |
set -e
image="$(params.IMAGE)"
echo -n "${image}" | tee "$(results.IMAGE_URL.path)"