From 05de03d1d3fc64d9f8f3061825a93dbd050befb3 Mon Sep 17 00:00:00 2001 From: kisfenyo Date: Wed, 27 May 2026 21:27:35 +0200 Subject: [PATCH] admin-system: add Renovate Bot pilot (CronJob + config) Self-hosted Renovate as a weekly CronJob (Sun 04:00 Europe/Budapest) opening dependency-update PRs against admin/homelab-manifests on Gitea. Pilot is deliberately narrow: - Only the kubernetes + helm-values managers are enabled. - Default-deny packageRule; only four images may update: opengist, uptime-kuma, gokapi, cal.com. - minor/patch -> PR with Gitea native auto-merge (platformAutomerge). - major -> held for manual approval via Dependency Dashboard checkbox. Image pinned to renovate/renovate:43.197.0 (the plain tag is the minimal image; the -slim suffix was retired upstream after v37.440.x). Stateless: no Service/Ingress/PVC. Read-only root FS with a 2Gi /tmp emptyDir for git clones + cache. Secrets from existing renovate-secrets. Co-Authored-By: Claude Opus 4.7 (1M context) --- admin-system/renovate.yaml | 175 +++++++++++++++++++++++++++++++++++++ 1 file changed, 175 insertions(+) create mode 100644 admin-system/renovate.yaml diff --git a/admin-system/renovate.yaml b/admin-system/renovate.yaml new file mode 100644 index 0000000..ce39ffc --- /dev/null +++ b/admin-system/renovate.yaml @@ -0,0 +1,175 @@ +# ============================================ +# Renovate Bot - Self-hosted dependency updater +# ============================================ +# https://docs.renovatebot.com +# Image: renovate/renovate (plain tag = minimal image, "formerly slim"; +# -slim suffix was retired after v37.440.x, so we pin the plain tag) +# +# PILOT SCOPE (intentionally narrow): +# Runs weekly (Sun 04:00 Europe/Budapest) as a CronJob and opens +# dependency-update PRs against admin/homelab-manifests on Gitea. +# Only the `kubernetes` and `helm-values` managers are enabled, and a +# default-deny packageRule limits updates to exactly four pilot images: +# - ghcr.io/thomiceli/opengist +# - louislam/uptime-kuma +# - f0rc3/gokapi +# - docker.io/calcom/cal.com +# minor/patch -> PR with Gitea native auto-merge; major -> waits for +# manual approval via a checkbox on the Dependency Dashboard issue. +# +# Stateless & ephemeral: no Service, Ingress, or PVC. Writable /tmp is an +# emptyDir (root FS is read-only); Renovate uses it for git clones + cache. +# +# Secrets (created manually, NOT in git) come from Secret `renovate-secrets`: +# - RENOVATE_TOKEN (Gitea PAT) +# - RENOVATE_GITHUB_COM_TOKEN (GitHub PAT, for release notes) +# ============================================ +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: renovate-config + namespace: admin-system + labels: + app.kubernetes.io/instance: renovate + app.kubernetes.io/name: renovate +data: + config.json: | + { + "platform": "gitea", + "endpoint": "https://gitea.dooplex.hu/api/v1", + "gitAuthor": "Renovate Bot ", + "repositories": ["admin/homelab-manifests"], + "onboarding": false, + "requireConfig": "optional", + "dependencyDashboard": true, + "dependencyDashboardTitle": "Renovate Dependency Dashboard", + "prHourlyLimit": 0, + "prConcurrentLimit": 0, + "enabledManagers": ["kubernetes", "helm-values"], + "kubernetes": { + "managerFilePatterns": ["/.+\\.ya?ml$/"] + }, + "packageRules": [ + { + "matchPackageNames": ["*"], + "enabled": false + }, + { + "matchPackageNames": [ + "ghcr.io/thomiceli/opengist", + "louislam/uptime-kuma", + "f0rc3/gokapi", + "docker.io/calcom/cal.com" + ], + "enabled": true + }, + { + "matchPackageNames": [ + "ghcr.io/thomiceli/opengist", + "louislam/uptime-kuma", + "f0rc3/gokapi", + "docker.io/calcom/cal.com" + ], + "matchUpdateTypes": ["minor", "patch"], + "automerge": true, + "platformAutomerge": true, + "automergeType": "pr" + }, + { + "matchPackageNames": [ + "ghcr.io/thomiceli/opengist", + "louislam/uptime-kuma", + "f0rc3/gokapi", + "docker.io/calcom/cal.com" + ], + "matchUpdateTypes": ["major"], + "automerge": false, + "dependencyDashboardApproval": true + } + ], + "labels": ["renovate"] + } +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: renovate + namespace: admin-system + labels: + app.kubernetes.io/instance: renovate + app.kubernetes.io/name: renovate + app.kubernetes.io/version: "43.197.0" +spec: + schedule: "0 4 * * 0" + timeZone: "Europe/Budapest" + concurrencyPolicy: Forbid + successfulJobsHistoryLimit: 3 + failedJobsHistoryLimit: 3 + startingDeadlineSeconds: 600 + jobTemplate: + metadata: + labels: + app.kubernetes.io/instance: renovate + app.kubernetes.io/name: renovate + app.kubernetes.io/version: "43.197.0" + spec: + template: + metadata: + labels: + app.kubernetes.io/instance: renovate + app.kubernetes.io/name: renovate + app.kubernetes.io/version: "43.197.0" + annotations: + # Renovate uses plain X.Y.Z semver tags (no -slim suffix anymore) + match-regex.version-checker.io/renovate: '^\d+\.\d+\.\d+$' + spec: + enableServiceLinks: false + restartPolicy: OnFailure + containers: + - name: renovate + image: renovate/renovate:43.197.0 + imagePullPolicy: IfNotPresent + envFrom: + - secretRef: + name: renovate-secrets + env: + - name: TZ + value: Europe/Budapest + - name: LOG_LEVEL + value: info + - name: RENOVATE_CONFIG_FILE + value: /config/config.json + # Renovate needs a writable tmp for git clones + cache; + # root FS is read-only so point it at the emptyDir below. + - name: TMPDIR + value: /tmp + resources: + requests: + cpu: 100m + memory: 256Mi + limits: + cpu: 2000m + memory: 2Gi + securityContext: + runAsNonRoot: true + runAsUser: 12021 + runAsGroup: 0 + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + capabilities: + drop: + - ALL + volumeMounts: + - name: config + mountPath: /config + readOnly: true + - name: tmp + mountPath: /tmp + volumes: + - name: config + configMap: + name: renovate-config + - name: tmp + emptyDir: + sizeLimit: 2Gi