Files
helm-gitea/templates/gitea/deployment.yaml
T
volker.raschekandCopilot c409e201b3 refactor(deployment): extract annotation and label rendering into helpers
The Deployment metadata inlined the annotation and label logic with nested
`if` blocks, which duplicated the fallback handling and made the empty-value
cases hard to follow. Moving the rendering into `gitea.deployment.annotations`
and `gitea.deployment.labels` keeps the manifest declarative and allows other
resources to reuse the same merge semantics later on.

The helpers are consumed through `with (include ... | fromYaml)` so that an
empty result never emits a dangling `annotations:` key. Labels always render
because `gitea.labels` is never empty, which keeps Argo CD from reporting drift.
Inside the label helper the user labels are appended with an untrimmed newline,
otherwise they would be concatenated onto the last line of `gitea.labels` and
`fromYaml` would silently return an `Error` map instead of failing the render.

The metadata attributes are additionally sorted alphabetically to follow the
chart conventions.

Unit tests now cover the previously untested `deployment.annotations` value and
assert that the base labels keep rendering despite the new `with` guard.

Co-authored-by: Copilot <copilot@github.com>
2026-09-04 15:26:17 +02:00

491 lines
20 KiB
YAML

{{- if .Values.deployment.enabled -}}
apiVersion: apps/v1
kind: Deployment
metadata:
{{- with (include "gitea.deployment.annotations" . | fromYaml) }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- with (include "gitea.deployment.labels" . | fromYaml) }}
labels:
{{- toYaml . | nindent 4 }}
{{- end }}
name: {{ include "gitea.fullname" . }}
namespace: {{ .Values.namespace | default .Release.Namespace }}
spec:
replicas: {{ .Values.deployment.replicas }}
strategy:
type: {{ .Values.deployment.strategy.type }}
{{- if eq .Values.deployment.strategy.type "RollingUpdate" }}
rollingUpdate:
maxUnavailable: {{ .Values.deployment.strategy.rollingUpdate.maxUnavailable }}
maxSurge: {{ .Values.deployment.strategy.rollingUpdate.maxSurge }}
{{- end }}
selector:
matchLabels:
{{- include "gitea.selectorLabels" . | nindent 6 }}
template:
metadata:
annotations:
{{- if and .Values.secrets.admin.addSHASumAnnotation (not .Values.secrets.admin.existingSecret.enabled) }}
checksum/admin: {{ include (print $.Template.BasePath "/gitea/secret_admin.yaml") . | sha256sum }}
{{- end }}
{{- if and .Values.secrets.config.addSHASumAnnotation (not .Values.secrets.config.existingSecret.enabled) }}
checksum/config: {{ include (print $.Template.BasePath "/gitea/secret_config.yaml") . | sha256sum }}
{{- end }}
{{- if and .Values.secrets.gpg.addSHASumAnnotation (not .Values.secrets.gpg.existingSecret.enabled) }}
checksum/gpg: {{ include (print $.Template.BasePath "/gitea/secret_gpg.yaml") . | sha256sum }}
{{- end }}
{{- if and .Values.secrets.init.addSHASumAnnotation (not .Values.secrets.init.existingSecret.enabled) }}
checksum/init: {{ include (print $.Template.BasePath "/gitea/secret_init.yaml") . | sha256sum }}
{{- end }}
{{- if and .Values.secrets.inlineConfig.addSHASumAnnotation (not .Values.secrets.inlineConfig.existingSecret.enabled) }}
checksum/inlineConfig: {{ include (print $.Template.BasePath "/gitea/secret_inlineConfig.yaml") . | sha256sum }}
{{- end }}
{{- if and .Values.secrets.metrics.addSHASumAnnotation (not .Values.secrets.metrics.existingSecret.enabled) }}
checksum/metrics: {{ include (print $.Template.BasePath "/gitea/secret_metrics.yaml") . | sha256sum }}
{{- end }}
{{- range $idx, $value := .Values.gitea.ldap }}
checksum/ldap_{{ $idx }}: {{ include "gitea.ldap_settings" (list $idx $value) | sha256sum }}
{{- end }}
{{- range $idx, $value := .Values.gitea.oauth }}
checksum/oauth_{{ $idx }}: {{ include "gitea.oauth_settings" (list $idx $value) | sha256sum }}
{{- end }}
{{- with .Values.gitea.podAnnotations }}
{{- toYaml . | nindent 8 }}
{{- end }}
labels:
{{- include "gitea.labels" . | nindent 8 }}
{{- if .Values.deployment.labels }}
{{- toYaml .Values.deployment.labels | nindent 8 }}
{{- end }}
spec:
{{- $hostUsers := include "gitea.hostUsers" . | trim }}
{{- $securityContext := include "gitea.deployment.securityContext" . | trim }}
{{- $containerSecurityContext := include "gitea.containerSecurityContext" (list . (deepCopy .Values.deployment.gitea.securityContext)) | trim }}
{{- $commandInitContainerSecurityContext := include "gitea.commandInitContainerSecurityContext" (list . (deepCopy .Values.deployment.gitea.securityContext)) | trim }}
{{- if .Values.deployment.schedulerName }}
schedulerName: "{{ .Values.deployment.schedulerName }}"
{{- end }}
{{- if (or .Values.serviceAccount.create .Values.serviceAccount.name) }}
serviceAccountName: {{ include "gitea.serviceAccountName" . }}
{{- end }}
{{- if .Values.deployment.priorityClassName }}
priorityClassName: "{{ .Values.deployment.priorityClassName }}"
{{- end }}
{{- if $hostUsers }}
hostUsers: {{ $hostUsers }}
{{- end }}
{{- include "gitea.images.pullSecrets" . | nindent 6 }}
{{- if $securityContext }}
securityContext:
{{- $securityContext | nindent 8 }}
{{- end }}
initContainers:
{{- if .Values.preExtraInitContainers }}
{{- toYaml .Values.preExtraInitContainers | nindent 8 }}
{{- end }}
- name: init-directories
image: "{{ include "gitea.image" . }}"
imagePullPolicy: {{ .Values.deployment.gitea.image.pullPolicy }}
command:
- "{{ .Values.initContainersScriptsVolumeMountPath }}/init_directory_structure.sh"
env:
- name: GITEA_APP_INI
value: /data/gitea/conf/app.ini
- name: GITEA_CUSTOM
value: /data/gitea
- name: GITEA_WORK_DIR
value: /data
- name: GITEA_TEMP
value: /tmp/gitea
{{- if .Values.deployment.gitea.env }}
{{- toYaml .Values.deployment.gitea.env | nindent 12 }}
{{- end }}
{{- if .Values.secrets.gpg.enabled }}
- name: GNUPGHOME
valueFrom:
secretKeyRef:
name: {{ include "gitea.secret.gpg.name" . }}
key: {{ include "gitea.secret.gpg.gpgHomeKey" . }}
{{- end }}
volumeMounts:
- name: init
mountPath: {{ .Values.initContainersScriptsVolumeMountPath }}
- name: temp
mountPath: /tmp
- name: data
mountPath: /data
{{- if .Values.persistence.subPath }}
subPath: {{ .Values.persistence.subPath }}
{{- end }}
{{- include "gitea.init-additional-mounts" . | nindent 12 }}
{{- if $containerSecurityContext }}
securityContext:
{{- $containerSecurityContext | nindent 12 }}
{{- end }}
resources:
{{- toYaml .Values.initContainers.resources | nindent 12 }}
- name: init-app-ini
image: "{{ include "gitea.image" . }}"
imagePullPolicy: {{ .Values.deployment.gitea.image.pullPolicy }}
{{- if .Values.gitea.extraEnvSourceFile }}
command:
- "/bin/bash"
- "-c"
args:
- "test -f {{ .Values.gitea.extraEnvSourceFile }} && source {{ .Values.gitea.extraEnvSourceFile }} || { echo 'ERROR: Failed to source {{ .Values.gitea.extraEnvSourceFile }}'; exit 1; } && {{ .Values.initContainersScriptsVolumeMountPath }}/config_environment.sh"
{{- else }}
command:
- "{{ .Values.initContainersScriptsVolumeMountPath }}/config_environment.sh"
{{- end }}
env:
- name: GITEA_APP_INI
value: /data/gitea/conf/app.ini
- name: GITEA_CUSTOM
value: /data/gitea
- name: GITEA_WORK_DIR
value: /data
- name: GITEA_TEMP
value: /tmp/gitea
- name: TMP_EXISTING_ENVS_FILE
value: /tmp/existing-envs
- name: ENV_TO_INI_MOUNT_POINT
value: /env-to-ini-mounts
{{- if .Values.deployment.gitea.env }}
{{- toYaml .Values.deployment.gitea.env | nindent 12 }}
{{- end }}
{{- if .Values.gitea.additionalConfigFromEnvs }}
{{- tpl (toYaml .Values.gitea.additionalConfigFromEnvs) $ | nindent 12 }}
{{- end }}
volumeMounts:
- name: config
mountPath: {{ .Values.initContainersScriptsVolumeMountPath }}
- name: temp
mountPath: /tmp
- name: data
mountPath: /data
{{- if .Values.persistence.subPath }}
subPath: {{ .Values.persistence.subPath }}
{{- end }}
- name: inline-config-sources
mountPath: /env-to-ini-mounts/inlines/
{{- range $idx, $value := .Values.gitea.additionalConfigSources }}
- name: additional-config-sources-{{ $idx }}
mountPath: "/env-to-ini-mounts/additionals/{{ $idx }}/"
{{- end }}
{{- include "gitea.init-additional-mounts" . | nindent 12 }}
{{- if $containerSecurityContext }}
securityContext:
{{- $containerSecurityContext | nindent 12 }}
{{- end }}
resources:
{{- toYaml .Values.initContainers.resources | nindent 12 }}
{{- if .Values.secrets.gpg.enabled }}
- name: configure-gpg
image: "{{ include "gitea.image" . }}"
{{- if .Values.gitea.extraEnvSourceFile }}
command:
- "/bin/bash"
- "-c"
args:
- "test -f {{ .Values.gitea.extraEnvSourceFile }} && source {{ .Values.gitea.extraEnvSourceFile }} || { echo 'ERROR: Failed to source {{ .Values.gitea.extraEnvSourceFile }}'; exit 1; } && {{ .Values.initContainersScriptsVolumeMountPath }}/configure_gpg_environment.sh"
{{- else }}
command:
- "{{ .Values.initContainersScriptsVolumeMountPath }}/configure_gpg_environment.sh"
{{- end }}
imagePullPolicy: {{ .Values.deployment.gitea.image.pullPolicy }}
{{- if $commandInitContainerSecurityContext }}
securityContext:
{{- $commandInitContainerSecurityContext | nindent 12 }}
{{- end }}
env:
- name: GNUPGHOME
valueFrom:
secretKeyRef:
name: {{ include "gitea.secret.gpg.name" . }}
key: {{ include "gitea.secret.gpg.gpgHomeKey" . }}
- name: TMP_RAW_GPG_KEY
value: /raw/private.asc
volumeMounts:
- name: init
mountPath: {{ .Values.initContainersScriptsVolumeMountPath }}
- name: data
mountPath: /data
{{- if .Values.persistence.subPath }}
subPath: {{ .Values.persistence.subPath }}
{{- end }}
- name: gpg-private-key
mountPath: /raw
readOnly: true
{{- if .Values.extraVolumeMounts }}
{{- toYaml .Values.extraVolumeMounts | nindent 12 }}
{{- end }}
resources:
{{- toYaml .Values.initContainers.resources | nindent 12 }}
{{- end }}
- name: configure-gitea
image: "{{ include "gitea.image" . }}"
{{- if .Values.gitea.extraEnvSourceFile }}
command:
- "/bin/bash"
- "-c"
args:
- "test -f {{ .Values.gitea.extraEnvSourceFile }} && source {{ .Values.gitea.extraEnvSourceFile }} || { echo 'ERROR: Failed to source {{ .Values.gitea.extraEnvSourceFile }}'; exit 1; } && {{ .Values.initContainersScriptsVolumeMountPath }}/configure_gitea.sh"
{{- else }}
command:
- "{{ .Values.initContainersScriptsVolumeMountPath }}/configure_gitea.sh"
{{- end }}
imagePullPolicy: {{ .Values.deployment.gitea.image.pullPolicy }}
{{- if $commandInitContainerSecurityContext }}
securityContext:
{{- $commandInitContainerSecurityContext | nindent 12 }}
{{- end }}
env:
- name: GITEA_APP_INI
value: /data/gitea/conf/app.ini
- name: GITEA_CUSTOM
value: /data/gitea
- name: GITEA_WORK_DIR
value: /data
- name: GITEA_TEMP
value: /tmp/gitea
{{- if .Values.deployment.gitea.image.rootless }}
- name: HOME
value: /data/gitea/git
{{- end }}
{{- if .Values.gitea.ldap }}
{{- range $idx, $value := .Values.gitea.ldap }}
{{- if $value.existingSecret }}
- name: GITEA_LDAP_BIND_DN_{{ $idx }}
valueFrom:
secretKeyRef:
key: bindDn
name: {{ $value.existingSecret }}
- name: GITEA_LDAP_PASSWORD_{{ $idx }}
valueFrom:
secretKeyRef:
key: bindPassword
name: {{ $value.existingSecret }}
{{- else }}
- name: GITEA_LDAP_BIND_DN_{{ $idx }}
value: {{ $value.bindDn | quote }}
- name: GITEA_LDAP_PASSWORD_{{ $idx }}
value: {{ $value.bindPassword | quote }}
{{- end }}
{{- end }}
{{- end }}
{{- if .Values.gitea.oauth }}
{{- range $idx, $value := .Values.gitea.oauth }}
{{- if $value.existingSecret }}
- name: GITEA_OAUTH_KEY_{{ $idx }}
valueFrom:
secretKeyRef:
key: key
name: {{ $value.existingSecret }}
- name: GITEA_OAUTH_SECRET_{{ $idx }}
valueFrom:
secretKeyRef:
key: secret
name: {{ $value.existingSecret }}
{{- end }}
{{- end }}
{{- end }}
{{- if .Values.secrets.admin.enabled }}
- name: GITEA_ADMIN_USERNAME
valueFrom:
secretKeyRef:
key: {{ include "gitea.secret.admin.usernameKey" . }}
name: {{ include "gitea.secret.admin.name" . }}
- name: GITEA_ADMIN_PASSWORD
valueFrom:
secretKeyRef:
key: {{ include "gitea.secret.admin.passwordKey" . }}
name: {{ include "gitea.secret.admin.name" . }}
- name: GITEA_ADMIN_EMAIL
valueFrom:
secretKeyRef:
key: {{ include "gitea.secret.admin.emailKey" . }}
name: {{ include "gitea.secret.admin.name" . }}
- name: GITEA_ADMIN_PASSWORD_MODE
value: {{ include "gitea.secret.admin.passwordMode" $ }}
{{- end }}
{{- if .Values.deployment.gitea.env }}
{{- toYaml .Values.deployment.gitea.env | nindent 12 }}
{{- end }}
volumeMounts:
- name: init
mountPath: {{ .Values.initContainersScriptsVolumeMountPath }}
- name: temp
mountPath: /tmp
- name: data
mountPath: /data
{{- if .Values.persistence.subPath }}
subPath: {{ .Values.persistence.subPath }}
{{- end }}
{{- include "gitea.init-additional-mounts" . | nindent 12 }}
resources:
{{- toYaml .Values.initContainers.resources | nindent 12 }}
{{- if .Values.postExtraInitContainers }}
{{- toYaml .Values.postExtraInitContainers | nindent 8 }}
{{- end }}
terminationGracePeriodSeconds: {{ .Values.deployment.terminationGracePeriodSeconds }}
containers:
- name: {{ .Chart.Name }}
image: "{{ include "gitea.image" . }}"
imagePullPolicy: {{ .Values.deployment.gitea.image.pullPolicy }}
env:
# SSH Port values have to be set here as well for openssh configuration
- name: SSH_LISTEN_PORT
value: {{ .Values.gitea.config.server.SSH_LISTEN_PORT | quote }}
- name: SSH_PORT
value: {{ .Values.gitea.config.server.SSH_PORT | quote }}
{{- if not .Values.deployment.gitea.image.rootless }}
- name: SSH_LOG_LEVEL
value: {{ .Values.gitea.ssh.logLevel | quote }}
{{- end }}
- name: GITEA_APP_INI
value: /data/gitea/conf/app.ini
- name: GITEA_CUSTOM
value: /data/gitea
- name: GITEA_WORK_DIR
value: /data
- name: GITEA_TEMP
value: /tmp/gitea
{{- with .Values.deployment.gitea.resources }}
{{- if and (hasKey . "limits") (hasKey (.limits | default dict) "cpu") }}
- name: GOMAXPROCS
valueFrom:
resourceFieldRef:
divisor: "1"
resource: limits.cpu
{{- end }}
{{- end }}
- name: TMPDIR
value: /tmp/gitea
{{- if .Values.deployment.gitea.image.rootless }}
- name: HOME
value: /data/gitea/git
{{- end }}
{{- if .Values.secrets.gpg.enabled }}
- name: GNUPGHOME
valueFrom:
secretKeyRef:
name: {{ include "gitea.secret.gpg.name" . }}
key: {{ include "gitea.secret.gpg.gpgHomeKey" . }}
{{- end }}
{{- if .Values.deployment.gitea.env }}
{{- toYaml .Values.deployment.gitea.env | nindent 12 }}
{{- end }}
ports:
- name: ssh
containerPort: {{ .Values.gitea.config.server.SSH_LISTEN_PORT }}
{{- if .Values.service.ssh.hostPort }}
hostPort: {{ .Values.service.ssh.hostPort }}
{{- end }}
- name: http
containerPort: {{ .Values.gitea.config.server.HTTP_PORT }}
{{- if .Values.gitea.config.server.ENABLE_PPROF }}
- name: profiler
containerPort: 6060
{{- end }}
{{- if .Values.gitea.livenessProbe.enabled }}
livenessProbe:
{{- include "gitea.deployment.probe" .Values.gitea.livenessProbe | nindent 12 }}
{{- end }}
{{- if .Values.gitea.readinessProbe.enabled }}
readinessProbe:
{{- include "gitea.deployment.probe" .Values.gitea.readinessProbe | nindent 12 }}
{{- end }}
{{- if .Values.gitea.startupProbe.enabled }}
startupProbe:
{{- include "gitea.deployment.probe" .Values.gitea.startupProbe | nindent 12 }}
{{- end }}
resources:
{{- toYaml (.Values.deployment.gitea.resources | default dict) | nindent 12 }}
{{- if $containerSecurityContext }}
securityContext:
{{- $containerSecurityContext | nindent 12 }}
{{- end }}
volumeMounts:
- name: temp
mountPath: /tmp
- name: data
mountPath: /data
{{- if .Values.persistence.subPath }}
subPath: {{ .Values.persistence.subPath }}
{{- end }}
{{- include "gitea.container-additional-mounts" . | nindent 12 }}
{{- if .Values.extraContainers }}
{{- toYaml .Values.extraContainers | nindent 8 }}
{{- end }}
{{- with .Values.global.hostAliases }}
hostAliases:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.deployment.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.deployment.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.deployment.topologySpreadConstraints }}
topologySpreadConstraints:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.deployment.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- if .Values.deployment.dnsConfig }}
dnsConfig:
{{- toYaml .Values.deployment.dnsConfig | nindent 8 }}
{{- end }}
{{- with .Values.deployment.resources }}
resources:
{{- toYaml . | nindent 8 }}
{{- end }}
volumes:
- name: init
secret:
secretName: {{ include "gitea.secret.init.name" . }}
defaultMode: 110
- name: config
secret:
secretName: {{ include "gitea.secret.config.name" . }}
defaultMode: 110
{{- if gt (len .Values.deployment.volumes) 0 }}
{{- toYaml .Values.deployment.volumes | nindent 8 }}
{{- end }}
- name: inline-config-sources
secret:
secretName: {{ include "gitea.secret.inlineConfig.name" . }}
{{- range $idx, $value := .Values.gitea.additionalConfigSources }}
- name: additional-config-sources-{{ $idx }}
{{- toYaml $value | nindent 10 }}
{{- end }}
- name: temp
emptyDir: {}
{{- if .Values.secrets.gpg.enabled }}
- name: gpg-private-key
secret:
secretName: {{ include "gitea.secret.gpg.name" . }}
items:
- key: {{ include "gitea.secret.gpg.privateKeyKey" . }}
path: private.asc
defaultMode: 0100
{{- end }}
{{- if .Values.persistence.enabled }}
{{- if .Values.persistence.mount }}
- name: data
persistentVolumeClaim:
claimName: {{ .Values.persistence.claimName }}
{{- end }}
{{- else if not .Values.persistence.enabled }}
- name: data
emptyDir: {}
{{- end }}
{{- end }}