# Per-Repository Renovate Configurations * Status: accepted * Date: 2026-02-13 * Deciders: Billy * Technical Story: Roll out Renovate configs to all application repos so the self-hosted CronJob (ADR-0036) can scan them for dependency and security updates ## Context and Problem Statement ADR-0036 deployed a **self-hosted Renovate CronJob** that auto-discovers all `daviestechlabs/*` repos, and the `homelab-k8s2` GitOps repo already has a detailed `.renovaterc.json5`. However, none of the application repositories contain a `renovate.json` yet, which means: - Renovate falls back to its bare defaults (no grouping, no auto-merge, no schedule control). - Python repos with both `pyproject.toml` and `requirements.txt` get duplicate PRs. - No security-update fast-path is configured. - Major updates are auto-merged without review because no rule prevents it. We need a consistent per-repo configuration that applies the correct managers, grouping, auto-merge policy, and security rules to every repo. ## Decision Drivers * Consistent behaviour across all repos in the org * Correct manager selection per ecosystem (Python/Go/Node/Docker) * Security updates treated with highest priority * Non-major updates grouped and auto-merged to reduce PR noise * Major updates require manual review * Schedule aligned with CI runner availability ## Considered Options 1. **Shared org-preset in a dedicated `renovate-config` repo** 2. **Identical standalone `renovate.json` copied into every repo** 3. **No per-repo config (rely on autodiscover defaults)** ## Decision Outcome Chosen option: **Option 1 — Shared org-preset with thin per-repo `renovate.json`** A central `renovate-config` repo holds a `default.json` preset that every application repo extends. Repo-specific overrides (extra managers, ignored paths) live in each repo's `renovate.json`. This keeps configuration DRY while allowing per-repo tailoring. ### Positive Consequences * Single place to update grouping strategy, schedule, and auto-merge policy * Each repo's `renovate.json` is 5-10 lines — easy to audit * Security updates auto-merge immediately across all repos * Major updates always require manual review ### Negative Consequences * Extra repository (`renovate-config`) to maintain * Preset changes propagate to all repos on next run — regressions possible ## Shared Preset (`renovate-config` repo) ### `default.json` ```json { "$schema": "https://docs.renovatebot.com/renovate-schema.json", "description": "DaviesTechLabs shared Renovate preset for application repos", "extends": [ "config:recommended", "group:allNonMajor", ":automergeMinor", ":automergePatch", ":semanticCommits" ], "dependencyDashboard": true, "platformAutomerge": true, "schedule": ["before 6am on monday"], "timezone": "America/New_York", "prCreation": "immediate", "vulnerabilityAlerts": { "enabled": true, "labels": ["security"] }, "packageRules": [ { "description": "Auto-merge security updates immediately", "matchCategories": ["security"], "automerge": true, "schedule": ["at any time"], "prPriority": 10 }, { "description": "Major updates require manual review", "matchUpdateTypes": ["major"], "automerge": false, "labels": ["major-update"] }, { "description": "Group Gitea Actions updates", "matchManagers": ["gitea-actions"], "groupName": "gitea-actions" }, { "description": "Group Docker base-image updates", "matchManagers": ["dockerfile"], "groupName": "docker-base-images" }, { "description": "Pin uv in CI to digest for reproducibility", "matchManagers": ["gitea-actions"], "matchPackageNames": ["astral-sh/setup-uv"], "pinDigests": true } ] } ``` ### `python.json` (supplemental preset for Python repos) ```json { "$schema": "https://docs.renovatebot.com/renovate-schema.json", "description": "Python-specific rules for uv/pip repos", "packageRules": [ { "description": "Group Python dev dependencies", "matchManagers": ["pep621", "pip_requirements"], "matchDepTypes": ["devDependencies", "optional-dependencies"], "groupName": "python-dev-deps" }, { "description": "Prefer pyproject.toml over requirements.txt when both exist", "matchManagers": ["pip_requirements"], "matchFileNames": ["requirements.txt"], "enabled": false } ] } ``` ### `golang.json` (supplemental preset for Go repos) ```json { "$schema": "https://docs.renovatebot.com/renovate-schema.json", "description": "Go-specific rules", "packageRules": [ { "description": "Group all Go module updates", "matchManagers": ["gomod"], "groupName": "go-modules" } ], "postUpdateOptions": ["gomodTidy"] } ``` ## Per-Repo Configuration Each application repo gets a minimal `renovate.json` that extends the org preset. ### Python repos (chat-handler, voice-assistant, handler-base, pipeline-bridge, stt-module, tts-module, ray-serve, mlflow, gradio-ui) ```json { "$schema": "https://docs.renovatebot.com/renovate-schema.json", "extends": [ "local>daviestechlabs/renovate-config", "local>daviestechlabs/renovate-config:python" ] } ``` ### Go repos (companions-frontend, ntfy-discord) ```json { "$schema": "https://docs.renovatebot.com/renovate-schema.json", "extends": [ "local>daviestechlabs/renovate-config", "local>daviestechlabs/renovate-config:golang" ] } ``` ### companions-frontend (Go + Node hybrid) ```json { "$schema": "https://docs.renovatebot.com/renovate-schema.json", "extends": [ "local>daviestechlabs/renovate-config", "local>daviestechlabs/renovate-config:golang" ], "packageRules": [ { "description": "Group npm dev dependencies", "matchManagers": ["npm"], "matchDepTypes": ["devDependencies"], "groupName": "npm-dev-deps" } ] } ``` ## Repo Coverage Matrix | Repository | Ecosystem | Preset(s) | Notes | |---|---|---|---| | homelab-k8s2 | Helm/Flux/K8s/Docker | Own `.renovaterc.json5` | Already configured | | chat-handler | Python, Docker, Gitea Actions | default + python | | | voice-assistant | Python, Docker, Gitea Actions | default + python | | | handler-base | Python, Docker, Gitea Actions | default + python | | | pipeline-bridge | Python, Docker, Gitea Actions | default + python | | | stt-module | Python, Docker, Gitea Actions | default + python | requirements.txt disabled | | tts-module | Python, Docker, Gitea Actions | default + python | requirements.txt disabled | | ray-serve | Python, Gitea Actions | default + python | requirements.txt disabled | | mlflow | Python, Gitea Actions | default + python | requirements.txt disabled | | gradio-ui | Python (requirements.txt only), Docker | default + python | No pyproject.toml — requirements.txt stays enabled | | kuberay-images | Python (amdsmi-shim), Docker | default + python | Multiple Dockerfiles | | companions-frontend | Go, Node, Docker | default + golang + npm | Hybrid repo | | ntfy-discord | Go, Docker, Gitea Actions | default + golang | | | kubeflow | Gitea Actions only | default | Pipeline definitions only | | argo | None | default | Workflow templates only | ## Update Flow ``` Renovate CronJob (every 8h) │ ▼ Autodiscover daviestechlabs/* │ ▼ Read repo's renovate.json │ ├── extends local>daviestechlabs/renovate-config │ │ │ └── Fetches default.json + python.json/golang.json │ ▼ Scan dependencies (pyproject.toml, Dockerfile, go.mod, etc.) │ ▼ Create/update PRs │ ├── Security → auto-merge immediately ├── Patch/Minor → auto-merge (minor after 3-day stabilisation) └── Major → label "major-update", await manual review ``` ## Links * Supersedes: nothing (extends [ADR-0036](0036-renovate-dependency-updates.md)) * Related: [ADR-0036](0036-renovate-dependency-updates.md) — Renovate CronJob deployment * Related: [ADR-0013](0013-gitea-actions-for-ci.md) — Gitea Actions for CI * Related: [ADR-0031](0031-gitea-cicd-strategy.md) — Gitea CI/CD Strategy * Related: [ADR-0012](0012-use-uv-for-python-development.md) — uv for Python development * [Renovate Shareable Config Presets](https://docs.renovatebot.com/config-presets/)