9 Commits

Author SHA1 Message Date
fe652d335c chore(ci): remove workflow_dispatch
All checks were successful
Lint Shell files / shellcheck (pull_request) Successful in 25s
check-and-test / check-and-test (pull_request) Successful in 46s
2025-03-31 22:08:00 +02:00
bd3afb64c4 chore(ci): update apt packages and proceed installation non-interactively
All checks were successful
Lint Shell files / shellcheck (pull_request) Successful in 25s
check-and-test / check-and-test (pull_request) Successful in 47s
2025-03-31 18:31:15 +02:00
421f3fcbc5 chore(ci): change types to oopened, reopened and synchronize
Some checks failed
Lint Shell files / shellcheck (pull_request) Failing after 9s
check-and-test / check-and-test (pull_request) Successful in 47s
2025-03-31 18:28:32 +02:00
891538554c style(ci): lint action
All checks were successful
check-and-test / check-and-test (pull_request) Successful in 47s
2025-03-31 18:24:30 +02:00
f757aff455 fix(Makefile): add new target 'yamllint' 2025-03-31 18:23:54 +02:00
ba7770fdbd style(editorconfig): set indent style to tab for Makefiles 2025-03-31 18:23:37 +02:00
6e9230d722 style(ci): remove obsolete spaces
Some checks failed
check-and-test / check-and-test (pull_request) Failing after 48s
2025-03-31 18:18:59 +02:00
d72d43a51f fix(scripts): shellcheck: SC2181
Some checks failed
check-and-test / check-and-test (pull_request) Failing after 46s
2025-03-31 18:15:59 +02:00
b569e49893 chore(ci): add shellcheck 2025-03-31 18:15:28 +02:00
22 changed files with 759 additions and 87 deletions

View File

@ -1 +0,0 @@
* @rossigee @volker.raschek @ChristopherHX

View File

@ -13,18 +13,7 @@ keywords:
sources: sources:
- https://gitea.com/gitea/helm-actions - https://gitea.com/gitea/helm-actions
- https://gitea.com/gitea/act - https://gitea.com/gitea/act
# FIXME:
maintainers: # maintainers:
# https://gitea.com/DaanSelen
- name: Daan Selen
email: dselen@nerthus.nl
# https://gitea.com/volker.raschek
- name: Markus Pesch
email: markus.pesch+apps@cryptic.systems
# https://gitea.com/ChristopherHX
- name: Christopher Homberger
email: christopher.homberger@web.de
dependencies: [] dependencies: []

View File

@ -1,10 +1,4 @@
# Gitea Actions Helm Chart # helm-act
This helm chart serves as the way to deploy the Gitea [act-runners](https://gitea.com/gitea/act_runner) alongside a running Gitea instance.
It serves as a standalone chart and does not rely on Gitea to be present in the same environment, however it needs to be able to reach a Gitea instance to function.
The parameters which can be used to customize the deployment are described below, check those out if you want to see if something is supported.
If you want to propose a new feature or mechanism, submit an [issue here](https://gitea.com/gitea/helm-actions/issues).
## Rootless Defaults ## Rootless Defaults
@ -21,7 +15,6 @@ If `.Values.image.rootless: true`, then the following will occur. In case you us
| `enabled` | Create an act runner StatefulSet. | `false` | | `enabled` | Create an act runner StatefulSet. | `false` |
| `init.image.repository` | The image used for the init containers | `busybox` | | `init.image.repository` | The image used for the init containers | `busybox` |
| `init.image.tag` | The image tag used for the init containers | `1.37.0` | | `init.image.tag` | The image tag used for the init containers | `1.37.0` |
| `statefulset.replicas` | the amount of (replica) runner pods deployed | `1` |
| `statefulset.annotations` | Act runner annotations | `{}` | | `statefulset.annotations` | Act runner annotations | `{}` |
| `statefulset.labels` | Act runner labels | `{}` | | `statefulset.labels` | Act runner labels | `{}` |
| `statefulset.resources` | Act runner resources | `{}` | | `statefulset.resources` | Act runner resources | `{}` |
@ -39,11 +32,49 @@ If `.Values.image.rootless: true`, then the following will occur. In case you us
| `statefulset.dind.pullPolicy` | The Docker-in-Docker pullPolicy | `IfNotPresent` | | `statefulset.dind.pullPolicy` | The Docker-in-Docker pullPolicy | `IfNotPresent` |
| `statefulset.dind.extraVolumeMounts` | Allows mounting extra volumes in the Docker-in-Docker container | `[]` | | `statefulset.dind.extraVolumeMounts` | Allows mounting extra volumes in the Docker-in-Docker container | `[]` |
| `statefulset.dind.extraEnvs` | Allows adding custom environment variables, such as `DOCKER_IPTABLES_LEGACY` | `[]` | | `statefulset.dind.extraEnvs` | Allows adding custom environment variables, such as `DOCKER_IPTABLES_LEGACY` | `[]` |
| `statefulset.persistence.size` | Size for persistence to store act runner data | `1Gi` | | `provisioning.enabled` | Create a job that will create and save the token in a Kubernetes Secret | `false` |
| `provisioning.annotations` | Job's annotations | `{}` |
| `provisioning.labels` | Job's labels | `{}` |
| `provisioning.resources` | Job's resources | `{}` |
| `provisioning.nodeSelector` | NodeSelector for the job | `{}` |
| `provisioning.tolerations` | Tolerations for the job | `[]` |
| `provisioning.affinity` | Affinity for the job | `{}` |
| `provisioning.ttlSecondsAfterFinished` | ttl for the job after finished in order to allow helm to properly recognize that the job completed | `300` |
| `provisioning.publish.repository` | The image that can create the secret via kubectl | `bitnami/kubectl` |
| `provisioning.publish.tag` | The publish image tag that can create the secret | `1.29.0` |
| `provisioning.publish.pullPolicy` | The publish image pullPolicy that can create the secret | `IfNotPresent` |
| `existingSecret` | Secret that contains the token | `""` | | `existingSecret` | Secret that contains the token | `""` |
| `existingSecretKey` | Secret key | `""` | | `existingSecretKey` | Secret key | `""` |
| `giteaRootURL` | URL the act_runner registers and connect with | `""` | | `giteaRootURL` | URL the act_runner registers and connect with | `""` |
### Persistence
| Name | Description | Value |
| ------------------------------------------------- | ------------------------------------------------------------------------- | ---------------------- |
| `persistence.enabled` | Enable persistent storage | `true` |
| `persistence.create` | Whether to create the persistentVolumeClaim for shared storage | `true` |
| `persistence.mount` | Whether the persistentVolumeClaim should be mounted (even if not created) | `true` |
| `persistence.claimName` | Use an existing claim to store repository information | `gitea-shared-storage` |
| `persistence.size` | Size for persistence to store repo information | `10Gi` |
| `persistence.accessModes` | AccessMode for persistence | `["ReadWriteOnce"]` |
| `persistence.labels` | Labels for the persistence volume claim to be created | `{}` |
| `persistence.annotations.helm.sh/resource-policy` | Resource policy for the persistence volume claim | `keep` |
| `persistence.storageClass` | Name of the storage class to use | `nil` |
| `persistence.subPath` | Subdirectory of the volume to mount at | `nil` |
| `persistence.volumeName` | Name of persistent volume in PVC | `""` |
### Image
| Name | Description | Value |
| -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ |
| `image.registry` | image registry, e.g. gcr.io,docker.io | `docker.gitea.com` |
| `image.repository` | Image to start for this pod | `gitea` |
| `image.tag` | Visit: [Image tag](https://hub.docker.com/r/gitea/gitea/tags?page=1&ordering=last_updated). Defaults to `appVersion` within Chart.yaml. | `""` |
| `image.digest` | Image digest. Allows to pin the given image tag. Useful for having control over mutable tags like `latest` | `""` |
| `image.pullPolicy` | Image pull policy | `IfNotPresent` |
| `image.rootless` | Wether or not to pull the rootless version of Gitea, only works on Gitea 1.14.x or higher | `true` |
| `image.fullOverride` | Completely overrides the image registry, path/image, tag and digest. **Adjust `image.rootless` accordingly and review [Rootless defaults](#rootless-defaults).** | `""` |
### Global ### Global
| Name | Description | Value | | Name | Description | Value |

View File

@ -1,6 +1,15 @@
{{- if .Values.enabled -}} {{- if .Values.enabled -}}
{{- if .Values.provisioning.enabled -}}
{{- if or (empty .Values.existingSecret) (empty .Values.existingSecretKey) -}} {{- if not (and .Values.persistence.enabled .Values.persistence.mount) -}}
{{- fail "persistence.enabled and persistence.mount are required when provisioning is enabled" -}}
{{- end -}}
{{- if and .Values.persistence.enabled .Values.persistence.mount -}}
{{- if .Values.existingSecret -}}
{{- fail "Can't specify both actions.provisioning.enabled and actions.existingSecret" -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- if and (not .Values.provisioning.enabled) (or (empty .Values.existingSecret) (empty .Values.existingSecretKey)) -}}
{{- fail "existingSecret and existingSecretKey are required when provisioning is disabled" -}} {{- fail "existingSecret and existingSecretKey are required when provisioning is disabled" -}}
{{- end -}} {{- end -}}
{{- if not .Values.giteaRootURL -}} {{- if not .Values.giteaRootURL -}}

View File

@ -3,7 +3,7 @@
Expand the name of the chart. Expand the name of the chart.
*/}} */}}
{{- define "gitea.actions.name" -}} {{- define "gitea.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}} {{- end -}}
@ -12,7 +12,7 @@ Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name. If release name contains chart name it will be used as a full name.
*/}} */}}
{{- define "gitea.actions.fullname" -}} {{- define "gitea.fullname" -}}
{{- if .Values.fullnameOverride -}} {{- if .Values.fullnameOverride -}}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
{{- else -}} {{- else -}}
@ -28,22 +28,45 @@ If release name contains chart name it will be used as a full name.
{{/* {{/*
Create a default worker name. Create a default worker name.
*/}} */}}
{{- define "gitea.actions.workername" -}} {{- define "gitea.workername" -}}
{{- printf "%s-%s" .global.Release.Name .worker | trunc 63 | trimSuffix "-" -}} {{- printf "%s-%s" .global.Release.Name .worker | trunc 63 | trimSuffix "-" -}}
{{- end -}} {{- end -}}
{{/* {{/*
Create chart name and version as used by the chart label. Create chart name and version as used by the chart label.
*/}} */}}
{{- define "gitea.actions.chart" -}} {{- define "gitea.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
{{- end -}} {{- end -}}
{{/*
Create image name and tag used by the deployment.
*/}}
{{- define "gitea.image" -}}
{{- $fullOverride := .Values.image.fullOverride | default "" -}}
{{- $registry := .Values.global.imageRegistry | default .Values.image.registry -}}
{{- $repository := .Values.image.repository -}}
{{- $separator := ":" -}}
{{- $tag := .Values.image.tag | default .Chart.AppVersion | toString -}}
{{- $rootless := ternary "-rootless" "" (.Values.image.rootless) -}}
{{- $digest := "" -}}
{{- if .Values.image.digest }}
{{- $digest = (printf "@%s" (.Values.image.digest | toString)) -}}
{{- end -}}
{{- if $fullOverride }}
{{- printf "%s" $fullOverride -}}
{{- else if $registry }}
{{- printf "%s/%s%s%s%s%s" $registry $repository $separator $tag $rootless $digest -}}
{{- else -}}
{{- printf "%s%s%s%s%s" $repository $separator $tag $rootless $digest -}}
{{- end -}}
{{- end -}}
{{/* {{/*
Storage Class Storage Class
*/}} */}}
{{- define "gitea.actions.persistence.storageClass" -}} {{- define "gitea.persistence.storageClass" -}}
{{- $storageClass := default (tpl ( default "" .Values.global.storageClass) .) }} {{- $storageClass := (tpl ( default "" .Values.persistence.storageClass) .) | default (tpl ( default "" .Values.global.storageClass) .) }}
{{- if $storageClass }} {{- if $storageClass }}
storageClassName: {{ $storageClass | quote }} storageClassName: {{ $storageClass | quote }}
{{- end }} {{- end }}
@ -52,37 +75,57 @@ storageClassName: {{ $storageClass | quote }}
{{/* {{/*
Common labels Common labels
*/}} */}}
{{- define "gitea.actions.labels" -}} {{- define "gitea.labels" -}}
helm.sh/chart: {{ include "gitea.actions.chart" . }} helm.sh/chart: {{ include "gitea.chart" . }}
app: {{ include "gitea.actions.name" . }} app: {{ include "gitea.name" . }}
{{ include "gitea.actions.selectorLabels" . }} {{ include "gitea.selectorLabels" . }}
app.kubernetes.io/version: {{ default .Chart.AppVersion | quote }} app.kubernetes.io/version: {{ .Values.image.tag | default .Chart.AppVersion | quote }}
version: {{ default .Chart.AppVersion | quote }} version: {{ .Values.image.tag | default .Chart.AppVersion | quote }}
app.kubernetes.io/managed-by: {{ .Release.Service }} app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end -}} {{- end -}}
{{- define "gitea.actions.labels.actRunner" -}} {{- define "gitea.labels.actRunner" -}}
helm.sh/chart: {{ include "gitea.actions.chart" . }} helm.sh/chart: {{ include "gitea.chart" . }}
app: {{ include "gitea.actions.name" . }}-act-runner app: {{ include "gitea.name" . }}-act-runner
{{ include "gitea.actions.selectorLabels.actRunner" . }} {{ include "gitea.selectorLabels.actRunner" . }}
app.kubernetes.io/version: {{ default .Chart.AppVersion | quote }} app.kubernetes.io/version: {{ .Values.image.tag | default .Chart.AppVersion | quote }}
version: {{ default .Chart.AppVersion | quote }} version: {{ .Values.image.tag | default .Chart.AppVersion | quote }}
app.kubernetes.io/managed-by: {{ .Release.Service }} app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end -}} {{- end -}}
{{/* {{/*
Selector labels Selector labels
*/}} */}}
{{- define "gitea.actions.selectorLabels" -}} {{- define "gitea.selectorLabels" -}}
app.kubernetes.io/name: {{ include "gitea.actions.name" . }} app.kubernetes.io/name: {{ include "gitea.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/instance: {{ .Release.Name }}
{{- end -}} {{- end -}}
{{- define "gitea.actions.selectorLabels.actRunner" -}} {{- define "gitea.selectorLabels.actRunner" -}}
app.kubernetes.io/name: {{ include "gitea.actions.name" . }}-act-runner app.kubernetes.io/name: {{ include "gitea.name" . }}-act-runner
app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/instance: {{ .Release.Name }}
{{- end -}} {{- end -}}
{{- define "gitea.actions.local_root_url" -}} {{- define "gitea.act_runner.local_root_url" -}}
{{- .Values.giteaRootURL -}} {{- .Values.giteaRootURL -}}
{{- end -}} {{- end -}}
{{/*
Parse the http url to hostname + port separated by space for the nc command
*/}}
{{- define "gitea.act_runner.nc" -}}
{{- $url := include "gitea.act_runner.local_root_url" . | urlParse -}}
{{- $host := get $url "host" -}}
{{- $scheme := get $url "scheme" -}}
{{- $port := "80" -}}
{{- if contains ":" $host -}}
{{- $hostAndPort := regexSplit ":" $host 2 -}}
{{- $host = index $hostAndPort 0 -}}
{{- $port = index $hostAndPort 1 -}}
{{- else if eq $scheme "https" -}}
{{- $port = "443" -}}
{{- else if eq $scheme "http" -}}
{{- $port = "80" -}}
{{- end -}}
{{- printf "%s %s" $host $port -}}
{{- end -}}

View File

@ -3,10 +3,10 @@
apiVersion: v1 apiVersion: v1
kind: ConfigMap kind: ConfigMap
metadata: metadata:
name: {{ include "gitea.actions.fullname" . }}-act-runner-config name: {{ include "gitea.fullname" . }}-act-runner-config
namespace: {{ .Values.namespace | default .Release.Namespace }} namespace: {{ .Values.namespace | default .Release.Namespace }}
labels: labels:
{{- include "gitea.actions.labels" . | nindent 4 }} {{- include "gitea.labels" . | nindent 4 }}
data: data:
config.yaml: | config.yaml: |
{{- with .Values.statefulset.actRunner.config -}} {{- with .Values.statefulset.actRunner.config -}}

View File

@ -0,0 +1,14 @@
{{- if .Values.enabled }}
{{- if and (and .Values.provisioning.enabled .Values.persistence.enabled) .Values.persistence.mount }}
---
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "gitea.fullname" . }}-scripts
namespace: {{ .Values.namespace | default .Release.Namespace }}
labels:
{{- include "gitea.labels" . | nindent 4 }}
data:
{{ (.Files.Glob "scripts/*.sh").AsConfig | indent 2 }}
{{- end }}
{{- end }}

115
templates/job.yaml Normal file
View File

@ -0,0 +1,115 @@
{{- if .Values.enabled }}
{{- if and (and .Values.provisioning.enabled .Values.persistence.enabled) .Values.persistence.mount }}
{{- $name := include "gitea.workername" (dict "global" . "worker" "actions-token-job") }}
{{- $secretName := include "gitea.workername" (dict "global" . "worker" "actions-token") }}
---
apiVersion: batch/v1
kind: Job
metadata:
name: {{ $name }}
namespace: {{ .Values.namespace | default .Release.Namespace }}
labels:
{{- include "gitea.labels" . | nindent 4 }}
{{- with .Values.provisioning.labels }}
{{- toYaml . | nindent 4 }}
{{- end }}
app.kubernetes.io/component: token-job
annotations:
{{- with .Values.provisioning.annotations }}
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
ttlSecondsAfterFinished: {{ .Values.provisioning.ttlSecondsAfterFinished }}
template:
metadata:
labels:
{{- include "gitea.labels" . | nindent 8 }}
{{- with .Values.provisioning.labels }}
{{- toYaml . | nindent 8 }}
{{- end }}
app.kubernetes.io/component: token-job
spec:
initContainers:
- name: init-gitea
image: "{{ .Values.init.image.repository }}:{{ .Values.init.image.tag }}"
command:
- sh
- -c
- |
while ! nc -z {{ include "gitea.act_runner.nc" . }}; do
sleep 5
done
containers:
- name: actions-token-create
image: "{{ include "gitea.image" . }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
env:
- name: GITEA_APP_INI
value: /data/gitea/conf/app.ini
command:
- sh
- -c
- |
echo "Generating act_runner token via 'gitea actions generate-runner-token'..."
mkdir -p /data/actions/
gitea actions generate-runner-token | grep -E '^.{40}$' | tr -d '\n' > /data/actions/token
resources:
{{- toYaml .Values.provisioning.resources | nindent 12 }}
volumeMounts:
- name: data
mountPath: /data
{{- if .Values.persistence.subPath }}
subPath: {{ .Values.persistence.subPath }}
{{- end }}
- name: actions-token-upload
image: "{{ .Values.provisioning.publish.repository }}:{{ .Values.provisioning.publish.tag }}"
imagePullPolicy: {{ .Values.provisioning.publish.pullPolicy }}
env:
- name: SECRET_NAME
value: {{ $secretName }}
command:
- sh
- -c
- |
printf "Checking rights to update kubernetes act_runner secret..."
kubectl auth can-i update secret/${SECRET_NAME}
/scripts/token.sh
resources:
{{- toYaml .Values.provisioning.resources | nindent 12 }}
volumeMounts:
- mountPath: /scripts
name: scripts
readOnly: true
- mountPath: /data
name: data
readOnly: true
{{- if .Values.persistence.subPath }}
subPath: {{ .Values.persistence.subPath }}
{{- end }}
{{- range $key, $value := .Values.provisioning.nodeSelector }}
nodeSelector:
{{ $key }}: {{ $value | quote }}
{{- end }}
{{- with .Values.provisioning.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.provisioning.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}
restartPolicy: Never
serviceAccount: {{ $name }}
volumes:
- name: scripts
configMap:
name: {{ include "gitea.fullname" . }}-scripts
defaultMode: 0755
- name: data
persistentVolumeClaim:
claimName: {{ .Values.persistence.claimName }}
parallelism: 1
completions: 1
backoffLimit: 1
{{- end }}
{{- end }}

26
templates/role-job.yaml Normal file
View File

@ -0,0 +1,26 @@
{{- if .Values.enabled }}
{{- if and (and .Values.provisioning.enabled .Values.persistence.enabled) .Values.persistence.mount }}
{{- $name := include "gitea.workername" (dict "global" . "worker" "actions-token-job") }}
{{- $secretName := include "gitea.workername" (dict "global" . "worker" "actions-token") }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: {{ $name }}
namespace: {{ .Values.namespace | default .Release.Namespace }}
labels:
{{- include "gitea.labels" . | nindent 4 }}
app.kubernetes.io/component: token-job
rules:
- apiGroups:
- ""
resources:
- secrets
resourceNames:
- {{ $secretName }}
verbs:
- get
- update
- patch
{{- end }}
{{- end }}

View File

@ -0,0 +1,23 @@
{{- if .Values.enabled }}
{{- if and (and .Values.provisioning.enabled .Values.persistence.enabled) .Values.persistence.mount }}
{{- $name := include "gitea.workername" (dict "global" . "worker" "actions-token-job") }}
{{- $secretName := include "gitea.workername" (dict "global" . "worker" "actions-token") }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: {{ $name }}
namespace: {{ .Values.namespace | default .Release.Namespace }}
labels:
{{- include "gitea.labels" . | nindent 4 }}
app.kubernetes.io/component: token-job
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: {{ $name }}
subjects:
- kind: ServiceAccount
name: {{ $name }}
namespace: {{ .Release.Namespace }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,20 @@
{{- if .Values.enabled }}
{{- if and (and .Values.provisioning.enabled .Values.persistence.enabled) .Values.persistence.mount }}
{{- $name := include "gitea.workername" (dict "global" . "worker" "actions-token-job") }}
{{- $secretName := include "gitea.workername" (dict "global" . "worker" "actions-token") }}
---
apiVersion: v1
kind: Secret
metadata:
name: {{ $secretName }}
namespace: {{ .Values.namespace | default .Release.Namespace }}
labels:
{{- include "gitea.labels" . | nindent 4 }}
app.kubernetes.io/component: token-job
{{ $secret := (lookup "v1" "Secret" .Release.Namespace $secretName) -}}
{{ if $secret -}}
data:
token: {{ (b64dec (index $secret.data "token")) | b64enc }}
{{ end -}}
{{- end }}
{{- end }}

View File

@ -0,0 +1,14 @@
{{- if .Values.enabled }}
{{- if and (and .Values.provisioning.enabled .Values.persistence.enabled) .Values.persistence.mount }}
{{- $name := include "gitea.workername" (dict "global" . "worker" "actions-token-job") }}
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ $name }}
namespace: {{ .Values.namespace | default .Release.Namespace }}
labels:
{{- include "gitea.labels" . | nindent 4 }}
app.kubernetes.io/component: token-job
{{- end }}
{{- end }}

View File

@ -1,11 +1,11 @@
{{- if .Values.enabled }} {{- if .Values.enabled }}
{{- $secretName := include "gitea.actions.workername" (dict "global" . "worker" "actions-token") }} {{- $secretName := include "gitea.workername" (dict "global" . "worker" "actions-token") }}
--- ---
apiVersion: apps/v1 apiVersion: apps/v1
kind: StatefulSet kind: StatefulSet
metadata: metadata:
labels: labels:
{{- include "gitea.actions.labels.actRunner" . | nindent 4 }} {{- include "gitea.labels.actRunner" . | nindent 4 }}
{{- with .Values.statefulset.labels }} {{- with .Values.statefulset.labels }}
{{- toYaml . | nindent 4 }} {{- toYaml . | nindent 4 }}
{{- end }} {{- end }}
@ -13,19 +13,18 @@ metadata:
{{- with .Values.statefulset.annotations }} {{- with .Values.statefulset.annotations }}
{{- toYaml . | nindent 4 }} {{- toYaml . | nindent 4 }}
{{- end }} {{- end }}
name: {{ include "gitea.actions.fullname" . }}-act-runner name: {{ include "gitea.fullname" . }}-act-runner
namespace: {{ .Values.namespace | default .Release.Namespace }} namespace: {{ .Values.namespace | default .Release.Namespace }}
spec: spec:
replicas: {{ .Values.statefulset.replicas | default 1 }}
selector: selector:
matchLabels: matchLabels:
{{- include "gitea.actions.selectorLabels.actRunner" . | nindent 6 }} {{- include "gitea.selectorLabels.actRunner" . | nindent 6 }}
template: template:
metadata: metadata:
annotations: annotations:
checksum/config: {{ include (print $.Template.BasePath "/config-act-runner.yaml") . | sha256sum }} checksum/config: {{ include (print $.Template.BasePath "/config-act-runner.yaml") . | sha256sum }}
labels: labels:
{{- include "gitea.actions.labels.actRunner" . | nindent 8 }} {{- include "gitea.labels.actRunner" . | nindent 8 }}
{{- with .Values.statefulset.labels }} {{- with .Values.statefulset.labels }}
{{- toYaml . | nindent 8 }} {{- toYaml . | nindent 8 }}
{{- end }} {{- end }}
@ -37,12 +36,9 @@ spec:
- sh - sh
- -c - -c
- | - |
echo 'Trying to reach Gitea on {{ include "gitea.actions.local_root_url" . }}' while ! nc -z {{ include "gitea.act_runner.nc" . }}; do
until timeout 10 wget --no-check-certificate --spider {{ include "gitea.actions.local_root_url" . }}; do sleep 5
sleep 3
echo "Trying again in 3 seconds..."
done done
echo "Gitea has been reached!"
containers: containers:
- name: act-runner - name: act-runner
image: "{{ .Values.statefulset.actRunner.repository }}:{{ .Values.statefulset.actRunner.tag }}" image: "{{ .Values.statefulset.actRunner.repository }}:{{ .Values.statefulset.actRunner.tag }}"
@ -61,7 +57,7 @@ spec:
name: "{{ .Values.existingSecret | default $secretName }}" name: "{{ .Values.existingSecret | default $secretName }}"
key: "{{ .Values.existingSecretKey | default "token" }}" key: "{{ .Values.existingSecretKey | default "token" }}"
- name: GITEA_INSTANCE_URL - name: GITEA_INSTANCE_URL
value: {{ include "gitea.actions.local_root_url" . }} value: {{ include "gitea.act_runner.local_root_url" . }}
- name: CONFIG_FILE - name: CONFIG_FILE
value: /actrunner/config.yaml value: /actrunner/config.yaml
resources: resources:
@ -115,7 +111,7 @@ spec:
volumes: volumes:
- name: act-runner-config - name: act-runner-config
configMap: configMap:
name: {{ include "gitea.actions.fullname" . }}-act-runner-config name: {{ include "gitea.fullname" . }}-act-runner-config
- name: docker-certs - name: docker-certs
emptyDir: {} emptyDir: {}
{{- with .Values.statefulset.extraVolumes }} {{- with .Values.statefulset.extraVolumes }}
@ -126,8 +122,8 @@ spec:
name: data-act-runner name: data-act-runner
spec: spec:
accessModes: [ "ReadWriteOnce" ] accessModes: [ "ReadWriteOnce" ]
{{- include "gitea.actions.persistence.storageClass" . | nindent 8 }} {{- include "gitea.persistence.storageClass" . | nindent 8 }}
resources: resources:
requests: requests:
storage: {{ .Values.statefulset.persistence.size }} storage: 1Mi
{{- end }} {{- end }}

View File

@ -5,15 +5,49 @@ release:
templates: templates:
- templates/01-consistency-checks.yaml - templates/01-consistency-checks.yaml
tests: tests:
- it: fails when provisioning is enabled BUT persistence is completely disabled
set:
persistence:
enabled: false
enabled: true
provisioning:
enabled: true
asserts:
- failedTemplate:
errorMessage: "persistence.enabled and persistence.mount are required when provisioning is enabled"
- it: fails when provisioning is enabled BUT mount is disabled, although persistence is enabled
set:
persistence:
enabled: true
mount: false
enabled: true
provisioning:
enabled: true
asserts:
- failedTemplate:
errorMessage: "persistence.enabled and persistence.mount are required when provisioning is enabled"
- it: fails when provisioning is enabled AND existingSecret is given
set:
enabled: true
provisioning:
enabled: true
existingSecret: "secret-reference"
asserts:
- failedTemplate:
errorMessage: "Can't specify both actions.provisioning.enabled and actions.existingSecret"
- it: fails when provisioning is disabled BUT existingSecret and existingSecretKey are missing - it: fails when provisioning is disabled BUT existingSecret and existingSecretKey are missing
set: set:
enabled: true enabled: true
provisioning:
enabled: false
asserts: asserts:
- failedTemplate: - failedTemplate:
errorMessage: "existingSecret and existingSecretKey are required when provisioning is disabled" errorMessage: "existingSecret and existingSecretKey are required when provisioning is disabled"
- it: fails when provisioning is disabled BUT existingSecretKey is missing - it: fails when provisioning is disabled BUT existingSecretKey is missing
set: set:
enabled: true enabled: true
provisioning:
enabled: false
existingSecret: "my-secret" existingSecret: "my-secret"
asserts: asserts:
- failedTemplate: - failedTemplate:
@ -21,6 +55,8 @@ tests:
- it: fails when provisioning is disabled BUT existingSecret is missing - it: fails when provisioning is disabled BUT existingSecret is missing
set: set:
enabled: true enabled: true
provisioning:
enabled: false
existingSecretKey: "my-secret-key" existingSecretKey: "my-secret-key"
asserts: asserts:
- failedTemplate: - failedTemplate:
@ -28,6 +64,8 @@ tests:
- it: fails when LOCAL_ROOT_URL is missing - it: fails when LOCAL_ROOT_URL is missing
set: set:
enabled: true enabled: true
provisioning:
enabled: false
existingSecret: "my-secret" existingSecret: "my-secret"
existingSecretKey: "my-secret-key" existingSecretKey: "my-secret-key"
asserts: asserts:

View File

@ -0,0 +1,47 @@
suite: actions template | config-scripts
release:
name: gitea-unittests
namespace: testing
templates:
- templates/config-scripts.yaml
tests:
- it: renders a ConfigMap when all criteria are met
template: templates/config-scripts.yaml
set:
enabled: true
provisioning:
enabled: true
persistence:
enabled: true
mount: true
asserts:
- hasDocuments:
count: 1
- containsDocument:
kind: ConfigMap
apiVersion: v1
name: gitea-unittests-actions-scripts
- isNotNullOrEmpty:
path: data["token.sh"]
- it: doesn't renders a ConfigMap by default
template: templates/config-scripts.yaml
asserts:
- hasDocuments:
count: 0
- it: doesn't renders a ConfigMap with disabled actions but enabled provisioning
template: templates/config-scripts.yaml
asserts:
- hasDocuments:
count: 0
- it: doesn't renders a ConfigMap with disabled actions but otherwise met criteria
template: templates/config-scripts.yaml
set:
enabled: false
provisioning:
enabled: true
persistence:
enabled: true
mount: true
asserts:
- hasDocuments:
count: 0

88
unittests/helm/job.yaml Normal file
View File

@ -0,0 +1,88 @@
suite: actions template | job
release:
name: gitea-unittests
namespace: testing
chart:
# Override appVersion to have a pinned version for comparison
appVersion: 1.23.6
templates:
- templates/job.yaml
tests:
- it: renders a Job
template: templates/job.yaml
set:
enabled: true
provisioning:
enabled: true
persistence:
enabled: true
mount: true
asserts:
- hasDocuments:
count: 1
- containsDocument:
kind: Job
apiVersion: batch/v1
name: gitea-unittests-actions-token-job
- equal:
path: spec.template.spec.containers[0].image
value: "docker.gitea.com/gitea:1.23.6-rootless"
- it: tag override
template: templates/job.yaml
set:
image.tag: "1.23.7"
enabled: true
provisioning:
enabled: true
publish:
tag: "1.29.0"
persistence:
enabled: true
mount: true
asserts:
- equal:
path: spec.template.spec.containers[0].image
value: "docker.gitea.com/gitea:1.23.7-rootless"
- equal:
path: spec.template.spec.containers[1].image
value: "bitnami/kubectl:1.29.0"
- it: doesn't renders a Job by default
template: templates/job.yaml
asserts:
- hasDocuments:
count: 0
- it: doesn't renders a Job when provisioning is enabled BUT actions are not enabled
template: templates/job.yaml
set:
enabled: false
provisioning:
enabled: true
asserts:
- hasDocuments:
count: 0
- it: renders a Job with correct nc command
template: templates/job.yaml
set:
enabled: true
giteaRootURL: "https://git.example.com:8443"
provisioning:
enabled: true
persistence:
enabled: true
mount: true
asserts:
- hasDocuments:
count: 1
- containsDocument:
kind: Job
apiVersion: batch/v1
name: gitea-unittests-actions-token-job
- equal:
path: spec.template.spec.containers[0].image
value: "docker.gitea.com/gitea:1.23.6-rootless"
- equal:
path: spec.template.spec.initContainers[0].command[2]
value: |
while ! nc -z git.example.com 8443; do
sleep 5
done

View File

@ -0,0 +1,40 @@
suite: actions template | role-job
release:
name: gitea-unittests
namespace: testing
templates:
- templates/role-job.yaml
tests:
- it: doesn't renders a Role by default
template: templates/role-job.yaml
asserts:
- hasDocuments:
count: 0
- it: renders a Role
template: templates/role-job.yaml
set:
enabled: true
provisioning:
enabled: true
persistence:
enabled: true
mount: true
asserts:
- hasDocuments:
count: 1
- containsDocument:
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
name: gitea-unittests-actions-token-job
- it: doesn't renders a Role when criteria met BUT actions are not enabled
template: templates/role-job.yaml
set:
enabled: false
provisioning:
enabled: true
persistence:
enabled: true
mount: true
asserts:
- hasDocuments:
count: 0

View File

@ -0,0 +1,40 @@
suite: actions template | rolebinding-job
release:
name: gitea-unittests
namespace: testing
templates:
- templates/rolebinding-job.yaml
tests:
- it: doesn't renders a RoleBinding by default
template: templates/rolebinding-job.yaml
asserts:
- hasDocuments:
count: 0
- it: renders a RoleBinding
template: templates/rolebinding-job.yaml
set:
enabled: true
provisioning:
enabled: true
persistence:
enabled: true
mount: true
asserts:
- hasDocuments:
count: 1
- containsDocument:
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
name: gitea-unittests-actions-token-job
- it: doesn't renders a RoleBinding when criteria met BUT actions are not enabled
template: templates/rolebinding-job.yaml
set:
enabled: false
provisioning:
enabled: true
persistence:
enabled: true
mount: true
asserts:
- hasDocuments:
count: 0

View File

@ -0,0 +1,40 @@
suite: actions template | secret-token
release:
name: gitea-unittests
namespace: testing
templates:
- templates/secret-token.yaml
tests:
- it: doesn't renders a Secret by default
template: templates/secret-token.yaml
asserts:
- hasDocuments:
count: 0
- it: renders a Secret
template: templates/secret-token.yaml
set:
enabled: true
provisioning:
enabled: true
persistence:
enabled: true
mount: true
asserts:
- hasDocuments:
count: 1
- containsDocument:
kind: Secret
apiVersion: v1
name: gitea-unittests-actions-token
- it: doesn't renders a Secret when criteria met BUT actions are not enabled
template: templates/secret-token.yaml
set:
enabled: false
provisioning:
enabled: true
persistence:
enabled: true
mount: true
asserts:
- hasDocuments:
count: 0

View File

@ -0,0 +1,40 @@
suite: actions template | serviceaccount-job
release:
name: gitea-unittests
namespace: testing
templates:
- templates/serviceaccount-job.yaml
tests:
- it: doesn't renders a ServiceAccount by default
template: templates/serviceaccount-job.yaml
asserts:
- hasDocuments:
count: 0
- it: renders a ServiceAccount
template: templates/serviceaccount-job.yaml
set:
enabled: true
provisioning:
enabled: true
persistence:
enabled: true
mount: true
asserts:
- hasDocuments:
count: 1
- containsDocument:
kind: ServiceAccount
apiVersion: v1
name: gitea-unittests-actions-token-job
- it: doesn't renders a ServiceAccount when criteria met BUT actions are not enabled
template: templates/serviceaccount-job.yaml
set:
enabled: false
provisioning:
enabled: true
persistence:
enabled: true
mount: true
asserts:
- hasDocuments:
count: 0

View File

@ -69,7 +69,7 @@ tests:
name: gitea-unittests-actions-act-runner name: gitea-unittests-actions-act-runner
- equal: - equal:
path: spec.template.metadata.annotations["checksum/config"] path: spec.template.metadata.annotations["checksum/config"]
value: "7566d9c60261bf8cbff6a6936fc7aead96cec540d8c793d142a5ad4664c56ba5" value: "e01f6cc186c5b523cba245cbfc9d556df49a71f7f650c979c2dbfd2bf40b9098"
- it: renders a StatefulSet http (with correct GITEA_INSTANCE_URL env from giteaRootURL) - it: renders a StatefulSet http (with correct GITEA_INSTANCE_URL env from giteaRootURL)
template: templates/statefulset.yaml template: templates/statefulset.yaml
set: set:
@ -92,12 +92,9 @@ tests:
- equal: - equal:
path: spec.template.spec.initContainers[0].command[2] path: spec.template.spec.initContainers[0].command[2]
value: | value: |
echo 'Trying to reach Gitea on http://git.example.com' while ! nc -z git.example.com 80; do
until timeout 10 wget --no-check-certificate --spider http://git.example.com; do sleep 5
sleep 3
echo "Trying again in 3 seconds..."
done done
echo "Gitea has been reached!"
- it: renders a StatefulSet https (with correct GITEA_INSTANCE_URL env from giteaRootURL) - it: renders a StatefulSet https (with correct GITEA_INSTANCE_URL env from giteaRootURL)
template: templates/statefulset.yaml template: templates/statefulset.yaml
set: set:
@ -120,12 +117,9 @@ tests:
- equal: - equal:
path: spec.template.spec.initContainers[0].command[2] path: spec.template.spec.initContainers[0].command[2]
value: | value: |
echo 'Trying to reach Gitea on https://git.example.com' while ! nc -z git.example.com 443; do
until timeout 10 wget --no-check-certificate --spider https://git.example.com; do sleep 5
sleep 3
echo "Trying again in 3 seconds..."
done done
echo "Gitea has been reached!"
- it: renders a StatefulSet https (with correct GITEA_INSTANCE_URL env from giteaRootURL) - it: renders a StatefulSet https (with correct GITEA_INSTANCE_URL env from giteaRootURL)
template: templates/statefulset.yaml template: templates/statefulset.yaml
set: set:
@ -148,12 +142,9 @@ tests:
- equal: - equal:
path: spec.template.spec.initContainers[0].command[2] path: spec.template.spec.initContainers[0].command[2]
value: | value: |
echo 'Trying to reach Gitea on https://git.example.com:8443' while ! nc -z git.example.com 8443; do
until timeout 10 wget --no-check-certificate --spider https://git.example.com:8443; do sleep 5
sleep 3
echo "Trying again in 3 seconds..."
done done
echo "Gitea has been reached!"
- it: allows adding custom environment variables to the docker-in-docker container - it: allows adding custom environment variables to the docker-in-docker container
template: templates/statefulset.yaml template: templates/statefulset.yaml
set: set:

View File

@ -1,10 +1,10 @@
# Configure Gitea Actions # Configure Gitea Actions
# - must enable persistence if the job is enabled
## @section Gitea Actions ## @section Gitea Actions
# #
## @param enabled Create an act runner StatefulSet. ## @param enabled Create an act runner StatefulSet.
## @param init.image.repository The image used for the init containers ## @param init.image.repository The image used for the init containers
## @param init.image.tag The image tag used for the init containers ## @param init.image.tag The image tag used for the init containers
## @param statefulset.replicas the amount of (replica) runner pods deployed
## @param statefulset.annotations Act runner annotations ## @param statefulset.annotations Act runner annotations
## @param statefulset.labels Act runner labels ## @param statefulset.labels Act runner labels
## @param statefulset.resources Act runner resources ## @param statefulset.resources Act runner resources
@ -22,13 +22,22 @@
## @param statefulset.dind.pullPolicy The Docker-in-Docker pullPolicy ## @param statefulset.dind.pullPolicy The Docker-in-Docker pullPolicy
## @param statefulset.dind.extraVolumeMounts Allows mounting extra volumes in the Docker-in-Docker container ## @param statefulset.dind.extraVolumeMounts Allows mounting extra volumes in the Docker-in-Docker container
## @param statefulset.dind.extraEnvs Allows adding custom environment variables, such as `DOCKER_IPTABLES_LEGACY` ## @param statefulset.dind.extraEnvs Allows adding custom environment variables, such as `DOCKER_IPTABLES_LEGACY`
## @param statefulset.persistence.size Size for persistence to store act runner data ## @param provisioning.enabled Create a job that will create and save the token in a Kubernetes Secret
## @param provisioning.annotations Job's annotations
## @param provisioning.labels Job's labels
## @param provisioning.resources Job's resources
## @param provisioning.nodeSelector NodeSelector for the job
## @param provisioning.tolerations Tolerations for the job
## @param provisioning.affinity Affinity for the job
## @param provisioning.ttlSecondsAfterFinished ttl for the job after finished in order to allow helm to properly recognize that the job completed
## @param provisioning.publish.repository The image that can create the secret via kubectl
## @param provisioning.publish.tag The publish image tag that can create the secret
## @param provisioning.publish.pullPolicy The publish image pullPolicy that can create the secret
## @param existingSecret Secret that contains the token ## @param existingSecret Secret that contains the token
## @param existingSecretKey Secret key ## @param existingSecretKey Secret key
## @param giteaRootURL URL the act_runner registers and connect with ## @param giteaRootURL URL the act_runner registers and connect with
enabled: false enabled: false
statefulset: statefulset:
replicas: 1
annotations: {} annotations: {}
labels: {} labels: {}
resources: {} resources: {}
@ -63,15 +72,29 @@ statefulset:
# - name: "DOCKER_IPTABLES_LEGACY" # - name: "DOCKER_IPTABLES_LEGACY"
# value: "1" # value: "1"
persistence:
size: 1Gi
init: init:
image: image:
repository: busybox repository: busybox
# Overrides the image tag whose default is the chart appVersion. # Overrides the image tag whose default is the chart appVersion.
tag: "1.37.0" tag: "1.37.0"
provisioning:
enabled: false
annotations: {}
labels: {}
resources: {}
nodeSelector: {}
tolerations: []
affinity: {}
publish:
repository: bitnami/kubectl
tag: 1.29.0
pullPolicy: IfNotPresent
ttlSecondsAfterFinished: 300
## Specify an existing token secret ## Specify an existing token secret
## ##
existingSecret: "" existingSecret: ""
@ -80,6 +103,52 @@ existingSecretKey: ""
## Specify the root URL of the Gitea instance ## Specify the root URL of the Gitea instance
giteaRootURL: "" giteaRootURL: ""
## @section Persistence
#
## @param persistence.enabled Enable persistent storage
## @param persistence.create Whether to create the persistentVolumeClaim for shared storage
## @param persistence.mount Whether the persistentVolumeClaim should be mounted (even if not created)
## @param persistence.claimName Use an existing claim to store repository information
## @param persistence.size Size for persistence to store repo information
## @param persistence.accessModes AccessMode for persistence
## @param persistence.labels Labels for the persistence volume claim to be created
## @param persistence.annotations.helm.sh/resource-policy Resource policy for the persistence volume claim
## @param persistence.storageClass Name of the storage class to use
## @param persistence.subPath Subdirectory of the volume to mount at
## @param persistence.volumeName Name of persistent volume in PVC
persistence:
enabled: true
create: true
mount: true
claimName: gitea-shared-storage
size: 10Gi
accessModes:
- ReadWriteOnce
labels: {}
storageClass:
subPath:
volumeName: ""
annotations:
helm.sh/resource-policy: keep
## @section Image
## @param image.registry image registry, e.g. gcr.io,docker.io
## @param image.repository Image to start for this pod
## @param image.tag Visit: [Image tag](https://hub.docker.com/r/gitea/gitea/tags?page=1&ordering=last_updated). Defaults to `appVersion` within Chart.yaml.
## @param image.digest Image digest. Allows to pin the given image tag. Useful for having control over mutable tags like `latest`
## @param image.pullPolicy Image pull policy
## @param image.rootless Wether or not to pull the rootless version of Gitea, only works on Gitea 1.14.x or higher
## @param image.fullOverride Completely overrides the image registry, path/image, tag and digest. **Adjust `image.rootless` accordingly and review [Rootless defaults](#rootless-defaults).**
image:
registry: "docker.gitea.com"
repository: gitea
# Overrides the image tag whose default is the chart appVersion.
tag: ""
digest: ""
pullPolicy: IfNotPresent
rootless: true
fullOverride: ""
## @section Global ## @section Global
# #
## @param global.imageRegistry global image registry override ## @param global.imageRegistry global image registry override