Add Gitea Actions act runner #596

Open
dementhorr wants to merge 16 commits from dementhorr/helm-chart:gitea-actions into main
25 changed files with 765 additions and 10 deletions

View File

@ -1,12 +1,12 @@
dependencies:
- name: postgresql
repository: oci://registry-1.docker.io/bitnamicharts
version: 13.2.26
version: 13.4.6
- name: postgresql-ha
repository: oci://registry-1.docker.io/bitnamicharts
version: 12.3.5
version: 12.8.2
- name: redis-cluster
repository: oci://registry-1.docker.io/bitnamicharts
version: 9.1.4
digest: sha256:1f76d28f5fda7d10fe814416c6d1d1a02fd626d8b9e895d28acf3ebf3fa71780
generated: "2023-12-28T00:15:48.963793716Z"
version: 9.5.20
digest: sha256:10ca7303e61effbe02163c0df6ed1a87f25d71edd44d1aadae971f56679ae985
generated: "2024-02-17T00:21:51.363456958Z"

View File

@ -36,15 +36,15 @@ dependencies:
# https://github.com/bitnami/charts/blob/main/bitnami/postgresql
- name: postgresql
repository: oci://registry-1.docker.io/bitnamicharts
version: 13.2.26
version: 13.4.6
condition: postgresql.enabled
# https://github.com/bitnami/charts/blob/main/bitnami/postgresql-ha/Chart.yaml
- name: postgresql-ha
repository: oci://registry-1.docker.io/bitnamicharts
version: 12.3.5
version: 12.8.2
condition: postgresql-ha.enabled
# https://github.com/bitnami/charts/blob/main/bitnami/redis-cluster/Chart.yaml
- name: redis-cluster
repository: oci://registry-1.docker.io/bitnamicharts
version: 9.1.4
version: 9.5.20
condition: redis-cluster.enabled

View File

@ -45,6 +45,7 @@
- [Persistence](#persistence-1)
- [Init](#init)
- [Signing](#signing)
- [Gitea Actions](#gitea-actions)
- [Gitea](#gitea)
- [LivenessProbe](#livenessprobe)
- [ReadinessProbe](#readinessprobe)
@ -980,6 +981,40 @@ To comply with the Gitea helm chart definition of the digest parameter, a "custo
| `signing.privateKey` | Inline private gpg key for signed Gitea actions | `""` |
| `signing.existingSecret` | Use an existing secret to store the value of `signing.privateKey` | `""` |
dementhorr marked this conversation as resolved Outdated
Outdated
Review

Gitea Actions

Gitea Actions

This section misses a Table-of-content reference at the top of this file.

This section misses a Table-of-content reference at the top of this file.
### Gitea Actions
| Name | Description | Value |
| ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------ |
dementhorr marked this conversation as resolved Outdated
Outdated
Review

I'd suggest using actions.enabled as a global flag for enabling actions.

I'd suggest using `actions.enabled` as a global flag for enabling actions.
| `actions.enabled` | Create an act runner StatefulSet. | `false` |
| `actions.statefulset.annotations` | Act runner annotations | `{}` |
| `actions.statefulset.labels` | Act runner labels | `{}` |
| `actions.statefulset.resources` | Act runner resources | `{}` |
| `actions.statefulset.nodeSelector` | NodeSelector for the statefulset | `{}` |
| `actions.statefulset.tolerations` | Tolerations for the statefulset | `[]` |
| `actions.statefulset.affinity` | Affinity for the statefulset | `{}` |
| `actions.statefulset.actRunner.repository` | The Gitea act runner image | `gitea/act_runner` |
| `actions.statefulset.actRunner.tag` | The Gitea act runner tag | `0.2.6` |
| `actions.statefulset.actRunner.pullPolicy` | The Gitea act runner pullPolicy | `IfNotPresent` |
| `actions.statefulset.actRunner.config` | Act runner custom configuration. See [Act Runner documentation](https://docs.gitea.com/usage/actions/act-runner#configuration) for details. | `Too complex. See values.yaml` |
| `actions.statefulset.dind.repository` | The Docker-in-Docker image | `docker` |
| `actions.statefulset.dind.tag` | The Docker-in-Docker image tag | `25.0.2-dind` |
dementhorr marked this conversation as resolved Outdated
Outdated
Review

let's bump to 25.0.2

let's bump to 25.0.2
| `actions.statefulset.dind.pullPolicy` | The Docker-in-Docker pullPolicy | `IfNotPresent` |
| `actions.provisioning.enabled` | Create a job that will create and save the token in a Kubernetes Secret | `false` |
| `actions.provisioning.annotations` | Job's annotations | `{}` |
| `actions.provisioning.labels` | Job's labels | `{}` |
| `actions.provisioning.resources` | Job's resources | `{}` |
| `actions.provisioning.nodeSelector` | NodeSelector for the job | `{}` |
| `actions.provisioning.tolerations` | Tolerations for the job | `[]` |
| `actions.provisioning.affinity` | Affinity for the job | `{}` |
| `actions.provisioning.token.repository` | The image that can create a token via `gitea actions generate-runner-token` | `gitea/gitea` |
| `actions.provisioning.token.tag` | The token image tag that can create a token | `""` |
| `actions.provisioning.token.pullPolicy` | The token image pullPolicy that can create a token | `IfNotPresent` |
| `actions.provisioning.publish.repository` | The image that can create the secret via kubectl | `bitnami/kubectl` |
| `actions.provisioning.publish.tag` | The publish image tag that can create the secret | `1.29.0` |
| `actions.provisioning.publish.pullPolicy` | The publish image pullPolicy that can create the secret | `IfNotPresent` |
| `actions.existingSecret` | Secret that contains the token | `""` |
| `actions.existingSecretKey` | Secret key | `""` |
### Gitea
| Name | Description | Value |

33
readme-actions-dev.md Normal file
View File

@ -0,0 +1,33 @@
# Gitea Actions
In order to use the Gitea Actions act-runner you must either:
- enable persistence (used for automatic deployment to be able to store the token in a place accessible for the Job)
- create a secret containing the act runner token and reference it as a `existingSecret`
dementhorr marked this conversation as resolved Outdated
Obsolete documentation when considering https://gitea.com/gitea/helm-chart/pulls/596/files#issuecomment-811808
In order to use Gitea Actions, you must log on the server that's running Gitea and run the command:
`gitea actions generate-runner-token`
This command will out a token that is needed by the act-runner to register with the Gitea backend.
Because this is a manual operation, we automated this using a Kubernetes Job using the following containers:
1) `actions-token-create`: it uses the current `gitea-rootless` image, mounts the persistent directory to `/data/` then it saves the output from `gitea actions generate-runner-token` to `/data/actions/token`
2) `actions-token-upload`: it uses a `bitnami/kubectl` image, mounts the scripts directory (`/scripts`) and
the persistent directory (`/data/`), and using the script from `/scripts/token.sh` stores the token in a Kubernetes secret
dementhorr marked this conversation as resolved
Review
Obsolete documentation when considering https://gitea.com/gitea/helm-chart/pulls/596/files#issuecomment-811808
After the token is stored in a Kubernetes secret we can create the statefulset that contains the following containers:
1) `act-runner`: authenticates with Gitea using the token that was stored in the secret
2) `dind`: DockerInDocker image that is used to run the actions
If you are not using persistent volumes, you cannot use the Job to automatically generate the token.
In this case, you can use either the Web UI to generate the token or run a shell into a Gitea pod and invoke
the command `gitea actions generate-runner-token`. After generating the token, you must create a secret and use it via:
```yaml
actions:
provisioning:
enabled: false
existingSecret: "secret-name"
existingSecretKey: "secret-key"
```

43
scripts/token.sh Normal file
View File

@ -0,0 +1,43 @@
#!/bin/sh
set -eu
timeout_delay=15
check_token() {
set +e
echo "Checking for existing token..."
token="$(kubectl get secret "$SECRET_NAME" -o jsonpath="{.data['token']}" 2> /dev/null)"
[ $? -ne 0 ] && return 1
[ -z "$token" ] && return 2
return 0
}
create_token() {
echo "Waiting for new token to be generated..."
dementhorr marked this conversation as resolved
Review

I think this should be way shorter. If a token doesn't exist or cannot be created for some reason, it won't resolve itself anyhow. I think 10-15 seconds would also suffice?

I think this should be way shorter. If a token doesn't exist or cannot be created for some reason, it won't resolve itself anyhow. I think 10-15 seconds would also suffice?
begin=$(date +%s)
end=$((begin + timeout_delay))
while true; do
[ -f /data/actions/token ] && return 0
[ "$(date +%s)" -gt $end ] && return 1
sleep 5
done
}
store_token() {
echo "Storing the token in Kubernetes secret..."
kubectl patch secret "$SECRET_NAME" -p "{\"data\":{\"token\":\"$(base64 /data/actions/token | tr -d '\n')\"}}"
}
if check_token; then
echo "Key already in place, exiting."
exit
fi
dementhorr marked this conversation as resolved
Review

echo "Timed out waiting for a token to appear."

This reminds me about the "good old days" waiting for Pokemon XY to appear 😛

Suggestion:

"Checking for an existing act runner token in secret $SECRET_NAME timed out after $time".

> echo "Timed out waiting for a token to appear." This reminds me about the "good old days" waiting for Pokemon XY to appear 😛 Suggestion: "Checking for an existing act runner token in secret $SECRET_NAME timed out after $time".
if ! create_token; then
echo "Checking for an existing act runner token in secret $SECRET_NAME timed out after $timeout_delay"
exit 1
fi
store_token

View File

@ -45,6 +45,13 @@ If release name contains chart name it will be used as a full name.
{{- end -}}
{{- end -}}
{{/*
Create a default worker name.
*/}}
dementhorr marked this conversation as resolved
Review

I'd leave this comment out as it's too k8s-internal-specific and might cause more confusion than it possibly helps. We also don't have stdout comments in other places and I haven't seen any other chart doing this.

I'd leave this comment out as it's too k8s-internal-specific and might cause more confusion than it possibly helps. We also don't have stdout comments in other places and I haven't seen any other chart doing this.
{{- define "gitea.workername" -}}
{{- printf "%s-%s" .global.Release.Name .worker | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Create chart name and version as used by the chart label.
*/}}
@ -112,6 +119,15 @@ version: {{ .Values.image.tag | default .Chart.AppVersion | quote }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end -}}
{{- define "gitea.labels.actRunner" -}}
helm.sh/chart: {{ include "gitea.chart" . }}
app: {{ include "gitea.name" . }}-act-runner
{{ include "gitea.selectorLabels.actRunner" . }}
app.kubernetes.io/version: {{ .Values.image.tag | default .Chart.AppVersion | quote }}
version: {{ .Values.image.tag | default .Chart.AppVersion | quote }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end -}}
{{/*
Selector labels
*/}}
@ -120,6 +136,11 @@ app.kubernetes.io/name: {{ include "gitea.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end -}}
{{- define "gitea.selectorLabels.actRunner" -}}
app.kubernetes.io/name: {{ include "gitea.name" . }}-act-runner
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end -}}
{{- define "postgresql-ha.dns" -}}
{{- if (index .Values "postgresql-ha").enabled -}}
{{- printf "%s-postgresql-ha-pgpool.%s.svc.%s:%g" .Release.Name .Release.Namespace .Values.clusterDomain (index .Values "postgresql-ha" "service" "ports" "postgresql") -}}
@ -275,6 +296,9 @@ https
{{- if not (hasKey .Values.gitea.config "indexer") -}}
{{- $_ := set .Values.gitea.config "indexer" dict -}}
{{- end -}}
{{- if not (hasKey .Values.gitea.config "actions") -}}
{{- $_ := set .Values.gitea.config "actions" dict -}}
{{- end -}}
{{- end -}}
{{- define "gitea.inline_configuration.defaults" -}}
@ -321,6 +345,15 @@ https
{{- if not .Values.gitea.config.indexer.ISSUE_INDEXER_TYPE -}}
{{- $_ := set .Values.gitea.config.indexer "ISSUE_INDEXER_TYPE" "db" -}}
{{- end -}}
{{- if not .Values.gitea.config.actions.GITEA__ACTIONS__ENABLED -}}
Review

The whole actions related app.ini block is rendered when running helm template my-release ., although it is disabled by default. Looks like this check is missing. And a test that covers this.

The whole actions related `app.ini` block is rendered when running `helm template my-release .`, although it is disabled by default. Looks like this check is missing. And a test that covers this.
{{- $_ := set .Values.gitea.config.actions "GITEA__ACTIONS__ENABLED" "true" -}}
{{- end -}}
{{- if not .Values.gitea.config.actions.GITEA__SERVER__LOCAL_ROOT_URL -}}
{{- $_ := set .Values.gitea.config.actions "GITEA__SERVER__LOCAL_ROOT_URL" (printf "http://%s-http:%.0f" (include "gitea.fullname" .) .Values.service.http.port) -}}
{{- end -}}
{{- if not .Values.gitea.config.actions.GITEA__INSTANCE__URL -}}
{{- $_ := set .Values.gitea.config.actions "GITEA__INSTANCE__URL" (printf "http://%s-http:%.0f" (include "gitea.fullname" .) .Values.service.http.port) -}}
{{- end -}}
{{- end -}}
{{- define "gitea.inline_configuration.defaults.server" -}}

View File

@ -0,0 +1,14 @@
{{- if .Values.actions.enabled }}
---
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "gitea.fullname" . }}-act-runner-config
labels:
{{- include "gitea.labels" . | nindent 4 }}
data:
config.yaml: |
{{- with .Values.actions.statefulset.actRunner.config -}}
{{ . | nindent 4}}
{{- end -}}
{{- end }}

View File

@ -0,0 +1,11 @@
{{- if and (and .Values.actions.provisioning.enabled .Values.persistence.enabled) .Values.persistence.mount }}
Outdated
Review

Would the non-creation of this part still lead to a functional actions?
If not, I would suggest to only condition essential parts on actions.enabled.

Would the non-creation of this part still lead to a functional actions? If not, I would suggest to only condition essential parts on `actions.enabled`.

In the current chart format, you can use the act-runner without the job and the persistence volumes if you manually generate the token (via Web UI or running a shell command into the pod) and save it to a Secret. After that you can specify actions.existingSecret and actions.existingSecretKey.

In the current chart format, you can use the `act-runner` without the job and the persistence volumes if you manually generate the `token` (via Web UI or running a shell command into the pod) and save it to a Secret. After that you can specify `actions.existingSecret` and `actions.existingSecretKey`.
---
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "gitea.fullname" . }}-scripts
labels:
{{- include "gitea.labels" . | nindent 4 }}
data:
{{ (.Files.Glob "scripts/*.sh").AsConfig | indent 2 }}
{{- end }}

View File

@ -0,0 +1,115 @@
{{- if and (and .Values.actions.provisioning.enabled .Values.persistence.enabled) .Values.persistence.mount }}
{{- if .Values.actions.existingSecret }}
{{- fail "Can't specify both actions.provisioning.enabled and actions.existingSecret" }}
{{- end }}
{{- $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 }}
labels:
{{- include "gitea.labels" . | nindent 4 }}
{{- with .Values.actions.provisioning.labels }}
{{- toYaml . | nindent 4 }}
{{- end }}
app.kubernetes.io/component: token-job
annotations:
{{- with .Values.actions.provisioning.annotations }}
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
ttlSecondsAfterFinished: 0
template:
metadata:
labels:
{{- include "gitea.labels" . | nindent 8 }}
{{- with .Values.actions.provisioning.labels }}
{{- toYaml . | nindent 8 }}
{{- end }}
app.kubernetes.io/component: token-job
spec:
initContainers:
- name: init-gitea
image: busybox:1.36.1
command:
- sh
- -c
- |
while ! nc -z {{ include "gitea.fullname" . }}-http {{ .Values.service.http.port }}; do
sleep 5
done
containers:
- name: actions-token-create
image: "{{ .Values.actions.provisioning.token.repository }}:{{ .Values.actions.provisioning.token.tag | default (printf "%s-rootless" .Chart.AppVersion) }}"
imagePullPolicy: {{ .Values.actions.provisioning.token.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.actions.provisioning.resources | nindent 12 }}
volumeMounts:
- name: data
mountPath: /data
{{- if .Values.persistence.subPath }}
subPath: {{ .Values.persistence.subPath }}
{{- end }}
- name: actions-token-upload
image: "{{ .Values.actions.provisioning.publish.repository }}:{{ .Values.actions.provisioning.publish.tag }}"
imagePullPolicy: {{ .Values.actions.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.actions.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 }}
{{- with .Values.actions.provisioning.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.actions.provisioning.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.actions.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 }}

View File

@ -0,0 +1,23 @@
{{- if and (and .Values.actions.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 }}
labels:
{{- include "gitea.labels" . | nindent 4 }}
app.kubernetes.io/component: token-job
rules:
- apiGroups:
- ""
resources:
- secrets
resourceNames:
- {{ $secretName }}
verbs:
- get
- update
- patch
{{- end }}

View File

@ -0,0 +1,20 @@
{{- if and (and .Values.actions.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 }}
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 }}

View File

@ -0,0 +1,17 @@
{{- if and (and .Values.actions.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 }}
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 }}

View File

@ -0,0 +1,11 @@
{{- if and (and .Values.actions.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 }}
labels:
{{- include "gitea.labels" . | nindent 4 }}
app.kubernetes.io/component: token-job
{{- end }}

View File

@ -0,0 +1,113 @@
{{- if .Values.actions.enabled }}
{{- $secretName := include "gitea.workername" (dict "global" . "worker" "actions-token") }}
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
labels:
{{- include "gitea.labels.actRunner" . | nindent 4 }}
{{- with .Values.actions.statefulset.labels }}
{{- toYaml . | nindent 4 }}
{{- end }}
annotations:
{{- with .Values.actions.statefulset.annotations }}
{{- toYaml . | nindent 4 }}
{{- end }}
name: {{ include "gitea.fullname" . }}-act-runner
spec:
selector:
matchLabels:
{{- include "gitea.selectorLabels.actRunner" . | nindent 6 }}
template:
metadata:
labels:
{{- include "gitea.labels.actRunner" . | nindent 8 }}
{{- with .Values.actions.statefulset.labels }}
{{- toYaml . | nindent 8 }}
{{- end }}
spec:
initContainers:
- name: init-gitea
image: busybox:1.36.1
command:
- sh
- -c
- |
while ! nc -z {{ include "gitea.fullname" . }}-http {{ .Values.service.http.port }}; do
sleep 5
done
containers:
- name: act-runner
image: "{{ .Values.actions.statefulset.actRunner.repository }}:{{ .Values.actions.statefulset.actRunner.tag }}"
imagePullPolicy: {{ .Values.actions.statefulset.actRunner.pullPolicy }}
workingDir: /data
env:
- name: DOCKER_HOST
value: tcp://127.0.0.1:2376
- name: DOCKER_TLS_VERIFY
value: "1"
- name: DOCKER_CERT_PATH
value: /certs/server
- name: GITEA_RUNNER_REGISTRATION_TOKEN
valueFrom:
secretKeyRef:
name: "{{ .Values.actions.existingSecret | default $secretName }}"
key: "{{ .Values.actions.existingSecretKey | default "token" }}"
- name: GITEA_INSTANCE_URL
value: "http://{{ include "gitea.fullname" . }}-http:{{ .Values.service.http.port }}"
- name: CONFIG_FILE
value: /actrunner/config.yaml
dementhorr marked this conversation as resolved Outdated

Let's move the default value into values.yaml. Eliminates the default usage here. 🙂

As an alternative thought: I've noticed that when running act_runner generate-config, you'll get a yaml structure where you can define a list of labels for the runner via runner.labels. Was there a reason for providing the labels as environment variable instead through the config.yaml? If not - and given the fact that it works - I suggest to move ubuntu-latest into the config.yaml and drop this environment variable and its values.yaml spec entirely.

Let's move the default value into `values.yaml`. Eliminates the default usage here. 🙂 As an alternative thought: I've noticed that when running `act_runner generate-config`, you'll get a yaml structure where you can define a list of labels for the runner via `runner.labels`. Was there a reason for providing the labels as environment variable instead through the config.yaml? If not - and given the fact that it works - I suggest to move `ubuntu-latest` into the config.yaml and drop this environment variable and its values.yaml spec entirely.
resources:
{{- toYaml .Values.actions.statefulset.resources | nindent 12 }}
volumeMounts:
- mountPath: /actrunner/config.yaml
name: act-runner-config
subPath: config.yaml
- mountPath: /certs/server
name: docker-certs
- mountPath: /data
name: data-act-runner
- name: dind
image: "{{ .Values.actions.statefulset.dind.repository }}:{{ .Values.actions.statefulset.dind.tag }}"
imagePullPolicy: {{ .Values.actions.statefulset.dind.pullPolicy }}
env:
- name: DOCKER_HOST
value: tcp://127.0.0.1:2376
- name: DOCKER_TLS_VERIFY
value: "1"
- name: DOCKER_CERT_PATH
value: /certs/server
securityContext:
privileged: true
resources:
{{- toYaml .Values.actions.statefulset.resources | nindent 12 }}
dementhorr marked this conversation as resolved Outdated

Is this comment a left-over from testing?

Is this comment a left-over from testing?

yes

yes
volumeMounts:
- mountPath: /certs/server
name: docker-certs
{{- with .Values.actions.statefulset.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.actions.statefulset.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.actions.statefulset.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}
volumes:
- name: act-runner-config
configMap:
name: {{ include "gitea.fullname" . }}-act-runner-config
- name: docker-certs
emptyDir: {}
volumeClaimTemplates:
- metadata:
name: data-act-runner
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 1Mi
{{- end }}

View File

@ -68,6 +68,12 @@ spec:
value: /data
- name: GITEA_TEMP
value: /tmp/gitea
{{- if .Values.actions.enabled }}
- name: GITEA__ACTIONS__ENABLED
value: {{ .Values.gitea.config.actions.GITEA__ACTIONS__ENABLED | quote }}
- name: GITEA__SERVER__LOCAL_ROOT_URL
value: {{ .Values.gitea.config.actions.GITEA__SERVER__LOCAL_ROOT_URL | quote }}
{{- end }}
{{- if .Values.deployment.env }}
{{- toYaml .Values.deployment.env | nindent 12 }}
{{- end }}
@ -103,6 +109,12 @@ spec:
value: /data
- name: GITEA_TEMP
value: /tmp/gitea
{{- if .Values.actions.enabled }}
- name: GITEA__ACTIONS__ENABLED
value: {{ .Values.gitea.config.actions.GITEA__ACTIONS__ENABLED | quote }}
- name: GITEA__SERVER__LOCAL_ROOT_URL
value: {{ .Values.gitea.config.actions.GITEA__SERVER__LOCAL_ROOT_URL | quote }}
{{- end }}
{{- if .Values.deployment.env }}
{{- toYaml .Values.deployment.env | nindent 12 }}
{{- end }}
@ -240,6 +252,12 @@ spec:
- name: GITEA_ADMIN_PASSWORD
value: {{ .Values.gitea.admin.password | quote }}
{{- end }}
{{- if .Values.actions.enabled }}
- name: GITEA__ACTIONS__ENABLED
value: {{ .Values.gitea.config.actions.GITEA__ACTIONS__ENABLED | quote }}
- name: GITEA__SERVER__LOCAL_ROOT_URL
value: {{ .Values.gitea.config.actions.GITEA__SERVER__LOCAL_ROOT_URL | quote }}
{{- end }}
{{- if .Values.deployment.env }}
{{- toYaml .Values.deployment.env | nindent 12 }}
{{- end }}
@ -289,6 +307,12 @@ spec:
- name: GNUPGHOME
value: {{ .Values.signing.gpgHome }}
{{- end }}
{{- if .Values.actions.enabled }}
- name: GITEA__ACTIONS__ENABLED
value: {{ .Values.gitea.config.actions.GITEA__ACTIONS__ENABLED | quote }}
- name: GITEA__SERVER__LOCAL_ROOT_URL
value: {{ .Values.gitea.config.actions.GITEA__SERVER__LOCAL_ROOT_URL | quote }}
{{- end }}
{{- if .Values.deployment.env }}
{{- toYaml .Values.deployment.env | nindent 12 }}
{{- end }}

View File

@ -0,0 +1,19 @@
suite: actions template | config-act-runner
release:
name: gitea-unittests
namespace: testing
templates:
- templates/gitea/act_runner/config-act-runner.yaml
tests:
- it: renders a ConfigMap
template: templates/gitea/act_runner/config-act-runner.yaml
set:
actions:
enabled: true
asserts:
- hasDocuments:
count: 1
- containsDocument:
kind: ConfigMap
apiVersion: v1
name: gitea-unittests-act-runner-config

View File

@ -0,0 +1,23 @@
suite: actions template | config-scripts
release:
name: gitea-unittests
namespace: testing
templates:
- templates/gitea/act_runner/config-scripts.yaml
tests:
- it: renders a ConfigMap
template: templates/gitea/act_runner/config-scripts.yaml
set:
actions:
provisioning:
enabled: true
persistence:
enabled: true
mount: true
asserts:
- hasDocuments:
count: 1
- containsDocument:
kind: ConfigMap
apiVersion: v1
name: gitea-unittests-scripts

View File

@ -0,0 +1,23 @@
suite: actions template | job
release:
name: gitea-unittests
namespace: testing
templates:
- templates/gitea/act_runner/job.yaml
tests:
- it: renders a Job
template: templates/gitea/act_runner/job.yaml
set:
actions:
provisioning:
enabled: true
persistence:
enabled: true
mount: true
asserts:
- hasDocuments:
count: 1
- containsDocument:
kind: Job
apiVersion: batch/v1
name: gitea-unittests-actions-token-job

View File

@ -0,0 +1,23 @@
suite: actions template | role-job
release:
name: gitea-unittests
namespace: testing
templates:
- templates/gitea/act_runner/role-job.yaml
tests:
- it: renders a Role
template: templates/gitea/act_runner/role-job.yaml
set:
actions:
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

View File

@ -0,0 +1,23 @@
suite: actions template | rolebinding-job
release:
name: gitea-unittests
namespace: testing
templates:
- templates/gitea/act_runner/rolebinding-job.yaml
tests:
- it: renders a RoleBinding
template: templates/gitea/act_runner/rolebinding-job.yaml
set:
actions:
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

View File

@ -0,0 +1,23 @@
suite: actions template | secret-token
release:
name: gitea-unittests
namespace: testing
templates:
- templates/gitea/act_runner/secret-token.yaml
tests:
- it: renders a Secret
template: templates/gitea/act_runner/secret-token.yaml
set:
actions:
provisioning:
enabled: true
persistence:
enabled: true
mount: true
asserts:
- hasDocuments:
count: 1
- containsDocument:
kind: Secret
apiVersion: v1
name: gitea-unittests-actions-token

View File

@ -0,0 +1,23 @@
suite: actions template | serviceaccount-job
release:
name: gitea-unittests
namespace: testing
templates:
- templates/gitea/act_runner/serviceaccount-job.yaml
tests:
- it: renders a ServiceAccount
template: templates/gitea/act_runner/serviceaccount-job.yaml
set:
actions:
provisioning:
enabled: true
persistence:
enabled: true
mount: true
asserts:
- hasDocuments:
count: 1
- containsDocument:
kind: ServiceAccount
apiVersion: v1
name: gitea-unittests-actions-token-job

View File

@ -0,0 +1,19 @@
suite: actions template | statefulset
release:
name: gitea-unittests
namespace: testing
templates:
- templates/gitea/act_runner/statefulset.yaml
tests:
- it: renders a StatefulSet
template: templates/gitea/act_runner/statefulset.yaml
set:
actions:
enabled: true
asserts:
- hasDocuments:
count: 1
- containsDocument:
kind: StatefulSet
apiVersion: apps/v1
name: gitea-unittests-act-runner

View File

@ -28,7 +28,7 @@ tests:
matchRegex:
path: spec.template.spec.containers[0].image
# IN CASE OF AN INTENTIONAL MAJOR BUMP, ADJUST THIS TEST
pattern: ^docker.io/bitnami/postgresql:16.+$
pattern: ^registry-1.docker.io/bitnami/postgresql:16.+$
- it: "[redis-cluster] ensures we detect major image version upgrades"
template: charts/redis-cluster/templates/redis-statefulset.yaml
set:
@ -39,4 +39,4 @@ tests:
matchRegex:
path: spec.template.spec.containers[0].image
# IN CASE OF AN INTENTIONAL MAJOR BUMP, ADJUST THIS TEST
pattern: ^docker.io/bitnami/redis-cluster:7.+$
pattern: ^registry-1.docker.io/bitnami/redis-cluster:7.+$

View File

@ -331,6 +331,93 @@ signing:
# -----END PGP PRIVATE KEY BLOCK-----
existingSecret: ""
# Configure Gitea Actions
# - must enable persistence if the job is enabled
## @section Gitea Actions

As mentioned for GITEA__ACTIONS__ENABLED in https://gitea.com/gitea/helm-chart/pulls/596/files#issuecomment-811807, these preconditions should be part of the templating logic.

  • Applying the chart must throw an error when actions.enabled: true and at the same time persistence.enabled: false.
  • Isn't GITEA__SERVER__LOCAL_ROOT_URL what is also dynamically built in templates/gitea/act_runner/statefulset.yaml for GITEA_INSTANCE_URL? We can define that environment variable for the user via helpers.tpl, too.
As mentioned for `GITEA__ACTIONS__ENABLED` in https://gitea.com/gitea/helm-chart/pulls/596/files#issuecomment-811807, these preconditions should be part of the templating logic. - Applying the chart must throw an error when `actions.enabled: true` and at the same time `persistence.enabled: false`. - Isn't `GITEA__SERVER__LOCAL_ROOT_URL` what is also dynamically built in `templates/gitea/act_runner/statefulset.yaml` for `GITEA_INSTANCE_URL`? We can define that environment variable for the user via [helpers.tpl](https://gitea.com/gitea/helm-chart/src/branch/main/templates/_helpers.tpl#L260), too.

The chart must throw an error when actions.provisioning.enabled: true and persistence.enabled: false. Otherwise actions.enabled: true with persistence.enabled: false is valid if actions.existingSecret and actions.existingSecretKey is defined. I have modified the readme-actions-dev.md file.

I wasn't able to modify the GITEA_INSTANCE_URL using the .Values.gitea.config.actions variable from _helpers.tpl.

The chart must throw an error when `actions.provisioning.enabled: true` and `persistence.enabled: false`. Otherwise `actions.enabled: true` with `persistence.enabled: false` is valid if `actions.existingSecret` and `actions.existingSecretKey` is defined. I have modified the `readme-actions-dev.md` file. I wasn't able to modify the `GITEA_INSTANCE_URL` using the `.Values.gitea.config.actions` variable from `_helpers.tpl`.

My initial comment was misleading - just realized that now. I didn't mean we should set GITEA_INSTANCE_URL via _helpers.tpl. This value is not known to the app.ini. But GITEA__SERVER__LOCAL_ROOT_URL is. And since the value for both environment variables are identical, there is no technical reason to define one but let the user define the other. 🙂
Sorry for that confusion.

My initial comment was misleading - just realized that now. I didn't mean we should set `GITEA_INSTANCE_URL` via `_helpers.tpl`. This value is not known to the `app.ini`. But `GITEA__SERVER__LOCAL_ROOT_URL` is. And since the value for both environment variables are identical, there is no technical reason to define one but let the user define the other. 🙂 Sorry for that confusion.
#
## @param actions.enabled Create an act runner StatefulSet.
## @param actions.statefulset.annotations Act runner annotations
## @param actions.statefulset.labels Act runner labels
## @param actions.statefulset.resources Act runner resources
## @param actions.statefulset.nodeSelector NodeSelector for the statefulset
## @param actions.statefulset.tolerations Tolerations for the statefulset
## @param actions.statefulset.affinity Affinity for the statefulset
## @param actions.statefulset.actRunner.repository The Gitea act runner image
## @param actions.statefulset.actRunner.tag The Gitea act runner tag
dementhorr marked this conversation as resolved Outdated

Suggestion:

- ## @param actions.statefulset.config Act runner custom configuration.
+ ## @param actions.statefulset.config Act runner custom configuration. See [Act Runner documentation](https://docs.gitea.com/usage/actions/act-runner#configuration) for details.

Or, combined with https://gitea.com/gitea/helm-chart/pulls/596/files#issuecomment-811801 (to prevent broken README generation 😆):

- ## @param actions.statefulset.config Act runner custom configuration.
+ ## @param actions.statefulset.config [default: Too complex. See values.yaml] Act runner custom configuration. See [Act Runner documentation](https://docs.gitea.com/usage/actions/act-runner#configuration) for details.
Suggestion: ```diff - ## @param actions.statefulset.config Act runner custom configuration. + ## @param actions.statefulset.config Act runner custom configuration. See [Act Runner documentation](https://docs.gitea.com/usage/actions/act-runner#configuration) for details. ``` Or, combined with https://gitea.com/gitea/helm-chart/pulls/596/files#issuecomment-811801 (to prevent broken README generation 😆): ```diff - ## @param actions.statefulset.config Act runner custom configuration. + ## @param actions.statefulset.config [default: Too complex. See values.yaml] Act runner custom configuration. See [Act Runner documentation](https://docs.gitea.com/usage/actions/act-runner#configuration) for details. ```
## @param actions.statefulset.actRunner.pullPolicy The Gitea act runner pullPolicy
dementhorr marked this conversation as resolved Outdated

Suggestion:

- ## @param actions.statefulset.runnerLabels Act runner labels.
+ ## @param actions.statefulset.runnerLabels Act runner labels. See [Act Runner documentation](https://docs.gitea.com/usage/actions/act-runner#labels) for details.
Suggestion: ```diff - ## @param actions.statefulset.runnerLabels Act runner labels. + ## @param actions.statefulset.runnerLabels Act runner labels. See [Act Runner documentation](https://docs.gitea.com/usage/actions/act-runner#labels) for details. ```
## @param actions.statefulset.actRunner.config [default: Too complex. See values.yaml] Act runner custom configuration. See [Act Runner documentation](https://docs.gitea.com/usage/actions/act-runner#configuration) for details.
## @param actions.statefulset.dind.repository The Docker-in-Docker image
## @param actions.statefulset.dind.tag The Docker-in-Docker image tag
## @param actions.statefulset.dind.pullPolicy The Docker-in-Docker pullPolicy
## @param actions.provisioning.enabled Create a job that will create and save the token in a Kubernetes Secret
## @param actions.provisioning.annotations Job's annotations
## @param actions.provisioning.labels Job's labels
## @param actions.provisioning.resources Job's resources
## @param actions.provisioning.nodeSelector NodeSelector for the job
## @param actions.provisioning.tolerations Tolerations for the job
## @param actions.provisioning.affinity Affinity for the job
## @param actions.provisioning.token.repository The image that can create a token via `gitea actions generate-runner-token`
## @param actions.provisioning.token.tag The token image tag that can create a token
## @param actions.provisioning.token.pullPolicy The token image pullPolicy that can create a token
## @param actions.provisioning.publish.repository The image that can create the secret via kubectl
## @param actions.provisioning.publish.tag The publish image tag that can create the secret
## @param actions.provisioning.publish.pullPolicy The publish image pullPolicy that can create the secret
## @param actions.existingSecret Secret that contains the token
## @param actions.existingSecretKey Secret key
actions:
enabled: false
statefulset:
annotations: {}
dementhorr marked this conversation as resolved Outdated

The current approach of only documenting what a chart user has to do manually is not ideal. Setting actions.enabled: true should automatically configure the instance to have enable Gitea Actions. Means, it should either define gitea.config.actions.enabled as provided inline values while templating, or inject the environment variable GITEA__ACTIONS__ENABLED=true to the app.ini processing.

To keep the amount of injected envs as low as possible, I would prefer we do it via inline values. There already is a method for that in helpers.tpl defining other default values. Here, we also can detect conflicting configurations (e.g. actions.enabled: true and user-defined inline gitea.config.actions.enabled: false) and fail the templating process with an appropriate error message.

Making that part of the chart logic reduces usage errors.

The current approach of only documenting what a chart user has to do manually is not ideal. Setting `actions.enabled: true` should automatically configure the instance to have enable _Gitea Actions_. Means, it should either define `gitea.config.actions.enabled` as provided inline values while templating, or inject the environment variable `GITEA__ACTIONS__ENABLED=true` to the app.ini processing. To keep the amount of injected envs as low as possible, I would prefer we do it via inline values. There already is a method for that in [helpers.tpl](https://gitea.com/gitea/helm-chart/src/branch/main/templates/_helpers.tpl#L260) defining other default values. Here, we also can detect conflicting configurations (e.g. `actions.enabled: true` and user-defined inline `gitea.config.actions.enabled: false`) and fail the templating process with an appropriate error message. Making that part of the chart logic reduces usage errors.
labels: {}
resources: {}
nodeSelector: {}
tolerations: []
affinity: {}
actRunner:
repository: gitea/act_runner
tag: 0.2.6
pullPolicy: IfNotPresent
dementhorr marked this conversation as resolved Outdated

Since config and runnerLabels are only used within the actRunner container, we should move those values settings into actions.statefulset.actRunner to make that clear. It also gives a better understanding for administrators.

Since `config` and `runnerLabels` are only used within the `actRunner` container, we should move those values settings into `actions.statefulset.actRunner` to make that clear. It also gives a better understanding for administrators.
config: |
log:
dementhorr marked this conversation as resolved Outdated
Outdated
Review

I'd remove the Image part from the name. Same for dind.

I'd remove the `Image` part from the name. Same for `dind`.
level: debug
cache:
enabled: false
runner:
labels:
- "ubuntu-latest"
dind:
repository: docker
tag: 25.0.2-dind
dementhorr marked this conversation as resolved Outdated

Since job.enabled: true basically means to automatically connect the runner to Gitea, I suggest renaming the object from job to provisioning or autoConnect. That makes it easier for users to understand its purpose. The fact its a Kubernetes Job is not important for users.

Since `job.enabled: true` basically means to automatically connect the runner to Gitea, I suggest renaming the object from `job` to `provisioning` or `autoConnect`. That makes it easier for users to understand its purpose. The fact its a Kubernetes Job is not important for users.
pullPolicy: IfNotPresent
provisioning:
enabled: false
annotations: {}
labels: {}
resources: {}
nodeSelector: {}
tolerations: []
affinity: {}
token:
repository: gitea/gitea
tag: ""
pullPolicy: IfNotPresent
publish:
repository: bitnami/kubectl
tag: 1.29.0
pullPolicy: IfNotPresent
## Specify an existing token secret
##
existingSecret: ""
existingSecretKey: ""
## @section Gitea
#
gitea: