From d8685dd5812c7ba34082f83f9dfc6fe159c691fe Mon Sep 17 00:00:00 2001 From: "juvenal.diaz" Date: Sat, 26 Sep 2026 12:31:18 -0600 Subject: [PATCH] Route Gitea actions by homelab operation type --- .gitea/workflows/homelab-main.yml | 52 ++++++++++++++++++++++++++++++- apps/gitea-runner/deployment.yaml | 23 +++++++++++++- apps/gitea-runner/pvc.yaml | 12 +++++++ bootstrap/apps/variables.tf | 9 ++++++ lib/jeannie/pipeline.sh | 5 +++ scripts/classify-gitea-action | 50 +++++++++++++++++++++++++++++ 6 files changed, 149 insertions(+), 2 deletions(-) create mode 100644 apps/gitea-runner/pvc.yaml create mode 100755 scripts/classify-gitea-action diff --git a/.gitea/workflows/homelab-main.yml b/.gitea/workflows/homelab-main.yml index 512eeeb..2f33a43 100644 --- a/.gitea/workflows/homelab-main.yml +++ b/.gitea/workflows/homelab-main.yml @@ -27,7 +27,35 @@ jobs: set -e ./jeannie validate - deploy: + running-update: + runs-on: k8s + container: golang:1.23-bookworm + needs: + - validate + if: ${{ gitea.ref == 'refs/heads/main' }} + steps: + - name: Install Toolchain (Python) + run: | + set -e + apt-get update && apt-get install -y --no-install-recommends python3-yaml + - name: Check out repository + run: | + set -e + git clone --depth 100 https://${{ secrets.GITEATOKEN }}@lab2025.duckdns.org/git/jv/my-homelab-configs.git . + - name: Apply running-homelab update policy + run: | + set -e + classification="$(./scripts/classify-gitea-action)" + printf '%s\n' "${classification}" + mode="$(printf '%s\n' "${classification}" | awk -F= '$1 == "mode" { print $2; exit }')" + if [ "${mode}" != "k8s-update" ]; then + echo "Host-managed create/recreate change detected; Debian runner will handle it." + exit 0 + fi + echo "Running homelab update accepted on the K8s runner." + echo "Argo CD will reconcile repo-managed applications from main." + + debian-ops: runs-on: homelab-debian needs: - validate @@ -37,9 +65,25 @@ jobs: run: | set -e git clone --depth 100 https://${{ secrets.GITEATOKEN }}@lab2025.duckdns.org/git/jv/my-homelab-configs.git . + - name: Select Debian host operation policy + run: | + set -e + classification="$(./scripts/classify-gitea-action)" + printf '%s\n' "${classification}" + mode="$(printf '%s\n' "${classification}" | awk -F= '$1 == "mode" { print $2; exit }')" + if [ "${mode}" != "debian-ops" ]; then + echo "App-only running-homelab update; K8s runner handled this path." + exit 0 + fi - name: Block automatic deploy for external Gitea changes run: | set -e + classification="$(./scripts/classify-gitea-action)" + mode="$(printf '%s\n' "${classification}" | awk -F= '$1 == "mode" { print $2; exit }')" + if [ "${mode}" != "debian-ops" ]; then + echo "Skipping Debian deploy guard for app-only update." + exit 0 + fi event_before="$( python3 -c 'import json, os; p = os.environ.get("GITHUB_EVENT_PATH", ""); print(json.load(open(p, encoding="utf-8")).get("before", "") if p and os.path.exists(p) else "")' @@ -138,6 +182,12 @@ jobs: - name: Deploy main branch run: | set -e + classification="$(./scripts/classify-gitea-action)" + mode="$(printf '%s\n' "${classification}" | awk -F= '$1 == "mode" { print $2; exit }')" + if [ "${mode}" != "debian-ops" ]; then + echo "Skipping Debian Jeannie execution for app-only update." + exit 0 + fi workspace_dir="${PWD}" deploy_dir="${HOMELAB_DEPLOY_DIR:-}" diff --git a/apps/gitea-runner/deployment.yaml b/apps/gitea-runner/deployment.yaml index 932de9a..3f249ee 100644 --- a/apps/gitea-runner/deployment.yaml +++ b/apps/gitea-runner/deployment.yaml @@ -13,9 +13,25 @@ spec: labels: app: gitea-runner spec: + nodeSelector: + kubernetes.io/hostname: debian + tolerations: + - key: node-role.kubernetes.io/control-plane + operator: Exists + effect: NoSchedule + - key: node-role.kubernetes.io/master + operator: Exists + effect: NoSchedule containers: - name: runner - image: gitea/act_runner:latest + image: gitea/act_runner:0.2.11 + resources: + requests: + cpu: 50m + memory: 128Mi + limits: + cpu: 500m + memory: 512Mi env: - name: GITEA_INSTANCE_URL valueFrom: @@ -32,9 +48,14 @@ spec: - name: GITEA_RUNNER_LABELS value: "k8s,ubuntu-latest:docker://node:18-bullseye,debian-latest:docker://node:18-bullseye" volumeMounts: + - name: runner-data + mountPath: /data - name: docker-sock mountPath: /var/run/docker.sock volumes: + - name: runner-data + persistentVolumeClaim: + claimName: gitea-runner-data - name: docker-sock hostPath: path: /var/run/docker.sock diff --git a/apps/gitea-runner/pvc.yaml b/apps/gitea-runner/pvc.yaml new file mode 100644 index 0000000..e46902d --- /dev/null +++ b/apps/gitea-runner/pvc.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: gitea-runner-data + namespace: gitea-runner +spec: + accessModes: + - ReadWriteOnce + storageClassName: openebs-hostpath-retain + resources: + requests: + storage: 1Gi diff --git a/bootstrap/apps/variables.tf b/bootstrap/apps/variables.tf index fbcde01..c2f2c3d 100644 --- a/bootstrap/apps/variables.tf +++ b/bootstrap/apps/variables.tf @@ -104,6 +104,15 @@ variable "applications" { self_heal = true create_namespace = false } + gitea-runner = { + project = "default" + path = "apps/gitea-runner" + namespace = "gitea-runner" + target_revision = "main" + prune = true + self_heal = true + create_namespace = true + } security-lab = { project = "default" path = "apps/security-lab" diff --git a/lib/jeannie/pipeline.sh b/lib/jeannie/pipeline.sh index 005aab3..b8a40d4 100644 --- a/lib/jeannie/pipeline.sh +++ b/lib/jeannie/pipeline.sh @@ -5430,6 +5430,11 @@ apps() { wait_for_namespaced_resource n8n deployment n8n n8n "${app_resource_wait_seconds}" wait_for_deployment_ready n8n n8n n8n "${app_ready_wait_seconds}" + refresh_argocd_application gitea-runner + wait_for_namespace gitea-runner gitea-runner "${app_resource_wait_seconds}" + wait_for_namespaced_resource gitea-runner deployment gitea-runner gitea-runner "${app_resource_wait_seconds}" + wait_for_deployment_ready gitea-runner gitea-runner gitea-runner "${app_ready_wait_seconds}" + echo "Application deployment successfully completed." } diff --git a/scripts/classify-gitea-action b/scripts/classify-gitea-action new file mode 100755 index 0000000..3ae897c --- /dev/null +++ b/scripts/classify-gitea-action @@ -0,0 +1,50 @@ +#!/usr/bin/env bash +set -euo pipefail + +base_ref="${1:-}" + +if [[ -z "${base_ref}" ]]; then + base_ref="$( + python3 - <<'PY' +import json +import os + +path = os.environ.get("GITHUB_EVENT_PATH", "") +if path and os.path.exists(path): + with open(path, encoding="utf-8") as handle: + print(json.load(handle).get("before", "")) +PY + )" +fi + +if [[ -z "${base_ref}" || "${base_ref}" =~ ^0+$ ]]; then + base_ref="$(git rev-parse HEAD^ 2>/dev/null || git hash-object -t tree /dev/null)" +fi + +changed_files="$(git diff --name-only "${base_ref}" HEAD)" + +mode="k8s-update" +while IFS= read -r path; do + [[ -n "${path}" ]] || continue + case "${path}" in + .gitea/workflows/* | \ + bootstrap/apps/* | \ + bootstrap/cluster/* | \ + bootstrap/edge/* | \ + bootstrap/host/* | \ + bootstrap/platform/* | \ + bootstrap/provisioning/* | \ + homelab.yml | \ + infra/gitea/* | \ + jeannie | \ + lib/jeannie/* | \ + scripts/*) + mode="debian-ops" + break + ;; + esac +done <<<"${changed_files}" + +printf 'mode=%s\n' "${mode}" +printf 'base_ref=%s\n' "${base_ref}" +printf '%s\n' "${changed_files}" | sed '/^$/d'