updating to match everything in my homelab.
This commit is contained in:
256
decisions/0036-renovate-dependency-updates.md
Normal file
256
decisions/0036-renovate-dependency-updates.md
Normal file
@@ -0,0 +1,256 @@
|
||||
# Automated Dependency Updates with Renovate
|
||||
|
||||
* Status: accepted
|
||||
* Date: 2026-02-05
|
||||
* Deciders: Billy
|
||||
* Technical Story: Automate dependency updates across all homelab repositories
|
||||
|
||||
## Context and Problem Statement
|
||||
|
||||
The homelab consists of 20+ repositories containing:
|
||||
- Kubernetes manifests with container image references
|
||||
- Helm chart versions
|
||||
- Python/Go dependencies
|
||||
- GitHub Actions / Gitea Actions workflow versions
|
||||
|
||||
Manually tracking and updating dependencies is:
|
||||
- Time-consuming
|
||||
- Error-prone
|
||||
- Often neglected until security issues arise
|
||||
|
||||
How do we automate dependency updates while maintaining control over what gets updated?
|
||||
|
||||
## Decision Drivers
|
||||
|
||||
* Automated detection of outdated dependencies
|
||||
* PR-based update workflow for review
|
||||
* Support for Kubernetes manifests, Helm, Python, Go, Docker
|
||||
* Self-hosted on existing infrastructure
|
||||
* Configurable grouping and scheduling
|
||||
* Security update prioritization
|
||||
|
||||
## Considered Options
|
||||
|
||||
1. **Renovate (self-hosted)**
|
||||
2. **Dependabot (GitHub-native)**
|
||||
3. **Manual updates with version scripts**
|
||||
4. **Flux image automation**
|
||||
|
||||
## Decision Outcome
|
||||
|
||||
Chosen option: **Option 1 - Renovate (self-hosted)**
|
||||
|
||||
Renovate runs as a CronJob in the cluster, scanning all repositories in the Gitea organization and creating PRs for outdated dependencies. It supports more package managers than Dependabot and works with Gitea.
|
||||
|
||||
### Positive Consequences
|
||||
|
||||
* Comprehensive manager support (40+ package managers)
|
||||
* Works with self-hosted Gitea
|
||||
* Configurable grouping (batch minor updates)
|
||||
* Auto-merge for patch/minor updates
|
||||
* Dashboard for update overview
|
||||
* Reusable preset configurations
|
||||
|
||||
### Negative Consequences
|
||||
|
||||
* Additional CronJob to maintain
|
||||
* Configuration complexity
|
||||
* API token management for Gitea access
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
┌───────────────────────────────────────────────────────────────────┐
|
||||
│ Renovate CronJob │
|
||||
│ (ci-cd namespace) │
|
||||
│ │
|
||||
│ Schedule: Every 8 hours (0 */8 * * *) │
|
||||
│ │
|
||||
│ ┌────────────────────────────────────────────────────────────┐ │
|
||||
│ │ Renovate Container │ │
|
||||
│ │ │ │
|
||||
│ │ 1. Fetch repositories from Gitea org │ │
|
||||
│ │ 2. Scan each repo for dependencies │ │
|
||||
│ │ 3. Compare versions with upstream registries │ │
|
||||
│ │ 4. Create/update PRs for outdated deps │ │
|
||||
│ │ 5. Auto-merge approved patches │ │
|
||||
│ └────────────────────────────────────────────────────────────┘ │
|
||||
└───────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌───────────────────────────────────────────────────────────────────┐
|
||||
│ Gitea │
|
||||
│ │
|
||||
│ ┌───────────────┐ ┌───────────────┐ ┌───────────────┐ │
|
||||
│ │ homelab-k8s2 │ │ chat-handler │ │ kuberay-images│ │
|
||||
│ │ │ │ │ │ │ │
|
||||
│ │ PR: Update │ │ PR: Update │ │ PR: Update │ │
|
||||
│ │ flux to 2.5.0 │ │ httpx to 0.28 │ │ ROCm to 6.4 │ │
|
||||
│ └───────────────┘ └───────────────┘ └───────────────┘ │
|
||||
└───────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
### CronJob
|
||||
|
||||
```yaml
|
||||
apiVersion: batch/v1
|
||||
kind: CronJob
|
||||
metadata:
|
||||
name: renovate
|
||||
namespace: ci-cd
|
||||
spec:
|
||||
schedule: "0 */8 * * *" # Every 8 hours
|
||||
jobTemplate:
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: renovate
|
||||
image: renovate/renovate:39
|
||||
env:
|
||||
- name: RENOVATE_PLATFORM
|
||||
value: "gitea"
|
||||
- name: RENOVATE_ENDPOINT
|
||||
value: "https://git.daviestechlabs.io/api/v1"
|
||||
- name: RENOVATE_TOKEN
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: renovate-github-token
|
||||
key: token
|
||||
- name: RENOVATE_AUTODISCOVER
|
||||
value: "true"
|
||||
- name: RENOVATE_AUTODISCOVER_FILTER
|
||||
value: "daviestechlabs/*"
|
||||
restartPolicy: OnFailure
|
||||
```
|
||||
|
||||
### Repository Config (renovate.json)
|
||||
|
||||
```json
|
||||
{
|
||||
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||
"extends": [
|
||||
"config:recommended",
|
||||
"group:allNonMajor",
|
||||
":automergeMinor",
|
||||
":automergePatch"
|
||||
],
|
||||
"kubernetes": {
|
||||
"fileMatch": ["\\.ya?ml$"]
|
||||
},
|
||||
"packageRules": [
|
||||
{
|
||||
"matchManagers": ["helm-values", "helmv3"],
|
||||
"groupName": "helm charts"
|
||||
},
|
||||
{
|
||||
"matchPackagePatterns": ["^ghcr.io/"],
|
||||
"groupName": "GHCR images"
|
||||
},
|
||||
{
|
||||
"matchUpdateTypes": ["major"],
|
||||
"automerge": false,
|
||||
"labels": ["major-update"]
|
||||
}
|
||||
],
|
||||
"schedule": ["before 6am on monday"]
|
||||
}
|
||||
```
|
||||
|
||||
## Supported Package Managers
|
||||
|
||||
| Manager | File Patterns | Examples |
|
||||
|---------|---------------|----------|
|
||||
| kubernetes | `*.yaml`, `*.yml` | Container images in Deployments |
|
||||
| helm | `Chart.yaml`, `values.yaml` | Helm chart dependencies |
|
||||
| helmv3 | HelmRelease CRDs | Flux HelmReleases |
|
||||
| flux | Flux CRDs | GitRepository, OCIRepository |
|
||||
| pip | `requirements.txt`, `pyproject.toml` | Python packages |
|
||||
| gomod | `go.mod` | Go modules |
|
||||
| dockerfile | `Dockerfile*` | Base images |
|
||||
| github-actions | `.github/workflows/*.yml` | Action versions |
|
||||
| gitea-actions | `.gitea/workflows/*.yml` | Action versions |
|
||||
|
||||
## Update Strategy
|
||||
|
||||
### Auto-merge Enabled
|
||||
|
||||
| Update Type | Auto-merge | Delay |
|
||||
|-------------|------------|-------|
|
||||
| Patch (x.x.1 → x.x.2) | ✅ Yes | Immediate |
|
||||
| Minor (x.1.x → x.2.x) | ✅ Yes | 3 days stabilization |
|
||||
| Major (1.x.x → 2.x.x) | ❌ No | Manual review |
|
||||
|
||||
### Grouping Strategy
|
||||
|
||||
| Group | Contents | Frequency |
|
||||
|-------|----------|-----------|
|
||||
| `all-non-major` | All patch + minor updates | Weekly (Monday) |
|
||||
| `helm-charts` | All Helm chart updates | Weekly |
|
||||
| `container-images` | Docker image updates | Weekly |
|
||||
| `security` | CVE fixes | Immediate |
|
||||
|
||||
## Security Updates
|
||||
|
||||
Renovate prioritizes security updates:
|
||||
|
||||
```json
|
||||
{
|
||||
"vulnerabilityAlerts": {
|
||||
"enabled": true,
|
||||
"labels": ["security"]
|
||||
},
|
||||
"packageRules": [
|
||||
{
|
||||
"matchCategories": ["security"],
|
||||
"automerge": true,
|
||||
"schedule": ["at any time"],
|
||||
"prPriority": 10
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Dashboard
|
||||
|
||||
Renovate creates a "Dependency Dashboard" issue in each repository:
|
||||
|
||||
```markdown
|
||||
## Dependency Dashboard
|
||||
|
||||
### Open PRs
|
||||
- [ ] Update httpx to 0.28.1 (#42)
|
||||
- [x] Update pillow to 11.0.0 (#41) - merged
|
||||
|
||||
### Pending Approval
|
||||
- [ ] Major: Update pydantic to v2 (#40)
|
||||
|
||||
### Rate Limited
|
||||
- fastapi (waiting for next schedule window)
|
||||
```
|
||||
|
||||
## Secrets
|
||||
|
||||
| Secret | Source | Purpose |
|
||||
|--------|--------|---------|
|
||||
| `renovate-github-token` | Vault | Gitea API access |
|
||||
| `renovate-dockerhub` | Vault | Docker Hub rate limits |
|
||||
|
||||
## Monitoring
|
||||
|
||||
```promql
|
||||
# Renovate job success rate
|
||||
sum(kube_job_status_succeeded{job_name=~"renovate-.*"})
|
||||
/
|
||||
sum(kube_job_status_succeeded{job_name=~"renovate-.*"} + kube_job_status_failed{job_name=~"renovate-.*"})
|
||||
```
|
||||
|
||||
## Links
|
||||
|
||||
* [Renovate Documentation](https://docs.renovatebot.com/)
|
||||
* [Renovate Presets](https://docs.renovatebot.com/presets-default/)
|
||||
* [Gitea Platform Support](https://docs.renovatebot.com/modules/platform/gitea/)
|
||||
* 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
|
||||
Reference in New Issue
Block a user