# Gitea Actions runner for the dezky monorepo, in-cluster on node1.
#
# Builds + pushes app images (platform-api / portal / booking) to the Gitea
# container registry on push. A privileged docker:dind sidecar provides the
# Docker daemon the runner's jobs use for `docker build`/`buildx` — k3s itself
# only has containerd, no Docker daemon.
#
# The registration token is NOT in git — create the 'gitea-runner-token' Secret
# out-of-band:
#   kubectl -n gitea-runner create secret generic gitea-runner-token \
#     --from-literal=token=<gitea registration token>
# act_runner auto-registers on first start (persisted on the runner-data PVC).
apiVersion: v1
kind: Namespace
metadata:
  name: gitea-runner
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: runner-data
  namespace: gitea-runner
spec:
  accessModes: [ReadWriteOnce]
  storageClassName: longhorn
  resources:
    requests:
      storage: 2Gi
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: act-runner-config
  namespace: gitea-runner
data:
  config.yaml: |
    log:
      level: info
    runner:
      # Some parallelism without overloading the single shared dind daemon
      # (concurrent container teardowns trigger moby's cgroup-v2 removal
      # deadlock). 2 is a safe balance on this node.
      capacity: 2
      timeout: 3h
      labels:
        - "ubuntu-latest:docker://catthehacker/ubuntu:act-22.04"
        - "docker:docker://docker:27-cli"
    cache:
      # We don't use the Actions cache (setup-node cache was removed); disabling
      # avoids the cache server the DinD job containers can't reach anyway.
      enabled: false
    container:
      # "" = find an available docker host automatically AND expose it to job
      # containers (the dind daemon's socket gets bind-mounted into jobs, which
      # is what `docker build` in the build jobs needs). gitea/runner 1.x no
      # longer does this by default — act_runner 0.2.x did.
      docker_host: ""
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: act-runner
  namespace: gitea-runner
  labels:
    app: act-runner
spec:
  replicas: 1
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: act-runner
  template:
    metadata:
      labels:
        app: act-runner
    spec:
      containers:
        - name: runner
          # gitea/runner is the successor of the deprecated gitea/act_runner.
          # act_runner 0.2.11 + Gitea 1.26 left finished jobs stuck "Running" —
          # the runner completed and freed slots, but Gitea never registered the
          # completion, so dependent jobs (build → deploy) were never dispatched.
          # Same config format / env vars / .runner registration file.
          image: gitea/runner:1.0.8
          env:
            - name: GITEA_INSTANCE_URL
              value: https://git.lastcloud.io
            - name: GITEA_RUNNER_REGISTRATION_TOKEN
              valueFrom:
                secretKeyRef:
                  name: gitea-runner-token
                  key: token
            - name: GITEA_RUNNER_NAME
              value: dezky-k3s
            # Map ubuntu-latest (used by .gitea/workflows/ci.yml) to a Docker
            # image with the usual build tooling; jobs run via the dind sidecar.
            - name: GITEA_RUNNER_LABELS
              value: "ubuntu-latest:docker://catthehacker/ubuntu:act-22.04,docker:docker://docker:27-cli"
            # No DOCKER_HOST: the runner auto-finds the dind daemon's unix
            # socket on the shared /var/run volume. A unix socket (unlike the
            # old tcp://localhost:2376) is the only kind of docker host the
            # runner can bind-mount into job containers — and the bind is
            # resolved by dockerd inside dind, where the path exists too — so
            # `docker build` works inside the build jobs.
            - name: CONFIG_FILE
              value: /config/config.yaml
          volumeMounts:
            - name: runner-data
              mountPath: /data
            - name: docker-run
              mountPath: /var/run
            - name: runner-config
              mountPath: /config
        - name: dind
          # docker:24-dind — moby 24 avoids the cgroup-v2 container-removal
          # deadlock seen on 27 ("removal of container … is already in
          # progress" looping → "Complete job" hangs).
          image: docker:24-dind
          securityContext:
            privileged: true
          env:
            - name: DOCKER_TLS_CERTDIR
              value: /certs
          volumeMounts:
            - name: docker-certs
              mountPath: /certs
            # dockerd serves /var/run/docker.sock here; sharing the volume
            # hands that socket to the runner container above.
            - name: docker-run
              mountPath: /var/run
            - name: dind-storage
              mountPath: /var/lib/docker
      volumes:
        - name: runner-data
          persistentVolumeClaim:
            claimName: runner-data
        - name: docker-certs
          emptyDir: {}
        - name: docker-run
          emptyDir: {}
        - name: dind-storage
          emptyDir: {}
        - name: runner-config
          configMap:
            name: act-runner-config
