# Renovate for Gitea Renovate runs as a Kubernetes CronJob and creates container image update pull requests in Gitea. It does not deploy changes itself. ## Kubernetes Create a dedicated Gitea user named `renovate-bot`, create a repository access token, and grant it repository read/write plus issue read/write permissions. Add `read:packages` if Renovate must inspect private Gitea registry images. Create the ignored Secret locally; never commit the PAT: ```sh cp renovate/k8s/secrets.yaml.example renovate/k8s/secrets.yaml $EDITOR renovate/k8s/secrets.yaml kubectl apply -f renovate/k8s/namespace.yaml kubectl apply -f renovate/k8s/secrets.yaml kubectl apply -f renovate/k8s/configmap.yaml kubectl apply -f renovate/k8s/cronjob.yaml ``` The `renovate/k8s/active` marker makes the normal deployment workflow include the namespace, ConfigMap, and CronJob. The Secret is intentionally excluded from Git and must be applied separately after every new cluster. Run it immediately instead of waiting for the six-hour schedule. Two options, both use the same `renovate/renovate.json`: ```sh kubectl create job --from=cronjob/renovate renovate-manual-$(date +%s) -n renovate ``` or the `renovate-run` Actions workflow (Actions tab → `renovate-run` → Run workflow). It runs the same image as the CronJob on the self-hosted runner via Docker — the tag is read out of `renovate/k8s/cronjob.yaml` at run time rather than hardcoded, so the two cannot drift apart. Required Actions secrets (repo or org settings): - `RENOVATE_TOKEN` — renovate-bot PAT (repository + issue read/write). - `RENOVATE_GITHUB_COM_TOKEN` — optional, for changelogs and GitHub rate limits. Inputs: `repositories` (default `forust/homelab`), `log_level` (`info`/`debug`). Only one run at a time (concurrency group `renovate-run`), same as the CronJob `Forbid` policy. Inspect runs with: ```sh kubectl get cronjob,jobs,pods -n renovate kubectl logs -n renovate job/ ``` `RENOVATE_GITHUB_COM_TOKEN` is optional but recommended for changelogs and GitHub API rate limits. Set it in the Kubernetes Secret if available. ## Compose Copy `.env.example` to `.env`, set the PAT, and run: ```sh docker compose -f renovate-compose.yaml run --rm renovate ``` The Compose file is intentionally named `renovate-compose.yaml`, so the repository's automatic deployment discovery does not start it accidentally. ## Configuration `renovate/renovate.json` is the single source of truth. The Compose file and the `renovate-run` workflow mount that file directly. A ConfigMap cannot read from the repository, so the CronJob needs the config inlined. `renovate/k8s/configmap.yaml` is therefore a **generated** copy: ```sh .gitea/workflows/sync-renovate-configmap.sh # regenerate after editing .gitea/workflows/sync-renovate-configmap.sh --check # fail if out of date ``` The `renovate-ci` workflow runs the `--check` form on every PR and push, so a config edit that forgets to regenerate the ConfigMap cannot be merged. Beyond images, `customManagers` in the config track: - Helm chart versions pinned in `.gitea/workflows/deploy-lib.sh`. The built-in `helmv3` manager only reads `Chart.yaml` and `helm-values` only reads values files, so neither sees a version written into a `helm upgrade` command — these are declared as `custom.regex` managers against the `helm` datasource. - CI linter versions in `.gitea/workflows/tool-versions.env`. The Renovate image tag is deliberately _not_ in `tool-versions.env`: `renovate/k8s/cronjob.yaml` owns it, and the workflows read it from there. ## How updates flow Renovate scans both `compose.yaml` files and Kubernetes manifests, opens a branch and PR with image tag changes, and waits for CI. After merge, the existing deployment workflow applies Kubernetes changes or redeploys Compose stacks. Renovate never updates running workloads directly.