This commit is contained in:
2024-04-19 12:22:23 +02:00
parent 7dae79cb46
commit b56a7de484
41 changed files with 2911 additions and 12 deletions

View File

@@ -0,0 +1,17 @@
locals {
common-labels = {
"vynil.solidite.fr/owner-name" = var.instance
"vynil.solidite.fr/owner-namespace" = var.namespace
"vynil.solidite.fr/owner-category" = var.category
"vynil.solidite.fr/owner-component" = var.component
"app.kubernetes.io/managed-by" = "vynil"
"app.kubernetes.io/name" = var.component
"app.kubernetes.io/instance" = var.instance
}
}
data "kustomization_overlay" "data" {
namespace = var.namespace
common_labels = local.common-labels
resources = [for file in fileset(path.module, "*.yaml"): file if file != "index.yaml"]
}

View File

@@ -0,0 +1,38 @@
locals {
gitea_host = "http://gitea-http.${var.domain}-ci.svc:3000"
gitea_username = data.kubernetes_secret_v1.gitea.data["username"]
gitea_password = data.kubernetes_secret_v1.gitea.data["password"]
request_headers = {
"Content-Type" = "application/json"
Authorization = "Basic ${base64encode("${local.gitea_username}:${local.gitea_password}")}"
}
}
data "kubernetes_secret_v1" "gitea" {
metadata {
name = "gitea-admin-user"
namespace = "${var.domain}-ci"
}
}
provider "restapi" {
uri = "${local.gitea_host}/api/v1"
headers = local.request_headers
id_attribute = "id"
}
# resource "restapi_object" "gitea_org_hook" {
# path = "/orgs/${var.organization}/hooks"
# data = jsonencode({
# type = "gitea"
# active = true
# branch_filter = "*"
# events = [
# "create",
# "push"
# ],
# config = {
# url = ""
# content_type = "application/json"
# }
# })
# }

View File

@@ -0,0 +1,38 @@
---
apiVersion: vinyl.solidite.fr/v1beta1
kind: Component
category: share
metadata:
name: gitea-tekton-org
description: null
options:
domain:
default: your-company
examples:
- your-company
type: string
organization:
default: your-org
examples:
- your-org
type: string
dependencies:
- dist: null
category: apps
component: gitea
- dist: null
category: workflow
component: tekton-pipelines
- dist: null
category: workflow
component: tekton-triggers
providers:
kubernetes: true
authentik: null
kubectl: true
postgresql: null
mysql: null
restapi: true
http: null
gitea: null
tfaddtype: null

View File

@@ -0,0 +1,12 @@
resource "kubectl_manifest" "el" {
yaml_body = <<-EOF
apiVersion: triggers.tekton.dev/v1beta1
kind: EventListener
metadata:
name: "${var.instance}-${var.component}"
namespace: "${var.namespace}"
labels: ${jsonencode(local.common-labels)}
spec:
serviceAccountName: "${var.instance}-${var.component}"
EOF
}

View File

@@ -0,0 +1,46 @@
resource "kubectl_manifest" "sa" {
yaml_body = <<-EOF
apiVersion: v1
kind: ServiceAccount
metadata:
name: "${var.instance}-${var.component}"
namespace: "${var.namespace}"
labels: ${jsonencode(local.common-labels)}
EOF
}
resource "kubectl_manifest" "rb" {
yaml_body = <<-EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: "${var.instance}-${var.component}"
namespace: "${var.namespace}"
labels: ${jsonencode(local.common-labels)}
subjects:
- kind: ServiceAccount
name: "${var.instance}-${var.component}"
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: tekton-triggers-eventlistener-roles
EOF
}
resource "kubectl_manifest" "crb" {
yaml_body = <<-EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: "${var.namespace}-${var.instance}-${var.component}"
namespace: "${var.namespace}"
labels: ${jsonencode(local.common-labels)}
subjects:
- kind: ServiceAccount
name: "${var.instance}-${var.component}"
namespace: "${var.namespace}"
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: tekton-triggers-eventlistener-clusterroles
EOF
}

View File

@@ -0,0 +1,86 @@
apiVersion: tekton.dev/v1
kind: Task
metadata:
name: hugo
labels:
app.kubernetes.io/version: "0.1"
annotations:
tekton.dev/pipelines.minVersion: "0.12.1"
tekton.dev/categories: Build Tools, Cloud
tekton.dev/tags: buildtools, cloud
tekton.dev/displayName: Hugo
tekton.dev/platforms: "linux/amd64"
spec:
description: >-
A Task that builds a Hugo site.
This task uses the Hugo static site generator to build a static site from the
content in the specified directory.
workspaces:
- name: work-dir
params:
- name: content-dir
type: string
description: The directory where the content is located
default: ""
- name: minify
type: string
description: Minify the output e.g. HTML, CSS, JS, XML
default: "false"
- name: base-url
type: string
description: The base URL for the Hugo site. By default reads from the hugo.toml or hugo.yaml
default: ""
- name: verbose
type: string
description: Verbose output
default: "false"
results:
- name: output
description: generated static site
steps:
- name: build
env:
- name: HUGO_MINIFY
value: $(params.minify)
- name: HUGO_BASEURL
value: $(params.base-url)
- name: HUGO_VERBOSE
value: $(params.verbose)
- name: HUGO_CONTENT_DIR
value: $(params.content-dir)
image: docker.io/hugomods/hugo:0.122.0@sha256:e90f2e6786969463f3475c7d5e7f031cb5dbf75a8394687d52f99d6c9d0eda0d
script: |
export HUGOCMD="hugo"
if [ "$HUGO_MINIFY" = 'true' ]; then
export HUGOCMD="${HUGOCMD} --minify"
fi
if [ "$HUGO_BASEURL" != '' ]; then
export HUGOCMD="${HUGOCMD} --baseURL $HUGO_BASEURL"
fi
if [ "$HUGO_VERBOSE" = 'true' ]; then
export HUGOCMD="${HUGOCMD} --verbose"
fi
if [ "$HUGO_CONTENT_DIR" != '' ]; then
export HUGOCMD="${HUGOCMD} --contentDir ${HUGO_CONTENT_DIR}"
fi
cd "$(workspaces.work-dir.path)" || exit
$HUGOCMD
printf "%s/public" "$(workspaces.work-dir.path)" | tee /tekton/results/output

View File

@@ -0,0 +1,139 @@
---
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: buildpacks
labels:
app.kubernetes.io/version: "0.2"
annotations:
tekton.dev/pipelines.minVersion: "0.17.0"
tekton.dev/tags: image-build
tekton.dev/displayName: "Buildpacks"
tekton.dev/platforms: "linux/amd64"
spec:
description: >-
The Buildpacks pipeline builds source from a Git repository into a container image and pushes it to a registry, using Cloud Native Buildpacks.
workspaces:
- name: source-ws
description: Location where source is stored.
- name: cache-ws
description: Location where cache is stored if CACHE_IMAGE is not provided.
optional: true
params:
- name: BUILDER_IMAGE
description: The image on which builds will run (must include lifecycle and compatible buildpacks).
- name: TRUST_BUILDER
description: >-
Whether the builder image is trusted.
When false, each build phase is executed in isolation and credentials are only shared with trusted images.
default: "false"
- name: APP_IMAGE
description: The name of where to store the app image.
- name: SOURCE_URL
description: A git repo url where the source code resides.
- name: SOURCE_REFERENCE
description: The branch, tag or SHA to checkout.
default: ""
- name: SOURCE_SUBPATH
description: A subpath within checked out source where the source to build is located.
default: ""
- name: ENV_VARS
type: array
description: Environment variables to set during _build-time_.
default: [""]
- name: PROCESS_TYPE
description: The default process type to set on the image.
default: "web"
- name: RUN_IMAGE
description: The name of the run image to use (defaults to image specified in builder).
default: ""
- name: CACHE_IMAGE
description: The name of the persistent cache image.
default: ""
- name: USER_ID
description: The user ID of the builder image user.
default: "1000"
- name: GROUP_ID
description: The group ID of the builder image user.
default: "1000"
tasks:
- name: fetch-from-git
taskRef:
name: git-clone
params:
- name: url
value: $(params.SOURCE_URL)
- name: revision
value: $(params.SOURCE_REFERENCE)
workspaces:
- name: output
workspace: source-ws
- name: build-trusted
runAfter:
- fetch-from-git
taskRef:
name: buildpacks
when:
- input: "$(params.TRUST_BUILDER)"
operator: in
values: ["true", "yes", "TRUE", "True"]
workspaces:
- name: source
workspace: source-ws
- name: cache
workspace: cache-ws
params:
- name: BUILDER_IMAGE
value: "$(params.BUILDER_IMAGE)"
- name: APP_IMAGE
value: "$(params.APP_IMAGE)"
- name: SOURCE_SUBPATH
value: "$(params.SOURCE_SUBPATH)"
- name: PROCESS_TYPE
value: "$(params.PROCESS_TYPE)"
- name: ENV_VARS
value: ["$(params.ENV_VARS)"]
- name: RUN_IMAGE
value: "$(params.RUN_IMAGE)"
- name: CACHE_IMAGE
value: "$(params.CACHE_IMAGE)"
- name: USER_ID
value: "$(params.USER_ID)"
- name: GROUP_ID
value: "$(params.GROUP_ID)"
- name: build-untrusted
runAfter:
- fetch-from-git
taskRef:
name: buildpacks-phases
when:
- input: "$(params.TRUST_BUILDER)"
operator: notin
values: ["true", "yes", "TRUE", "True"]
workspaces:
- name: source
workspace: source-ws
- name: cache
workspace: cache-ws
params:
- name: BUILDER_IMAGE
value: "$(params.BUILDER_IMAGE)"
- name: APP_IMAGE
value: "$(params.APP_IMAGE)"
- name: SOURCE_SUBPATH
value: "$(params.SOURCE_SUBPATH)"
- name: ENV_VARS
value: ["$(params.ENV_VARS)"]
- name: PROCESS_TYPE
value: "$(params.PROCESS_TYPE)"
- name: RUN_IMAGE
value: "$(params.RUN_IMAGE)"
- name: CACHE_IMAGE
value: "$(params.CACHE_IMAGE)"
- name: USER_ID
value: "$(params.USER_ID)"
- name: GROUP_ID
value: "$(params.GROUP_ID)"

View File

@@ -0,0 +1,51 @@
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: ansible-builder
labels:
app.kubernetes.io/version: "0.1"
annotations:
tekton.dev/deprecated: "true"
tekton.dev/pipelines.minVersion: "0.12.0"
tekton.dev/displayName: ansible-builder
tekton.dev/categories: Build Tools
tekton.dev/tags: ansible, ansible-builder, build-tool, automation
tekton.dev/platforms: "linux/amd64"
spec:
description: >-
Creates a build context (including a Containerfile) from an execution environment spec.
This build context is populated with dependencies including requirements files.
workspaces:
- name: source
description: The source workspace where the execution environment code is cloned.
params:
- description: Execution environment file definition.
name: FILENAME
type: string
default: execution-environment.yml
- description: Execution environment build context.
name: BUILD_CONTEXT
type: string
default: context
- name: OUTPUT_FILENAME
description: Name of file to write image definition to. Either Dockerfile or Containerfile.
type: string
default: Containerfile
- description: ansible-builder output verbosity.
name: VERBOSITY
type: string
default: "2"
- name: BUILDER_IMAGE
description: The location of the ansible-builder image.
type: string
default: quay.io/ansible/ansible-builder:latest
steps:
- name: ansible-builder-create
workingDir: $(workspaces.source.path)
image: $(params.BUILDER_IMAGE)
script: |
#!/bin/sh
set -eux -o
ansible-builder create -f "$(params.FILENAME)" -c "$(params.BUILD_CONTEXT)" --output-filename "$(params.OUTPUT_FILENAME)" -v "$(params.VERBOSITY)"

View File

@@ -0,0 +1,72 @@
---
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: ansible-runner
labels:
app.kubernetes.io/version: '0.2'
app.kubernetes.io/ansible-version: '2.12.5'
annotations:
tekton.dev/deprecated: "true"
tekton.dev/pipelines.minVersion: '0.12.1'
tekton.dev/categories: CLI
tekton.dev/tags: cli
tekton.dev/displayName: 'Ansible Runner'
tekton.dev/platforms: "linux/amd64"
spec:
description: >-
Task to run Ansible playbooks using Ansible Runner
workspaces:
- name: runner-dir
description: The Ansibler runner directory
params:
- name: project-dir
description: The project directory under the workspace runner-dir
default: 'project'
- name: args
description: The arguments to pass ansible-runner
type: array
default:
- --help
- name: user-home
description: Absolute path to the user's home directory.
default: /tekton/home
- name: image
description: Ansible runner image.
default: quay.io/ansible/ansible-runner:stable-2.12-latest #tag: stable-2.12-latest
stepTemplate:
env:
- name: HOME
value: $(params.user-home)
steps:
- name: requirements
image: $(params.image)
script: |
#!/bin/bash
set -e
if [ -f requirements.txt ];
then
pip3 install --user \
-r requirements.txt
fi
if [ -f requirements.yml ];
then
ansible-galaxy role install -vv \
-r requirements.yml
ansible-galaxy collection install -vv \
-r requirements.yml
fi
workingDir: '$(workspaces.runner-dir.path)/$(params.project-dir)'
- name: run-playbook
image: $(params.image)
command: ['entrypoint']
args:
- ansible-runner
- run
- $(params.args)
- $(params.project-dir)
workingDir: '$(workspaces.runner-dir.path)'

View File

@@ -0,0 +1,43 @@
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: black
labels:
app.kubernetes.io/version: "0.2"
annotations:
tekton.dev/pipelines.minVersion: "0.12.1"
tekton.dev/categories: Code Quality
tekton.dev/tags: formatter, python, black
tekton.dev/displayName: "Python Black"
tekton.dev/platforms: "linux/amd64"
spec:
description: >-
This task can be used to format Python code
workspaces:
- name: shared-workspace
description: >-
The workspace containing python source code which we want to format.
params:
- name: image
description: The container image to use black in
default: docker.io/cytopia/black:latest-0.2@sha256:2ec766f1c7e42e6b59c0873ce066fa0a2aa2bf8a80dbc1c40f1566bb539303e0
- name: requirements_file
description: The name of the requirements file inside the source location
default: requirements.txt
- name: args
type: array
description: extra args that needs to be appended
default: ["--help"]
steps:
- name: format-python-code
image: $(params.image)
workingDir: $(workspaces.shared-workspace.path)
script: |
export HOME=/tmp/python
export PATH=$PATH:/tmp/python/.local/bin
if [ -n "$(params.requirements_file)" ] && [ -e "$(params.requirements_file)" ];then
python -mpip install --user -r $(params.requirements_file)
fi
black $@
args:
- $(params.args)

View File

@@ -0,0 +1,98 @@
---
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: buildah
labels:
app.kubernetes.io/version: "0.7"
annotations:
tekton.dev/categories: Image Build
tekton.dev/pipelines.minVersion: "0.17.0"
tekton.dev/tags: image-build
tekton.dev/platforms: "linux/amd64,linux/s390x,linux/ppc64le,linux/arm64"
tekton.dev/displayName: buildah
spec:
description: >-
Buildah task builds source into a container image and
then pushes it to a container registry.
Buildah Task builds source into a container image using Project Atomic's
Buildah build tool.It uses Buildah's support for building from Dockerfiles,
using its buildah bud command.This command executes the directives in the
Dockerfile to assemble a container image, then pushes that image to a
container registry.
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
- name: STORAGE_DRIVER
description: Set buildah storage driver
default: overlay
- name: DOCKERFILE
description: Path to the Dockerfile to build.
default: ./Dockerfile
- name: CONTEXT
description: Path to the directory to use as context.
default: .
- name: TLSVERIFY
description: Verify the TLS on the registry endpoint (for push/pull to a non-TLS registry)
default: "true"
- name: FORMAT
description: The format of the built container, oci or docker
default: "oci"
- name: BUILD_EXTRA_ARGS
description: Extra parameters passed for the build command when building images.
default: ""
- name: PUSH_EXTRA_ARGS
description: Extra parameters passed for the push command when pushing images.
type: string
default: ""
- name: SKIP_PUSH
description: Skip pushing the built image
default: "false"
workspaces:
- name: source
- name: sslcertdir
optional: true
- name: dockerconfig
description: >-
An optional workspace that allows providing a .docker/config.json file
for Buildah to access the container registry.
The file should be placed at the root of the Workspace with name config.json.
optional: true
results:
- name: IMAGE_DIGEST
description: Digest of the image just built.
- name: IMAGE_URL
description: Image repository where the built image would be pushed to
steps:
- name: build-and-push
image: $(params.BUILDER_IMAGE)
workingDir: $(workspaces.source.path)
script: |
[ "$(workspaces.sslcertdir.bound)" = "true" ] && CERT_DIR_FLAG="--cert-dir=$(workspaces.sslcertdir.path)"
[ "$(workspaces.dockerconfig.bound)" = "true" ] && DOCKER_CONFIG="$(workspaces.dockerconfig.path)" && export DOCKER_CONFIG
# build the image (CERT_DIR_FLAG should be omitted if empty and BUILD_EXTRA_ARGS can contain multiple args)
# shellcheck disable=SC2046,SC2086
buildah ${CERT_DIR_FLAG} "--storage-driver=$(params.STORAGE_DRIVER)" bud $(params.BUILD_EXTRA_ARGS) \
"--format=$(params.FORMAT)" "--tls-verify=$(params.TLSVERIFY)" \
-f "$(params.DOCKERFILE)" -t "$(params.IMAGE)" "$(params.CONTEXT)"
[ "$(params.SKIP_PUSH)" = "true" ] && echo "Push skipped" && exit 0
# push the image (CERT_DIR_FLAG should be omitted if empty and PUSH_EXTRA_ARGS can contain multiple args)
# shellcheck disable=SC2046,SC2086
buildah ${CERT_DIR_FLAG} "--storage-driver=$(params.STORAGE_DRIVER)" push $(params.PUSH_EXTRA_ARGS) \
"--tls-verify=$(params.TLSVERIFY)" --digestfile /tmp/image-digest "$(params.IMAGE)" \
"docker://$(params.IMAGE)"
tee "$(results.IMAGE_DIGEST.path)" < /tmp/image-digest
printf '%s' "$(params.IMAGE)" | tee "$(results.IMAGE_URL.path)"
volumeMounts:
- name: varlibcontainers
mountPath: /var/lib/containers
securityContext:
privileged: true
volumes:
- name: varlibcontainers
emptyDir: {}

View File

@@ -0,0 +1,51 @@
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: buildkit-daemonless
labels:
app.kubernetes.io/version: "0.1"
annotations:
tekton.dev/pipelines.minVersion: "0.12.1"
tekton.dev/categories: Image Build
tekton.dev/tags: image-build
tekton.dev/displayName: "buildkit daemonless"
tekton.dev/platforms: "linux/amd64"
tekton.dev/deprecated: "true"
spec:
description: >-
This Task builds source into a container image using Moby BuildKit.
This buildkit-daemonless Task is similar to buildkit but does not need
creating Secret, Deployment, and Service resources for setting up the
buildkitd daemon cluster.
params:
- name: DOCKERFILE
description: The name of the Dockerfile
default: "Dockerfile"
- name: BUILDKIT_IMAGE
description: The name of the BuildKit image
# The image needs to be rootful because Tekton creates /builder/home/.docker/config.json owned by root:root with 0600
# https://github.com/tektoncd/pipeline/issues/852
default: "docker.io/moby/buildkit:v0.6.2@sha256:db234cf7362aef489e4273a6937794cb19c09ba15c7ee0ec6f85044086ea4f6a"
workspaces:
- name: source
resources:
outputs:
- name: image
type: image
steps:
- name: build-and-push
image: $(params.BUILDKIT_IMAGE)
workingDir: $(workspaces.source.path)
securityContext:
privileged: true
command: ["buildctl-daemonless.sh", "--debug",
"build",
"--progress=plain",
"--frontend=dockerfile.v0",
"--opt", "filename=$(params.DOCKERFILE)",
"--local", "context=.", "--local", "dockerfile=.",
"--output", "type=image,name=$(resources.outputs.image.url),push=true",
"--export-cache", "type=inline",
"--import-cache", "type=registry,ref=$(resources.outputs.image.url)"]

View File

@@ -0,0 +1,241 @@
---
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: buildpacks-phases
labels:
app.kubernetes.io/version: "0.2"
annotations:
tekton.dev/categories: Image Build, Security
tekton.dev/pipelines.minVersion: "0.17.0"
tekton.dev/tags: image-build
tekton.dev/displayName: "Buildpacks (phases)"
tekton.dev/platforms: "linux/amd64"
spec:
description: >-
The Buildpacks-Phases task builds source into a container image and pushes it to
a registry, using Cloud Native Buildpacks. This task separately calls the aspects of the
Cloud Native Buildpacks lifecycle, to provide increased security via container isolation.
workspaces:
- name: source
description: Directory where application source is located.
- name: cache
description: Directory where cache is stored (when no cache image is provided).
optional: true
params:
- name: APP_IMAGE
description: The name of where to store the app image.
- name: BUILDER_IMAGE
description: The image on which builds will run (must include lifecycle and compatible buildpacks).
- name: SOURCE_SUBPATH
description: A subpath within the `source` input where the source to build is located.
default: ""
- name: ENV_VARS
type: array
description: Environment variables to set during _build-time_.
default: []
- name: PROCESS_TYPE
description: The default process type to set on the image.
default: "web"
- name: RUN_IMAGE
description: Reference to a run image to use.
default: ""
- name: CACHE_IMAGE
description: The name of the persistent app cache image (if no cache workspace is provided).
default: ""
- name: USER_ID
description: The user ID of the builder image user.
default: "1000"
- name: GROUP_ID
description: The group ID of the builder image user.
default: "1000"
- name: PLATFORM_DIR
description: The name of the platform directory.
default: empty-dir
- name: LIFECYCLE_IMAGE
description: The image to use when executing sensitive phases.
default: docker.io/buildpacksio/lifecycle:0.10.2@sha256:1bf8d3fc41d2fdf0ee4abdad50038ab8902ef58c74f5bcfc432c26767d889ed0
- name: USER_HOME
description: Absolute path to the user's home directory.
default: /tekton/home
results:
- name: APP_IMAGE_DIGEST
description: The digest of the built `APP_IMAGE`.
stepTemplate:
env:
- name: CNB_PLATFORM_API
value: "0.4"
- name: HOME
value: $(params.USER_HOME)
steps:
- name: prepare
image: docker.io/library/bash:5.1.4@sha256:b208215a4655538be652b2769d82e576bc4d0a2bb132144c060efc5be8c3f5d6
args:
- "--env-vars"
- "$(params.ENV_VARS[*])"
script: |
#!/usr/bin/env bash
set -e
if [[ "$(workspaces.cache.bound)" == "true" ]]; then
echo "> Setting permissions on '$(workspaces.cache.path)'..."
chown -R "$(params.USER_ID):$(params.GROUP_ID)" "$(workspaces.cache.path)"
fi
for path in "/tekton/home" "/layers" "$(workspaces.source.path)"; do
echo "> Setting permissions on '$path'..."
chown -R "$(params.USER_ID):$(params.GROUP_ID)" "$path"
done
echo "> Parsing additional configuration..."
parsing_flag=""
envs=()
for arg in "$@"; do
if [[ "$arg" == "--env-vars" ]]; then
echo "-> Parsing env variables..."
parsing_flag="env-vars"
elif [[ "$parsing_flag" == "env-vars" ]]; then
envs+=("$arg")
fi
done
echo "> Processing any environment variables..."
ENV_DIR="/platform/env"
echo "--> Creating 'env' directory: $ENV_DIR"
mkdir -p "$ENV_DIR"
for env in "${envs[@]}"; do
IFS='=' read -r key value string <<< "$env"
if [[ "$key" != "" && "$value" != "" ]]; then
path="${ENV_DIR}/${key}"
echo "--> Writing ${path}..."
echo -n "$value" > "$path"
fi
done
volumeMounts:
- name: layers-dir
mountPath: /layers
- name: $(params.PLATFORM_DIR)
mountPath: /platform
securityContext:
privileged: true
# Copy stack.toml so that it will be accessible to the exporter, since the lifecycle image will not contain it.
- name: copy-stack-toml
image: $(params.BUILDER_IMAGE)
imagePullPolicy: Always
command: ["/bin/sh"]
args:
- "-c"
- >
cp /cnb/stack.toml /layers/
volumeMounts:
- name: layers-dir
mountPath: /layers
- name: detect
image: $(params.BUILDER_IMAGE)
imagePullPolicy: Always
command: ["/cnb/lifecycle/detector"]
args:
- "-app=$(workspaces.source.path)/$(params.SOURCE_SUBPATH)"
- "-group=/layers/group.toml"
- "-plan=/layers/plan.toml"
volumeMounts:
- name: layers-dir
mountPath: /layers
- name: $(params.PLATFORM_DIR)
mountPath: /platform
- name: empty-dir
mountPath: /tekton/home
- name: analyze
image: $(params.LIFECYCLE_IMAGE)
imagePullPolicy: Always
command: ["/cnb/lifecycle/analyzer"]
args:
- "-layers=/layers"
- "-group=/layers/group.toml"
- "-cache-dir=$(workspaces.cache.path)"
- "-cache-image=$(params.CACHE_IMAGE)"
- "-uid=$(params.USER_ID)"
- "-gid=$(params.GROUP_ID)"
- "$(params.APP_IMAGE)"
volumeMounts:
- name: layers-dir
mountPath: /layers
- name: restore
image: $(params.LIFECYCLE_IMAGE)
imagePullPolicy: Always
command: ["/cnb/lifecycle/restorer"]
args:
- "-group=/layers/group.toml"
- "-layers=/layers"
- "-cache-dir=$(workspaces.cache.path)"
- "-cache-image=$(params.CACHE_IMAGE)"
- "-uid=$(params.USER_ID)"
- "-gid=$(params.GROUP_ID)"
volumeMounts:
- name: layers-dir
mountPath: /layers
- name: build
image: $(params.BUILDER_IMAGE)
imagePullPolicy: Always
command: ["/cnb/lifecycle/builder"]
args:
- "-app=$(workspaces.source.path)/$(params.SOURCE_SUBPATH)"
- "-layers=/layers"
- "-group=/layers/group.toml"
- "-plan=/layers/plan.toml"
volumeMounts:
- name: layers-dir
mountPath: /layers
- name: $(params.PLATFORM_DIR)
mountPath: /platform
- name: empty-dir
mountPath: /tekton/home
- name: export
image: $(params.LIFECYCLE_IMAGE)
imagePullPolicy: Always
command: ["/cnb/lifecycle/exporter"]
args:
- "-app=$(workspaces.source.path)/$(params.SOURCE_SUBPATH)"
- "-layers=/layers"
- "-group=/layers/group.toml"
- "-cache-dir=$(workspaces.cache.path)"
- "-cache-image=$(params.CACHE_IMAGE)"
- "-report=/layers/report.toml"
- "-process-type=$(params.PROCESS_TYPE)"
- "-uid=$(params.USER_ID)"
- "-gid=$(params.GROUP_ID)"
- "-stack=/layers/stack.toml"
- "-run-image=$(params.RUN_IMAGE)"
- "$(params.APP_IMAGE)"
volumeMounts:
- name: layers-dir
mountPath: /layers
- name: results
image: docker.io/library/bash:5.1.4@sha256:b208215a4655538be652b2769d82e576bc4d0a2bb132144c060efc5be8c3f5d6
script: |
#!/usr/bin/env bash
set -e
cat /layers/report.toml | grep "digest" | cut -d'"' -f2 | cut -d'"' -f2 | tr -d '\n' | tee $(results.APP_IMAGE_DIGEST.path)
volumeMounts:
- name: layers-dir
mountPath: /layers
volumes:
- name: empty-dir
emptyDir: {}
- name: layers-dir
emptyDir: {}

View File

@@ -0,0 +1,178 @@
---
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: buildpacks
labels:
app.kubernetes.io/version: "0.6"
annotations:
tekton.dev/categories: Image Build
tekton.dev/pipelines.minVersion: "0.17.0"
tekton.dev/tags: image-build
tekton.dev/displayName: "Buildpacks"
tekton.dev/platforms: "linux/amd64"
spec:
description: >-
The Buildpacks task builds source into a container image and pushes it to a registry,
using Cloud Native Buildpacks.
workspaces:
- name: source
description: Directory where application source is located.
- name: cache
description: Directory where cache is stored (when no cache image is provided).
optional: true
- name: dockerconfig
description: >-
An optional workspace that allows providing a .docker/config.json file
for Buildpacks lifecycle binary to access the container registry.
The file should be placed at the root of the Workspace with name config.json.
optional: true
params:
- name: APP_IMAGE
description: The name of where to store the app image.
- name: BUILDER_IMAGE
description: The image on which builds will run (must include lifecycle and compatible buildpacks).
- name: SOURCE_SUBPATH
description: A subpath within the `source` input where the source to build is located.
default: ""
- name: ENV_VARS
type: array
description: Environment variables to set during _build-time_.
default: []
- name: PROCESS_TYPE
description: The default process type to set on the image.
default: "web"
- name: RUN_IMAGE
description: Reference to a run image to use.
default: ""
- name: CACHE_IMAGE
description: The name of the persistent app cache image (if no cache workspace is provided).
default: ""
- name: SKIP_RESTORE
description: Do not write layer metadata or restore cached layers.
default: "false"
- name: USER_ID
description: The user ID of the builder image user.
default: "1000"
- name: GROUP_ID
description: The group ID of the builder image user.
default: "1000"
- name: PLATFORM_DIR
description: The name of the platform directory.
default: empty-dir
results:
- name: APP_IMAGE_DIGEST
description: The digest of the built `APP_IMAGE`.
- name: APP_IMAGE_URL
description: The URL of the built `APP_IMAGE`.
stepTemplate:
env:
- name: CNB_PLATFORM_API
value: "0.9"
steps:
- name: prepare
image: docker.io/library/bash:5.1.4@sha256:b208215a4655538be652b2769d82e576bc4d0a2bb132144c060efc5be8c3f5d6
args:
- "--env-vars"
- "$(params.ENV_VARS[*])"
script: |
#!/usr/bin/env bash
set -e
if [[ "$(workspaces.cache.bound)" == "true" ]]; then
echo "> Setting permissions on '$(workspaces.cache.path)'..."
chown -R "$(params.USER_ID):$(params.GROUP_ID)" "$(workspaces.cache.path)"
fi
for path in "/tekton/home" "/layers" "$(workspaces.source.path)"; do
echo "> Setting permissions on '$path'..."
chown -R "$(params.USER_ID):$(params.GROUP_ID)" "$path"
if [[ "$path" == "$(workspaces.source.path)" ]]; then
chmod 775 "$(workspaces.source.path)"
fi
done
echo "> Parsing additional configuration..."
parsing_flag=""
envs=()
for arg in "$@"; do
if [[ "$arg" == "--env-vars" ]]; then
echo "-> Parsing env variables..."
parsing_flag="env-vars"
elif [[ "$parsing_flag" == "env-vars" ]]; then
envs+=("$arg")
fi
done
echo "> Processing any environment variables..."
ENV_DIR="/platform/env"
echo "--> Creating 'env' directory: $ENV_DIR"
mkdir -p "$ENV_DIR"
for env in "${envs[@]}"; do
IFS='=' read -r key value <<< "$env"
if [[ "$key" != "" && "$value" != "" ]]; then
path="${ENV_DIR}/${key}"
echo "--> Writing ${path}..."
echo -n "$value" > "$path"
fi
done
volumeMounts:
- name: layers-dir
mountPath: /layers
- name: $(params.PLATFORM_DIR)
mountPath: /platform
- name: create
image: $(params.BUILDER_IMAGE)
imagePullPolicy: Always
command: ["/cnb/lifecycle/creator"]
env:
- name: DOCKER_CONFIG
value: $(workspaces.dockerconfig.path)
args:
- "-app=$(workspaces.source.path)/$(params.SOURCE_SUBPATH)"
- "-cache-dir=$(workspaces.cache.path)"
- "-cache-image=$(params.CACHE_IMAGE)"
- "-uid=$(params.USER_ID)"
- "-gid=$(params.GROUP_ID)"
- "-layers=/layers"
- "-platform=/platform"
- "-report=/layers/report.toml"
- "-process-type=$(params.PROCESS_TYPE)"
- "-skip-restore=$(params.SKIP_RESTORE)"
- "-previous-image=$(params.APP_IMAGE)"
- "-run-image=$(params.RUN_IMAGE)"
- "$(params.APP_IMAGE)"
volumeMounts:
- name: layers-dir
mountPath: /layers
- name: $(params.PLATFORM_DIR)
mountPath: /platform
securityContext:
runAsUser: 1000
runAsGroup: 1000
- name: results
image: docker.io/library/bash:5.1.4@sha256:b208215a4655538be652b2769d82e576bc4d0a2bb132144c060efc5be8c3f5d6
script: |
#!/usr/bin/env bash
set -e
grep "digest" /layers/report.toml | cut -d'"' -f2 | cut -d'"' -f2 | tr -d '\n' | tee "$(results.APP_IMAGE_DIGEST.path)"
echo -n "$(params.APP_IMAGE)" | tee "$(results.APP_IMAGE_URL.path)"
volumeMounts:
- name: layers-dir
mountPath: /layers
volumes:
- name: empty-dir
emptyDir: {}
- name: layers-dir
emptyDir: {}

View File

@@ -0,0 +1,31 @@
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: check-make
labels:
app.kubernetes.io/version: "0.1"
annotations:
tekton.dev/pipelines.minVersion: "0.12.1"
tekton.dev/categories: Code Quality
tekton.dev/tags: linter
tekton.dev/displayName: "Makefile linter"
tekton.dev/platforms: "linux/amd64"
spec:
description: >-
This task can be used to perform lint check on Makefiles
workspaces:
- name: shared-workspace
description: A workspace that contains the fetched git repository.
params:
- name: args
type: array
description: extra args needs to append
default: ["--help"]
steps:
- name: lint-makefile
image: docker.io/cytopia/checkmake:0.1.0@sha256:50957311f1ae25fd5925e1a45798d323cf00b3654cd1eede8db7814c72cec41d #tag: 0.1.0
workingDir: $(workspaces.shared-workspace.path)
command:
- checkmake
args:
- $(params.args)

View File

@@ -0,0 +1,32 @@
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: curl
labels:
app.kubernetes.io/version: "0.1"
annotations:
tekton.dev/pipelines.minVersion: "0.12.1"
tekton.dev/categories: CLI
tekton.dev/tags: search
tekton.dev/platforms: "linux/amd64,linux/s390x,linux/ppc64le,linux/arm64"
spec:
description: >-
This task performs curl operation to transfer data from internet.
params:
- name: url
description: URL to curl'ed
type: string
- name: options
description: options of url
type: array
default: []
- name: curl-image
description: option of curl image
type: string
default: "docker.io/curlimages/curl:7.72.0@sha256:bd5bbd35f89b867c1dccbc84b8be52f3f74dea20b46c5fe0db3780e040afcb6f" #tag: 7.72.0
steps:
- name: curl
image: "$(params.curl-image)"
command: [curl]
args: ["$(params.options[*])", "$(params.url)"]

View File

@@ -0,0 +1,113 @@
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: docker-build
labels:
app.kubernetes.io/version: "0.1"
annotations:
tekton.dev/pipelines.minVersion: "0.12.1"
tekton.dev/categories: Image Build
tekton.dev/tags: docker, build-image, push-image, dind
tekton.dev/displayName: docker-build
tekton.dev/platforms: "linux/amd64"
spec:
description: >-
This task will build and push an image using docker.
The task will build an out image out of a Dockerfile.
This image will be pushed to an image registry.
The image will be built and pushed using a dind sidecar over TCP+TLS.
params:
- name: image
description: Reference of the image docker will produce.
- name: builder_image
description: The location of the docker builder image.
default: docker.io/library/docker:stable@sha256:18ff92d3d31725b53fa6633d60bed323effb6d5d4588be7b547078d384e0d4bf #tag: stable
- name: dind_image
description: The location of the docker-in-docker image.
default: docker:dind
- name: dockerfile
description: Path to the Dockerfile to build.
default: ./Dockerfile
- name: context
description: Path to the directory to use as context.
default: .
- name: build_extra_args
description: Extra parameters passed for the build command when building images.
default: ""
- name: push_extra_args
description: Extra parameters passed for the push command when pushing images.
default: ""
- name: insecure_registry
description: Allows the user to push to an insecure registry that has been specified
default: ""
workspaces:
- name: source
results:
- name: IMAGE_DIGEST
description: Digest of the image just built.
steps:
- name: docker-build
image: $(params.builder_image)
env:
# Connect to the sidecar over TCP, with TLS.
- name: DOCKER_HOST
value: tcp://localhost:2376
# Verify TLS.
- name: DOCKER_TLS_VERIFY
value: '1'
# Use the certs generated by the sidecar daemon.
- name: DOCKER_CERT_PATH
value: /certs/client
workingDir: $(workspaces.source.path)
script: |
docker build \
$(params.build_extra_args) \
--no-cache \
-f $(params.dockerfile) -t $(params.image) $(params.context)
volumeMounts:
- mountPath: /certs/client
name: dind-certs
- name: docker-push
image: $(params.builder_image)
env:
# Connect to the sidecar over TCP, with TLS.
- name: DOCKER_HOST
value: tcp://localhost:2376
# Verify TLS.
- name: DOCKER_TLS_VERIFY
value: '1'
# Use the certs generated by the sidecar daemon.
- name: DOCKER_CERT_PATH
value: /certs/client
workingDir: $(workspaces.source.path)
script: |
docker push $(params.push_extra_args) $(params.image)
volumeMounts:
- mountPath: /certs/client
name: dind-certs
sidecars:
- image: $(params.dind_image)
name: server
args:
- --storage-driver=vfs
- --userland-proxy=false
- --debug
- --insecure-registry=$(params.insecure_registry)
securityContext:
privileged: true
env:
# Write generated certs to the path shared with the client.
- name: DOCKER_TLS_CERTDIR
value: /certs
volumeMounts:
- mountPath: /certs/client
name: dind-certs
# Wait for the dind daemon to generate the certs it will share with the
# client.
readinessProbe:
periodSeconds: 1
exec:
command: ['ls', '/certs/client/ca.pem']
volumes:
- name: dind-certs
emptyDir: {}

View File

@@ -0,0 +1,42 @@
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: generate-build-id
labels:
app.kubernetes.io/version: "0.1"
annotations:
tekton.dev/pipelines.minVersion: "0.12.1"
tekton.dev/categories: Build Tools
tekton.dev/tags: build-tool
tekton.dev/displayName: "buildid"
tekton.dev/platforms: "linux/amd64,linux/s390x,linux/ppc64le,linux/arm64"
spec:
description: >-
Given a base version, this task generates a unique build id by appending
the base-version to the current timestamp.
params:
- name: base-version
description: Base product version
type: string
default: "1.0"
results:
- name: timestamp
description: Current timestamp
- name: build-id
description: ID of the current build
steps:
- name: get-timestamp
image: docker.io/library/bash:5.0.18@sha256:879f94a9da53dc064779e7a68339aecd60a9028ff884cacaa47ae752ca690404 #tag: 5.0.18
script: |
#!/usr/bin/env bash
ts=`date "+%Y%m%d-%H%M%S"`
echo "Current Timestamp: ${ts}"
echo ${ts} | tr -d "\n" | tee $(results.timestamp.path)
- name: get-buildid
image: docker.io/library/bash:5.0.18@sha256:879f94a9da53dc064779e7a68339aecd60a9028ff884cacaa47ae752ca690404 #tag: 5.0.18
script: |
#!/usr/bin/env bash
ts=`cat $(results.timestamp.path)`
buildId=$(inputs.params.base-version)-${ts}
echo ${buildId} | tr -d "\n" | tee $(results.build-id.path)

View File

@@ -0,0 +1,242 @@
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: git-clone
labels:
app.kubernetes.io/version: "0.9"
annotations:
tekton.dev/pipelines.minVersion: "0.38.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: >-
These Tasks are Git tasks to work with repositories used by other tasks
in your Pipeline.
The git-clone Task will clone a repo from the provided url into the
output Workspace. By default the repo will be cloned into the root of
your Workspace. You can clone into a subdirectory by setting this Task's
subdirectory param. This Task also supports sparse checkouts. To perform
a sparse checkout, pass a list of comma separated directory patterns to
this Task's sparseCheckoutDirectories param.
workspaces:
- name: output
description: The git repo will be cloned onto the volume backing this Workspace.
- name: ssh-directory
optional: true
description: |
A .ssh directory with private key, known_hosts, config, etc. Copied to
the user's home before git commands are executed. Used to authenticate
with the git remote when performing the clone. Binding a Secret to this
Workspace is strongly recommended over other volume types.
- name: basic-auth
optional: true
description: |
A Workspace containing a .gitconfig and .git-credentials file. These
will be copied to the user's home before any git commands are run. Any
other files in this Workspace are ignored. It is strongly recommended
to use ssh-directory over basic-auth whenever possible and to bind a
Secret to this Workspace over other volume types.
- name: ssl-ca-directory
optional: true
description: |
A workspace containing CA certificates, this will be used by Git to
verify the peer with when fetching or pushing over HTTPS.
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: ""
- name: refspec
description: Refspec to fetch before checking out revision.
default: ""
- name: submodules
description: Initialize and fetch git submodules.
type: string
default: "true"
- 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: crtFileName
description: file name of mounted crt using ssl-ca-directory workspace. default value is ca-bundle.crt.
type: string
default: "ca-bundle.crt"
- name: subdirectory
description: Subdirectory inside the `output` Workspace to clone the repo into.
type: string
default: ""
- name: sparseCheckoutDirectories
description: Define the directory patterns to match or exclude when performing a sparse checkout.
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: "true"
- 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.
type: string
default: "/home/git"
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.
- name: committer-date
description: The epoch timestamp of the commit 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_CRT_FILENAME
value: $(params.crtFileName)
- 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_SPARSE_CHECKOUT_DIRECTORIES
value: $(params.sparseCheckoutDirectories)
- name: PARAM_USER_HOME
value: $(params.userHome)
- name: WORKSPACE_OUTPUT_PATH
value: $(workspaces.output.path)
- name: WORKSPACE_SSH_DIRECTORY_BOUND
value: $(workspaces.ssh-directory.bound)
- name: WORKSPACE_SSH_DIRECTORY_PATH
value: $(workspaces.ssh-directory.path)
- name: WORKSPACE_BASIC_AUTH_DIRECTORY_BOUND
value: $(workspaces.basic-auth.bound)
- name: WORKSPACE_BASIC_AUTH_DIRECTORY_PATH
value: $(workspaces.basic-auth.path)
- name: WORKSPACE_SSL_CA_DIRECTORY_BOUND
value: $(workspaces.ssl-ca-directory.bound)
- name: WORKSPACE_SSL_CA_DIRECTORY_PATH
value: $(workspaces.ssl-ca-directory.path)
securityContext:
runAsNonRoot: true
runAsUser: 65532
script: |
#!/usr/bin/env sh
set -eu
if [ "${PARAM_VERBOSE}" = "true" ] ; then
set -x
fi
if [ "${WORKSPACE_BASIC_AUTH_DIRECTORY_BOUND}" = "true" ] ; then
cp "${WORKSPACE_BASIC_AUTH_DIRECTORY_PATH}/.git-credentials" "${PARAM_USER_HOME}/.git-credentials"
cp "${WORKSPACE_BASIC_AUTH_DIRECTORY_PATH}/.gitconfig" "${PARAM_USER_HOME}/.gitconfig"
chmod 400 "${PARAM_USER_HOME}/.git-credentials"
chmod 400 "${PARAM_USER_HOME}/.gitconfig"
fi
if [ "${WORKSPACE_SSH_DIRECTORY_BOUND}" = "true" ] ; then
cp -R "${WORKSPACE_SSH_DIRECTORY_PATH}" "${PARAM_USER_HOME}"/.ssh
chmod 700 "${PARAM_USER_HOME}"/.ssh
chmod -R 400 "${PARAM_USER_HOME}"/.ssh/*
fi
if [ "${WORKSPACE_SSL_CA_DIRECTORY_BOUND}" = "true" ] ; then
export GIT_SSL_CAPATH="${WORKSPACE_SSL_CA_DIRECTORY_PATH}"
if [ "${PARAM_CRT_FILENAME}" != "" ] ; then
export GIT_SSL_CAINFO="${WORKSPACE_SSL_CA_DIRECTORY_PATH}/${PARAM_CRT_FILENAME}"
fi
fi
CHECKOUT_DIR="${WORKSPACE_OUTPUT_PATH}/${PARAM_SUBDIRECTORY}"
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_DELETE_EXISTING}" = "true" ] ; then
cleandir || true
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}"
git config --global --add safe.directory "${WORKSPACE_OUTPUT_PATH}"
/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}" \
-sparseCheckoutDirectories="${PARAM_SPARSE_CHECKOUT_DIRECTORIES}"
cd "${CHECKOUT_DIR}"
RESULT_SHA="$(git rev-parse HEAD)"
EXIT_CODE="$?"
if [ "${EXIT_CODE}" != 0 ] ; then
exit "${EXIT_CODE}"
fi
RESULT_COMMITTER_DATE="$(git log -1 --pretty=%ct)"
printf "%s" "${RESULT_COMMITTER_DATE}" > "$(results.committer-date.path)"
printf "%s" "${RESULT_SHA}" > "$(results.commit.path)"
printf "%s" "${PARAM_URL}" > "$(results.url.path)"

View File

@@ -0,0 +1,51 @@
---
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: git-version
labels:
app.kubernetes.io/version: "0.1"
annotations:
tekton.dev/pipelines.minVersion: "0.12.0"
tekton.dev/displayName: "git version"
tekton.dev/categories: Git
tekton.dev/tags: git
tekton.dev/platforms: "linux/amd64"
spec:
description: >-
This task can be used to create a version from git history
params:
- description: branch to checkout to create a version for e.g. "develop"
name: branch
type: string
results:
- description: The calculated git version you could use for git tagging e.g. "0.1.0-tektonize.1-188"
name: gitVersion
- description: A normalized version for use in container images e.g. "0.1.0-tektonize.1-188"
name: packageVersion
steps:
- image: mcr.microsoft.com/dotnet/sdk:3.1-focal@sha256:1d31e2582f69920c3a6ea9498bb7da285baffbca7ea84d90d9e5b545604cc92d
name: set-git-version
workingDir: $(workspaces.source.path)
securityContext:
runAsUser: 0
env:
- name: PARAM_BRANCH
value: $(params.branch)
script: |
#!/usr/bin/env bash
export PATH="$PATH:/tekton/home/.dotnet/tools"
dotnet tool install GitVersion.Tool --version 5.5.0 --tool-path "/tekton/home/.dotnet/tools"
git checkout "${PARAM_BRANCH}"
export GITVERSION=$(dotnet gitversion /showvariable FullSemVer)
echo -n "${GITVERSION}" | tee $(results.gitVersion.path)
# normalize a bit because
# image tags can only contain `abcdefghijklmnopqrstuvwxyz0123456789_-.ABCDEFGHIJKLMNOPQRSTUVWXYZ`
export PACKAGEVERSION=$(echo -n $GITVERSION | sed 's/[^-._0-9A-Za-z]/-/g')
echo -n "${PACKAGEVERSION}" | tee $(results.packageVersion.path)
workspaces:
- name: source
description: A workspace that contains the fetched git repository to create a version for.

View File

@@ -0,0 +1,162 @@
---
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: gitea-set-status
labels:
app.kubernetes.io/version: "0.1"
annotations:
tekton.dev/categories: Git
tekton.dev/pipelines.minVersion: "0.12.1"
tekton.dev/tags: gitea
tekton.dev/displayName: "set gitea status"
tekton.dev/platforms: "linux/amd64,linux/s390x,linux/ppc64le"
spec:
description: >-
This task will set the status of the CI job to the specified value along
with a link to the specified target URL where developers can follow the
progress of the CI job.
The `gitea-set-status` task allows external services to mark Gitea commits
with an `error`, `failure`, `pending`, or `success` state, which is then
reflected in pull requests involving those commits. Statuses include as well a
`description` and a `target_url`, to give the user informations about the CI
statuses or a direct link to the full log.
params:
- name: GITEA_HOST_URL
description: |
The Gitea host, e.g: git.yourcompany.com. Can include port.
type: string
- name: GITEA_HTTPS_OR_HTTP
description: |
If we should connect with HTTP or HTTPS. Use "http" or "https" here.
type: string
default: https
- name: API_PATH_PREFIX
description: |
The API path prefix of Gitea, default: /api/v1
default: "/api/v1"
type: string
- name: REPO_FULL_NAME
description: |
The Gitea repository full name, e.g.: tektoncd/catalog
type: string
- name: GITEA_TOKEN_SECRET_NAME
description: |
The name of the kubernetes secret that contains the Gitea token, default: gitea
type: string
default: gitea
- name: GITEA_TOKEN_SECRET_KEY
description: |
The key within the kubernetes secret that contains the Gitea token, default: token
type: string
default: token
- name: SHA
description: |
Commit SHA to set the status for.
type: string
- name: TARGET_URL
description: |
The target URL to associate with this status. This URL will be linked
from the Gitea UI to allow users to easily see the source of the
status.
type: string
- name: DESCRIPTION
description: |
A short description of the status.
type: string
- name: CONTEXT
description: |
The Gitea context, A string label to differentiate this status from
the status of other systems. ie: "continuous-integration/tekton"
default: "continuous-integration/tekton"
type: string
- name: STATE
description: |
The state of the status. Can be one of the following `error`,
`failure`, `pending`, `warning` or `success`.
type: string
- name: IMAGE
description: |
Image providing the python binary which this task uses.
type: string
default: python:3.10.1-alpine3.15@sha256:affe0faa14e7553fc570beec3864e74b5e36f8c19b2bb49ae8ba79c0e9e7236e
- name: SHEBANG
description: |
Python path. Depends on the image.
type: string
default: /usr/bin/env python
volumes:
- name: giteatoken
secret:
secretName: $(params.GITEA_TOKEN_SECRET_NAME)
steps:
- name: set-status
volumeMounts:
- name: giteatoken
mountPath: /etc/gitea-set-status
image: $(params.IMAGE)
script: |
#!$(params.SHEBANG)
"""This script will set the CI status on a Gitea commit"""
import json
import sys
import http.client
gitea_token = open("/etc/gitea-set-status/$(params.GITEA_TOKEN_SECRET_KEY)", "r").read()
status_url = "$(params.API_PATH_PREFIX)" + "/repos/$(params.REPO_FULL_NAME)/" + \
"statuses/$(params.SHA)"
data = {
"state": "$(params.STATE)",
"target_url": "$(params.TARGET_URL)",
"description": "$(params.DESCRIPTION)",
"context": "$(params.CONTEXT)"
}
print("Sending this data to Gitea: ")
print(data)
authHeader = "token " + gitea_token
if "$(params.GITEA_HTTPS_OR_HTTP)" == "https":
conn = http.client.HTTPSConnection("$(params.GITEA_HOST_URL)")
else:
conn = http.client.HTTPConnection("$(params.GITEA_HOST_URL)")
conn.request(
"POST",
status_url,
body=json.dumps(data),
headers={
"User-Agent": "TektonCD, the peaceful cat",
"Authorization": authHeader,
"Accept": "application/json",
"Content-Type": "application/json",
})
resp = conn.getresponse()
if not str(resp.status).startswith("2"):
print("Error: %d" % (resp.status))
print(resp.read())
sys.exit(1)
else:
print("Gitea status '$(params.STATE)' has been set on "
"$(params.REPO_FULL_NAME)#$(params.SHA) ")

View File

@@ -0,0 +1,60 @@
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
annotations:
tekton.dev/categories: Code Quality
tekton.dev/displayName: Hadolint
tekton.dev/pipelines.minVersion: 0.12.1
tekton.dev/platforms: linux/amd64
tekton.dev/tags: 'Kubernetes, Misconfiguration'
name: hadolint
labels:
app.kubernetes.io/version: '0.1'
spec:
description: >-
This task makes it possible to use Hadolint within Tekton Pipeline.
A smarter Dockerfile linter that helps you build best practice Docker
images. The linter parses the Dockerfile into an AST and performs rules on
top of the AST
params:
- default: ''
description: ignore rules.
name: ignore-rules
type: string
- default: './Dockerfile'
description: Dockerfile path.
name: dockerfile-path
type: string
- default: tty
description: >-
The output format for the results [tty | json | checkstyle | codeclimate
| gitlab_codeclimate | codacy] (default tty).
name: output-format
type: string
steps:
- image: 'ghcr.io/hadolint/hadolint:v2.8.0-debian@sha256:50b0e60aa2b4aba5a26eeb4ad08c96ed7a828fca996632e29114aabea18345f4'
name: lint-dockerfile
script: |
#!/bin/bash
set -e
if [ -n "$RULES" ]
then
IFS="," read -a RULES <<< "$RULES"
for rule in ${RULES[@]}; do ignore_rules="--ignore $rule $ignore_rules"; done
command_to_run="hadolint ${ignore_rules}"
else
command_to_run="hadolint"
fi
$command_to_run "$DOCKERFILE" -f "$OFORMAT"
env:
- name: RULES
value: "$(params.ignore-rules)"
- name: DOCKERFILE
value: "$(params.dockerfile-path)"
- name: OFORMAT
value: "$(params.output-format)"
workingDir: $(workspaces.source.path)
workspaces:
- description: A workspace that contains fetched git repo.
name: source

View File

@@ -0,0 +1,65 @@
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: kaniko
labels:
app.kubernetes.io/version: "0.6"
annotations:
tekton.dev/pipelines.minVersion: "0.17.0"
tekton.dev/categories: Image Build
tekton.dev/tags: image-build
tekton.dev/displayName: "Build and upload container image using Kaniko"
tekton.dev/platforms: "linux/amd64,linux/arm64,linux/ppc64le"
spec:
description: >-
This Task builds a simple Dockerfile with kaniko and pushes to a registry.
This Task stores the image name and digest as results, allowing Tekton Chains to pick up
that an image was built & sign it.
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.5.1)
default: gcr.io/kaniko-project/executor:v1.5.1@sha256:c6166717f7fe0b7da44908c986137ecfeab21f31ec3992f6e128fff8a94be8a5
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) # The user does not need to care the workspace and the source.
- --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)"

View File

@@ -0,0 +1,90 @@
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: kube-linter
labels:
app.kubernetes.io/version: "0.1"
annotations:
tekton.dev/pipelines.minVersion: "0.12.1"
tekton.dev/categories: Code Quality
tekton.dev/tags: Kubernetes, Misconfiguration
tekton.dev/displayName: "Kube-Linter"
tekton.dev/platforms: "linux/amd64"
spec:
description: >-
This task makes it possible to use kube-linter within Tekton Pipeline.
The KubeLinter tool by StackRox is an open-source command-line interface to identify misconfigurations in Kubernetes objects.
KubeLinter offers the ability to integrate checks on Kubernetes YAML files and Helm charts before deployment into a Kubernetes cluster.
With 31 standard built-in checks and the room to configure your own, you get immediate feedback about misconfigurations and Kubernetes security violations.
workspaces:
- name: source
description: A workspace that contains fetched git repo.
params:
- name: config_file_url
type: string
description: url from where the config file would be fetched.
default: ""
- name: config_file_path
type: string
description: path to config file.
default: ""
- name: manifest
type: string
description: path to manifest files or manifest directory to be checked.
default: "."
- name: includelist
type: string
description: "A string with comma separated checks to be included"
default: ""
- name: excludelist
type: string
description: "A string with comma separated checks to be excluded"
default: ""
- name: default_option
type: string
description: "provides two options (adding all built-in checks or disabling all default checks): add-all-built-in and/do-not-auto-add-defaults"
default: ""
- name: output_format
type: string
description: format in which report will be generated. (json|sarif|plain) (default:"json")
default: json
- name: args
type: array
description: "args"
default: []
steps:
- name: fetch-config-file
image: registry.access.redhat.com/ubi8/ubi-minimal:8.2
workingDir: $(workspaces.source.path)
script: |
#!/usr/bin/env bash
set -e
if [ -n "$(params.config_file_url)" ]
then
curl "$(params.config_file_url)" --output "$(params.config_file_path)"
echo "Fetched the config file from given ($(params.config_file_url)) URL and successfully saved at $(workspaces.source.path)/$(params.config_file_path)"
else
echo "No config file url was set"
fi
- name: lint-yaml
image: docker.io/stackrox/kube-linter:0.2.2-2-g7d10a69154-alpine@sha256:e520e9d8d3a2dfa611914836536545b135845e7bda9f1df34b060e116232dbf0
workingDir: $(workspaces.source.path)
script: |
mv ../../kube-linter ../../bin;
if [ -n "$(params.config_file_path)" ]
then
kube-linter lint "$(params.manifest)" --config "$(params.config_file_path)" --format "$(params.output_format)" "$@"
else
if [ -n "$(params.default_option)" ]
then
kube-linter lint "$(params.manifest)" --"$(params.default_option)" --include "$(params.includelist)" --exclude "$(params.excludelist)" --format "$(params.output_format)" "$@"
else
kube-linter lint "$(params.manifest)" --include "$(params.includelist)" --exclude "$(params.excludelist)" --format "$(params.output_format)" "$@"
fi
fi
args:
- $(params.args)

View File

@@ -0,0 +1,41 @@
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: kubeval
labels:
app.kubernetes.io/version: "0.1"
annotations:
tekton.dev/pipelines.minVersion: "0.12.1"
tekton.dev/categories: Code Quality, Kubernetes
tekton.dev/tags: test
tekton.dev/platforms: "linux/amd64"
spec:
description: >-
This task makes it possible to use Kubeval within your Tekton pipelines.
Kubeval is a tool used for validating Kubernetes configuration files. By
default the task will recursively scan the provided repository for YAML
files and validate them against the Kubernetes schemas.
workspaces:
- name: source
params:
- name: files
default: "."
- name: output
default: "stdout"
- name: args
type: array
default: []
steps:
- name: kubeval
workingDir: $(workspaces.source.path)
image: docker.io/garethr/kubeval:0.15.0@sha256:6962d8ecbb7839637667f66e6703e6ebaae0c29dfe93a31d9968fba4324c7b8d #tag: 0.15.0
command:
- kubeval
- -d
- $(params.files)
- -o
- $(params.output)
- $(params.args)

View File

@@ -0,0 +1,31 @@
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: markdown-lint
labels:
app.kubernetes.io/version: "0.1"
annotations:
tekton.dev/pipelines.minVersion: "0.12.1"
tekton.dev/categories: Code Quality
tekton.dev/tags: linter
tekton.dev/displayName: "Markdown linter"
tekton.dev/platforms: "linux/amd64"
spec:
description: >-
This task can be used to perform lint check on Markdown files
workspaces:
- name: shared-workspace
description: A workspace that contains the fetched git repository.
params:
- name: args
type: array
description: extra args needs to append
default: ["--help"]
steps:
- name: lint-markdown-files
image: docker.io/markdownlint/markdownlint:0.11.0@sha256:399a199c92f89f42cf3a0a1159bd86ca5cdc293fcfd39f87c0669ddee9767724 #tag: 0.11.0
workingDir: $(workspaces.shared-workspace.path)
command:
- mdl
args:
- $(params.args)

View File

@@ -0,0 +1,44 @@
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: npm
labels:
app.kubernetes.io/version: "0.1"
annotations:
tekton.dev/pipelines.minVersion: "0.17.0"
tekton.dev/categories: Build Tools
tekton.dev/tags: build-tool
tekton.dev/platforms: "linux/amd64,linux/s390x,linux/ppc64le"
spec:
description: >-
This task can be used to run npm goals on a project.
This task can be used to run npm goals on a project
where package.json is present and has some pre-defined
npm scripts.
workspaces:
- name: source
params:
- name: PATH_CONTEXT
type: string
default: "."
description: The path where package.json of the project is defined.
- name: ARGS
type: array
default: ["version"]
description: The npm goals you want to run.
- name: IMAGE
type: string
default: "docker.io/library/node:12-alpine@sha256:dfbebf17bfb014e1e7068e76325a117bccf8679c68aec6a28514184a209c8bae"
description: The node image you want to use.
steps:
- name: npm-run
image: $(params.IMAGE)
command:
- "npm"
args:
- $(params.ARGS)
workingDir: $(workspaces.source.path)/$(params.PATH_CONTEXT)
env:
- name: CI
value: "true"

View File

@@ -0,0 +1,62 @@
---
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: prometheus-gate
labels:
app.kubernetes.io/version: "0.1"
annotations:
tekton.dev/categories: Monitoring
tekton.dev/pipelines.minVersion: "0.12.1"
tekton.dev/tags: gate, prometheus
tekton.dev/displayName: prometheus gate
tekton.dev/platforms: "linux/amd64"
spec:
description: >-
A gate task which will query the prometheus API in a loop and await a matching status for N length of time.
params:
- name: prometheus_endpoint
type: string
description: Prometheus API endpoint
- name: range_query
type: string
description: range query to use to define SLO
- name: range_time
type: string
description: time we want to assert fits the SLO
default: "-10m"
- name: target_value
type: string
description: value we will use as threshold
default: "1"
- name: target_strategy
type: string
description: The target_strategy is min,max or equal
default: "min"
- name: timeout
type: string
description: timeout of the gate
default: "3600"
- name: tick_time
type: string
description: how often to draw data from prometheus
default: "1m"
steps:
- name: gate
image: docker.io/iancoffey/prometheus-gate-cf7c3e662ede0a4e9bc24d37d2af86d6@sha256:c3df9d8400aef7acb76f409d1e347c5ecaa6f28a69df50981c14bfe87add85d7
env:
- name: "PROMETHEUS_ENDPOINT"
value: $(params.prometheus_endpoint)
- name: "RANGE_QUERY"
value: $(params.range_query)
- name: "RANGE_TIME"
value: $(params.range_time)
- name: "TARGET_VALUE"
value: $(params.target_value)
- name: "TARGET_STRATEGY"
value: $(params.target_strategy)
- name: "TIMEOUT"
value: $(params.timeout)
- name: "TICK_TIME"
value: $(params.tick_time)

View File

@@ -0,0 +1,66 @@
---
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: pylint
labels:
app.kubernetes.io/version: "0.3"
annotations:
tekton.dev/categories: Code Quality
tekton.dev/pipelines.minVersion: "0.17.0"
tekton.dev/tags: python, pylint
tekton.dev/displayName: pylint
tekton.dev/platforms: "linux/amd64"
spec:
description: >-
This task will run pylint on the provided input.
workspaces:
- name: source
- description: The workspace consisting of the custom pip settings.
name: pip-conf
optional: true
params:
- name: image
description: The container image with pylint
default: registry.gitlab.com/pipeline-components/pylint:0.12.0@sha256:051b701936dfab6fa27bd1ebd50ef56b19577565661bc0227e50dd1cf94a3d6e
- name: path
description: The path to the module which should be analysed by pylint
default: "."
type: string
- name: requirements_file
description: The name of the requirements file inside the source location
default: "requirements.txt"
- name: args
description: The arguments to pass to the pylint CLI.
type: array
default: []
- name: pip_conf_file
description: The name of the custom pip config file.
default: "pip.conf"
steps:
- name: pylint
image: $(params.image)
workingDir: $(workspaces.source.path)
env:
- name: HOME
value: /tmp/python
- name: PARAM_PIP_CONF_FILE
value: $(params.pip_conf_file)
- name: WORKSPACE_PIP_CONF_BOUND
value: $(workspaces.pip-conf.bound)
- name: WORKSPACE_PIP_CONF_PATH
value: $(workspaces.pip-conf.path)
script: |
export PATH=$PATH:$HOME/.local/bin
if [ "${WORKSPACE_PIP_CONF_BOUND}" = "true" ] ; then
export PIP_CONFIG_FILE="${WORKSPACE_PIP_CONF_PATH}/${PARAM_PIP_CONF_FILE}"
fi
if [ -n "$(params.requirements_file)" ] && [ -e "$(params.requirements_file)" ];then
python -mpip install --user -r "$(params.requirements_file)"
fi
pylint $@ "$(params.path)"
args:
- "$(params.args)"

View File

@@ -0,0 +1,77 @@
---
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: pytest
labels:
app.kubernetes.io/version: "0.2"
annotations:
tekton.dev/categories: Testing
tekton.dev/pipelines.minVersion: "0.17.0"
tekton.dev/tags: python, pytest
tekton.dev/displayName: pytest
tekton.dev/platforms: "linux/amd64,linux/s390x,linux/ppc64le"
spec:
description: >-
This task will run pytest on the provided input.
workspaces:
- name: source
- description: The workspace consisting of the custom pip settings.
name: pip-conf
optional: true
params:
- name: PYTHON_IMAGE
description: The used Python image
type: string
default: "docker.io/python:3.11.1-bullseye"
- name: ARGS
description: The additional arguments to be used with pytest
type: string
default: ""
- name: SOURCE_PATH
description: The path to the source code
default: "."
- name: REQUIREMENTS_FILE
description: The name of the requirements file inside the source location, with fallback to the requirements file in the root location
default: "requirements.txt"
- name: PIP_CONF_FILE
description: The name of the custom pip config file.
default: "pip.conf"
steps:
- name: unit-test
image: $(params.PYTHON_IMAGE)
workingDir: $(workspaces.source.path)
env:
- name: PARAM_PIP_CONF_FILE
value: $(params.PIP_CONF_FILE)
- name: WORKSPACE_PIP_CONF_BOUND
value: $(workspaces.pip-conf.bound)
- name: WORKSPACE_PIP_CONF_PATH
value: $(workspaces.pip-conf.path)
script: |
export PATH=$PATH:$HOME/.local/bin
if [ "${WORKSPACE_PIP_CONF_BOUND}" = "true" ] ; then
export PIP_CONFIG_FILE="${WORKSPACE_PIP_CONF_PATH}/${PARAM_PIP_CONF_FILE}"
fi
if [ -e "$(params.SOURCE_PATH)"/"$(params.REQUIREMENTS_FILE)" ];
then
pip install -r "$(params.SOURCE_PATH)"/"$(params.REQUIREMENTS_FILE)"
pip show pytest || {
printf "###\nWarning: Pytest is missing in your test requirements file\n###";
pip install pytest
}
else
if [ -e "$(params.REQUIREMENTS_FILE)" ];
then
pip install -r "$(params.REQUIREMENTS_FILE)"
fi
pip install pytest
fi
if [ -z "$(params.ARGS)" ]; then
pytest "$(params.SOURCE_PATH)"
else
pytest "$(params.ARGS)" "$(params.SOURCE_PATH)"
fi

View File

@@ -0,0 +1,55 @@
---
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: python-coverage
labels:
app.kubernetes.io/version: "0.1"
annotations:
tekton.dev/categories: Code Quality
tekton.dev/pipelines.minVersion: "0.12.1"
tekton.dev/tags: python, coverage
tekton.dev/displayName: python coverage
tekton.dev/platforms: "linux/amd64,linux/s390x,linux/ppc64le"
spec:
description: >-
This task can be used to measure code coverage of Python projects.
workspaces:
- name: source
params:
- name: PYTHON
description: The used Python version, more precisely the tag for the Python image
type: string
default: "latest"
- name: ARGS
description: The additional arguments to be used with pytest
type: string
default: ""
- name: SOURCE_PATH
description: The path to the source code
default: "."
- name: REQUIREMENTS_FILE
description: The name of the requirements file inside the source location
default: "requirements.txt"
steps:
- name: code-coverage
image: docker.io/python:$(inputs.params.PYTHON)
workingDir: $(workspaces.source.path)
script: |
export PATH=$PATH:$HOME/.local/bin
if [ -n "$(inputs.params.REQUIREMENTS_FILE)" ] && [ -e "$(inputs.params.REQUIREMENTS_FILE)" ];then
pip install -r $(inputs.params.SOURCE_PATH)/$(inputs.params.REQUIREMENTS_FILE)
pip show pytest || {
echo "###\nWarning: Pytest is missing in your requirements\n###";
pip install pytest
}
pip show coverage || {
echo "###\nWarning: Coverage is missing in your requirements\n###";
pip install coverage
}
else
pip install pytest coverage
fi
coverage run -m pytest $(inputs.params.ARGS) $(inputs.params.SOURCE_PATH)
coverage report -m

View File

@@ -0,0 +1,31 @@
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: shellcheck
labels:
app.kubernetes.io/version: "0.1"
annotations:
tekton.dev/pipelines.minVersion: "0.12.1"
tekton.dev/categories: Code Quality
tekton.dev/tags: linter
tekton.dev/displayName: "Shellcheck"
tekton.dev/platforms: "linux/amd64"
spec:
description: >-
This task can be used to perform lint check on Shell Script files
workspaces:
- name: shared-workspace
description: A workspace that contains the fetched git repository.
params:
- name: args
type: array
description: extra args needs to append
default: ["--help"]
steps:
- name: lint-shell
image: docker.io/koalaman/shellcheck:v0.7.1@sha256:ad95c140f7bf5cc66e50e19da7d72c398583ba24c5866ac32c882eb3ddc153ee #tag: v0.7.1
workingDir: $(workspaces.shared-workspace.path)
command:
- /bin/shellcheck
args:
- $(params.args)

View File

@@ -0,0 +1,79 @@
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: skopeo-copy
labels:
app.kubernetes.io/version: "0.3"
annotations:
tekton.dev/pipelines.minVersion: "0.12.1"
tekton.dev/categories: CLI
tekton.dev/tags: cli
tekton.dev/displayName: "skopeo copy"
tekton.dev/platforms: "linux/amd64,linux/s390x,linux/ppc64le,linux/arm64"
spec:
description: >-
Skopeo is a command line tool for working with remote image registries.
Skopeo doesnt require a daemon to be running while performing its operations.
In particular, the handy skopeo command called copy will ease the whole image
copy operation. The copy command will take care of copying the image from
internal.registry to production.registry. If your production registry requires
credentials to login in order to push the image, skopeo can handle that as well.
workspaces:
- name: images-url
params:
- name: srcImageURL
description: URL of the image to be copied to the destination registry
type: string
default: ""
- name: destImageURL
description: URL of the image where the image from source should be copied to
type: string
default: ""
- name: srcTLSverify
description: Verify the TLS on the src registry endpoint
type: string
default: "true"
- name: destTLSverify
description: Verify the TLS on the dest registry endpoint
type: string
default: "true"
steps:
- name: skopeo-copy
env:
- name: HOME
value: /tekton/home
image: quay.io/skopeo/stable:v1
script: |
# Function to copy multiple images.
#
copyimages() {
filename="$(workspaces.images-url.path)/url.txt"
while IFS= read -r line || [ -n "$line" ]
do
cmd=""
for url in $line
do
# echo $url
cmd="$cmd \
$url"
done
read -ra sourceDest <<<"${cmd}"
skopeo copy "${sourceDest[@]}" --src-tls-verify="$(params.srcTLSverify)" --dest-tls-verify="$(params.destTLSverify)"
echo "$cmd"
done < "$filename"
}
#
# If single image is to be copied then, it can be passed through
# params in the taskrun.
if [ "$(params.srcImageURL)" != "" ] && [ "$(params.destImageURL)" != "" ] ; then
skopeo copy "$(params.srcImageURL)" "$(params.destImageURL)" --src-tls-verify="$(params.srcTLSverify)" --dest-tls-verify="$(params.destTLSverify)"
else
# If file is provided as a configmap in the workspace then multiple images can be copied.
#
copyimages
fi
securityContext:
runAsNonRoot: true
runAsUser: 65532

View File

@@ -0,0 +1,158 @@
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: sonarqube-scanner
labels:
app.kubernetes.io/version: "0.4"
annotations:
tekton.dev/deprecated: "true"
tekton.dev/pipelines.minVersion: "0.17.0"
tekton.dev/categories: Security
tekton.dev/tags: security
tekton.dev/displayName: "sonarqube scanner"
tekton.dev/platforms: "linux/amd64"
spec:
description: >-
The following task can be used to perform static analysis on the source code
provided the SonarQube server is hosted
SonarQube is the leading tool for continuously inspecting the Code Quality and Security
of your codebases, all while empowering development teams. Analyze over 25 popular
programming languages including C#, VB.Net, JavaScript, TypeScript and C++. It detects
bugs, vulnerabilities and code smells across project branches and pull requests.
workspaces:
- name: source
description: "Workspace containing the code which needs to be scanned by SonarQube"
- name: sonar-settings
description: "Optional workspace where SonarQube properties can be mounted"
optional: true
- name: sonar-credentials
description: |
A workspace containing a login or password for use within sonarqube.
optional: true
params:
- name: SONAR_HOST_URL
description: SonarQube server URL
default: ""
- name: SONAR_PROJECT_KEY
description: Project's unique key
default: ""
- name: PROJECT_VERSION
description: "Version of the project. Default: 1.0"
default: "1.0"
- name: SOURCE_TO_SCAN
description: "Comma-separated paths to directories containing main source files"
default: "."
- name: SONAR_ORGANIZATION
description: "The organization in sonarqube where the project exists"
default: ""
- name: SONAR_SCANNER_IMAGE
description: "The sonarqube scanner CLI image which will run the scan"
default: "docker.io/sonarsource/sonar-scanner-cli:4.6@sha256:7a976330a8bad1beca6584c1c118e946e7a25fdc5b664d5c0a869a6577d81b4f"
- name: SONAR_LOGIN_KEY
description: Name of the file of the login within the sonarqube credentials workspace
default: "login"
- name: SONAR_PASSWORD_KEY
description: Name of the file of the password within the sonarqube credentials workspace
default: "password"
steps:
- name: sonar-properties-create
image: registry.access.redhat.com/ubi8/ubi-minimal:8.2
workingDir: $(workspaces.source.path)
env:
- name: SONAR_HOST_URL
value: $(params.SONAR_HOST_URL)
- name: SONAR_PROJECT_KEY
value: $(params.SONAR_PROJECT_KEY)
- name: PROJECT_VERSION
value: $(params.PROJECT_VERSION)
- name: SOURCE_TO_SCAN
value: $(params.SOURCE_TO_SCAN)
- name: SONAR_ORGANIZATION
value: $(params.SONAR_ORGANIZATION)
script: |
#!/usr/bin/env bash
replaceValues() {
filename=$1
thekey=$2
newvalue=$3
if ! grep -R "^[#]*\s*${thekey}=.*" $filename >/dev/null; then
echo "APPENDING because '${thekey}' not found"
echo "" >>$filename
echo "$thekey=$newvalue" >>$filename
else
echo "SETTING because '${thekey}' found already"
sed -ir "s|^[#]*\s*${thekey}=.*|$thekey=$newvalue|" $filename
fi
}
if [[ "$(workspaces.sonar-settings.bound)" == "true" ]]; then
if [[ -f $(workspaces.sonar-settings.path)/sonar-project.properties ]]; then
echo "using user provided sonar-project.properties file"
cp -RL $(workspaces.sonar-settings.path)/sonar-project.properties $(workspaces.source.path)/sonar-project.properties
fi
fi
if [[ -f $(workspaces.source.path)/sonar-project.properties ]]; then
if [[ -n "${SONAR_HOST_URL}" ]]; then
echo "replacing sonar host URL"
replaceValues $(workspaces.source.path)/sonar-project.properties sonar.host.url "${SONAR_HOST_URL}"
fi
if [[ -n "${SONAR_PROJECT_KEY}" ]]; then
echo "replacing sonar project key"
replaceValues $(workspaces.source.path)/sonar-project.properties sonar.projectKey "${SONAR_PROJECT_KEY}"
fi
echo "Values in sonar-project.properties file replaced successfully..."
else
echo "Creating sonar-project.properties file..."
touch sonar-project.properties
[[ -n "${SONAR_PROJECT_KEY}" ]] && {
echo "sonar.projectKey=${SONAR_PROJECT_KEY}" >> sonar-project.properties
} || {
echo "missing property SONAR_PROJECT_KEY"
exit 1
}
[[ -n "${SONAR_HOST_URL}" ]] && {
echo "sonar.host.url=${SONAR_HOST_URL}" >> sonar-project.properties
} || {
echo "missing property SONAR_HOST_URL"
exit 1
}
[[ -n "${PROJECT_VERSION}" ]] && {
echo "sonar.projectVersion=${PROJECT_VERSION}" >> sonar-project.properties
} || {
echo "missing property PROJECT_VERSION"
exit 1
}
[[ -n "${SONAR_ORGANIZATION}" ]] && {
echo "sonar.organization=${SONAR_ORGANIZATION}" >> sonar-project.properties
} || {
echo "missing property SONAR_ORGANIZATION"
exit 1
}
echo "sonar.sources=${SOURCE_TO_SCAN}" >> sonar-project.properties
echo "---------------------------"
cat $(workspaces.source.path)/sonar-project.properties
fi
if [[ "$(workspaces.sonar-credentials.bound)" == "true" ]]; then
if [[ -f $(workspaces.sonar-credentials.path)/$(params.SONAR_PASSWORD_KEY) ]]; then
SONAR_PASSWORD=`cat $(workspaces.sonar-credentials.path)/$(params.SONAR_PASSWORD_KEY)`
replaceValues $(workspaces.source.path)/sonar-project.properties sonar.password "${SONAR_PASSWORD}"
fi
if [[ -f $(workspaces.sonar-credentials.path)/$(params.SONAR_LOGIN_KEY) ]]; then
SONAR_LOGIN=`cat $(workspaces.sonar-credentials.path)/$(params.SONAR_LOGIN_KEY)`
replaceValues $(workspaces.source.path)/sonar-project.properties sonar.login "${SONAR_LOGIN}"
fi
fi
- name: sonar-scan
image: $(params.SONAR_SCANNER_IMAGE)
workingDir: $(workspaces.source.path)
command:
- sonar-scanner

View File

@@ -0,0 +1,31 @@
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: ts-lint
labels:
app.kubernetes.io/version: "0.1"
annotations:
tekton.dev/pipelines.minVersion: "0.12.1"
tekton.dev/categories: Code Quality
tekton.dev/tags: linter
tekton.dev/displayName: "TypeScript linter"
tekton.dev/platforms: "linux/amd64"
spec:
description: >-
This task can be used to perform lint check on TypeScript files
workspaces:
- name: shared-workspace
description: A workspace that contains the fetched git repository.
params:
- name: args
type: array
description: extra args needs to append
default: ["--help"]
steps:
- name: lint-typescript
image: docker.io/pipelinecomponents/tslint:0.14.1@sha256:85c7dd3f2b6d411fd01b8ad489afd20fb6ac4b2560f29ca506782c1f1a8d9b45 #tag: 0.14.1
workingDir: $(workspaces.shared-workspace.path)
command:
- tslint
args:
- $(params.args)

View File

@@ -0,0 +1,57 @@
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: write-file
labels:
app.kubernetes.io/version: "0.1"
annotations:
tekton.dev/pipelines.minVersion: "0.12.1"
tekton.dev/categories: Developer Tools
tekton.dev/tags: generic
tekton.dev/displayName: Write a file
tekton.dev/platforms: "linux/amd64,linux/s390x,linux/ppc64le"
spec:
description: >-
Write a file to a workspace
This task can be used to write a file onto the output workspace.
Use parameter expansion to insert variable content into the written
file. It can also set specific permissions on the file.
params:
- name: path
type: string
description: >
Relative path to create within the workspace. Directories will
be created as necessary.
- name: contents
type: string
description: >
Contents of the file to create.
- name: mode
type: string
default: "0755"
description: >
chmod-style permission string to apply to the file. Note that
octal numbers need quoting in YAML. Mode will not be applied
to created directories.
workspaces:
- name: output
description: Workspace onto which the file is written.
steps:
- name: write-file
image: docker.io/library/alpine:3.12@sha256:36553b10a4947067b9fbb7d532951066293a68eae893beba1d9235f7d11a20ad
workingDir: $(workspaces.output.path)
env:
- name: PARAM_PATH
value: $(params.path)
- name: PARAM_MODE
value: $(params.mode)
- name: PARAM_CONTENTS
value: $(params.contents)
script: |
#!/bin/sh
set -eu
DIRNAME=$(dirname "${PARAM_PATH}")
mkdir -p "$DIRNAME"
printf '%s' "${PARAM_CONTENTS}" > "./${PARAM_PATH}"
chmod "${PARAM_MODE}" "./${PARAM_PATH}"

View File

@@ -0,0 +1,31 @@
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: yaml-lint
labels:
app.kubernetes.io/version: "0.1"
annotations:
tekton.dev/pipelines.minVersion: "0.12.1"
tekton.dev/categories: Code Quality
tekton.dev/tags: linter
tekton.dev/displayName: "YAML linter"
tekton.dev/platforms: "linux/amd64"
spec:
description: >-
This task can be used to perform lint check on YAML files
workspaces:
- name: shared-workspace
description: A workspace that contains the fetched git repository.
params:
- name: args
type: array
description: extra args needs to append
default: ["--help"]
steps:
- name: lint-yaml-files
image: docker.io/cytopia/yamllint:1.23@sha256:e9deea51bbdc35950cacf6594dab94100d9bbf5c987540b8874167d58e6bdce2 #tag: 1.23
workingDir: $(workspaces.shared-workspace.path)
command:
- yamllint
args:
- $(params.args)

View File

@@ -0,0 +1,57 @@
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: yq
labels:
app.kubernetes.io/version: "0.4"
annotations:
tekton.dev/pipelines.minVersion: "0.12.1"
tekton.dev/categories: Developer Tools
tekton.dev/tags: yq
tekton.dev/displayName: "YQ"
tekton.dev/platforms: "linux/amd64"
spec:
description: >-
This task can be used to replace fields in YAML files. For example for altering helm charts on GitOps repos.
workspaces:
- name: source
description: A workspace that contains the file which needs to be altered.
params:
- name: SCRIPT
type: string
description: The yq script to execute. Can be multiple lines for complex tasks.
default: ""
- name: image
type: string
description: The yq image to use.
default: docker.io/mikefarah/yq:4.27.5@sha256:2be3626ed633fbe1fc33ee9343a1256a6be53334412b2251b9a859f8c145bb53
- name: files
type: array
description: (deprecated, use SCRIPT instead) A list of files to execute the expression on. Needs to be relative to the source workspace.
default: []
- name: expression
type: string
description: (deprecated, use SCRIPT instead) The yq expression to apply. Can be used to replace yaml fields.
default: ""
results:
- name: yq
description: The result from your yq command. You can write to it using `$(results.yq.path)`
steps:
- name: yq-script
image: $(params.image)
workingDir: $(workspaces.source.path)
args: ["$(params.files[*])"]
script: |
/usr/bin/env sh
set -e
# For backwards compatibility with previous versions
if [ "$(params.SCRIPT)" = "" ]; then
for var in "$@"
do
/usr/bin/yq eval -i "$(params.expression)" "$var"
done
exit $?
fi
$(params.SCRIPT)

View File

@@ -0,0 +1,66 @@
resource "kubernetes_namespace_v1" "ns-tekton" {
count = var.haveGitea && var.haveTekton?1:0
metadata {
annotations = local.annotations
labels = merge(local.common-labels, local.annotations)
name = "${var.domain}-ci-${var.instance}"
}
}
resource "kubectl_manifest" "tekton" {
count = var.haveGitea && var.haveTekton?1:0
depends_on = [kubernetes_namespace_v1.ns-tekton]
yaml_body = <<-EOF
apiVersion: "vynil.solidite.fr/v1"
kind: "Install"
metadata:
name: "tekton-base"
namespace: "${var.domain}-ci-${var.instance}"
labels: ${jsonencode(local.common-labels)}
spec:
distrib: "${var.distributions.domain}"
category: "share"
component: "gitea-tekton-org"
options:
domain: "${var.domain}"
organization: "${trimprefix(var.instance,"org-")}"
EOF
}
resource "kubectl_manifest" "ci-ssh-creds" {
depends_on = [kubernetes_namespace_v1.ns-tekton]
count = var.haveGitea && var.haveTekton?1:0
yaml_body = <<-EOF
apiVersion: "secretgenerator.mittwald.de/v1alpha1"
kind: "SSHKeyPair"
metadata:
name: "ssh-credentials"
namespace: "${var.domain}-ci-${var.instance}"
labels: ${jsonencode(local.common-labels)}
spec:
length: "2048"
forceRegenerate: false
data:
known_hosts: "${data.local_file.known_host[0].content}"
EOF
lifecycle {
ignore_changes = [
yaml_body,
]
}
}
data "kubernetes_secret_v1" "ci-ssh-creds-read" {
depends_on = [kubectl_manifest.ci-ssh-creds]
count = var.haveGitea && var.haveTekton?1:0
metadata {
name = "ssh-credentials"
namespace = "${var.domain}-ci-${var.instance}"
}
}
resource "gitea_public_key" "user-ci-keys" {
count = var.haveGitea && var.haveTekton?1:0
title = "Tekton token to read repository ${var.instance}"
username = gitea_user.user-ci[0].username
key = data.kubernetes_secret_v1.ci-ssh-creds-read[count.index].data["ssh-publickey"]
}

View File

@@ -1,5 +1,6 @@
locals {
needUser = length(local.sorted-stages)>0 && var.haveGitea
needKnownHost = var.haveGitea && (length(local.sorted-stages)>0 || var.haveTekton)
needDeploy = var.haveGitea && length(local.sorted-stages)>0
gitea_host = "http://gitea-http.${var.domain}-ci.svc:3000/"
gitea_username = data.kubernetes_secret_v1.gitea.data["username"]
gitea_password = data.kubernetes_secret_v1.gitea.data["password"]
@@ -27,7 +28,7 @@ data "kubernetes_service" "gitea-ssh" {
}
resource "null_resource" "get_known" {
count = local.needUser?1:0
count = local.needKnownHost?1:0
triggers = { always_run = "${timestamp()}" }
provisioner "local-exec" {
command = "ssh-keyscan -p ${data.kubernetes_service.gitea-ssh.spec.0.port.0.port} ${var.gitea-ssh-domain!=""?var.gitea-ssh-domain:data.kubernetes_ingress_v1.gitea.spec[0].rule[0].host} > ${path.module}/known_host.txt"
@@ -35,14 +36,14 @@ resource "null_resource" "get_known" {
}
data "local_file" "known_host" {
count = local.needUser?1:0
count = local.needKnownHost?1:0
filename = "${path.module}/known_host.txt"
depends_on = [null_resource.get_known]
}
resource "kubectl_manifest" "ssh-creds" {
depends_on = [kubernetes_namespace_v1.ns]
count = local.needUser?length(local.sorted-stages):0
count = var.haveGitea?length(local.sorted-stages):0
yaml_body = <<-EOF
apiVersion: "secretgenerator.mittwald.de/v1alpha1"
kind: "SSHKeyPair"
@@ -65,7 +66,7 @@ resource "kubectl_manifest" "ssh-creds" {
data "kubernetes_secret_v1" "ssh-creds-read" {
depends_on = [kubectl_manifest.ssh-creds]
count = local.needUser?length(local.sorted-stages):0
count = var.haveGitea?length(local.sorted-stages):0
metadata {
name = "ssh-credentials"
namespace = "${local.sorted-stages[count.index].namespace}"
@@ -79,7 +80,7 @@ resource "random_password" "password" {
}
resource "gitea_user" "user-ci" {
count = local.needUser?1:0
count = local.needKnownHost?1:0
username = "${var.instance}-ci"
login_name = "${var.instance}-ci"
password = random_password.password.result
@@ -88,7 +89,7 @@ resource "gitea_user" "user-ci" {
}
resource "gitea_public_key" "user-ci-keys" {
count = local.needUser?length(local.sorted-stages):0
count = var.haveGitea?length(local.sorted-stages):0
title = "Stage ${local.sorted-stages[count.index].name} for organisation ${var.instance}"
username = gitea_user.user-ci[0].username
key = data.kubernetes_secret_v1.ssh-creds-read[count.index].data["ssh-publickey"]
@@ -100,23 +101,32 @@ resource "gitea_org" "orga" {
}
resource "gitea_repository" "deploy" {
count = local.needUser?1:0
count = local.needDeploy?1:0
username = gitea_org.orga[0].name
name = "deploy"
private = true
}
resource "gitea_team" "ci-team" {
count = local.needUser?1:0
name = "Automation"
resource "gitea_team" "cd-team" {
count = local.needDeploy?1:0
name = "Deployment"
organisation = gitea_org.orga[0].name
description = "Automation"
description = "Deployment"
permission = "write"
members = [gitea_user.user-ci[0].username]
include_all_repositories = false
repositories = [gitea_repository.deploy[0].name]
}
resource "gitea_team" "ci-team" {
count = local.needKnownHost?1:0
name = "Automation"
organisation = gitea_org.orga[0].name
description = "Automation"
permission = "read"
members = [gitea_user.user-ci[0].username]
}
resource "gitea_team" "dev-team" {
count = var.haveGitea?1:0
name = "Devs"

View File

@@ -88,6 +88,11 @@ options:
examples:
- false
type: boolean
haveTekton:
default: false
examples:
- false
type: boolean
ingress_class:
default: traefik
examples: