chore(renovate): move config under renovate/ and validate it in CI
The config lived in renovate.json at the repo root while everything else Renovate-related sat under renovate/, and renovate/config.js was a second, unused source of truth. Both are gone: renovate/renovate.json is now the only config file. Because the CronJob in the cluster cannot read the repository, its ConfigMap carries an inlined copy of the config. That copy is generated, and sync-renovate-configmap.sh --check now fails the build when it drifts from the source file. The workflows also stop carrying a copy of the renovate/renovate image tag. They read it from renovate/k8s/cronjob.yaml, so the version validated in CI is the version that actually runs in the cluster. ci.yaml validates the config with renovate-config-validator, checks the generated ConfigMap, and kubeconforms the CronJob's own manifests.
This commit is contained in:
1 parent
f22793e32e
commit
7ce727bc8a
10 files changed
+410
-173
No files matched your search
@@ -10,30 +10,52 @@ on:
|
||||
jobs:
|
||||
validate-renovate:
|
||||
runs-on: [self-hosted, linux, arch, homelab]
|
||||
timeout-minutes: 20
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
|
||||
|
||||
- name: Validate Renovate Compose draft
|
||||
# renovate/k8s/cronjob.yaml is the single source of truth for the image tag,
|
||||
# so the same version that runs in the cluster is the one validated here.
|
||||
- name: Resolve the deployed Renovate image
|
||||
id: image
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
trap 'rm -f renovate/.env' EXIT
|
||||
printf '%s\n' \
|
||||
'RENOVATE_ENDPOINT=https://gitea.example/api/v1' \
|
||||
'RENOVATE_TOKEN=test-token' \
|
||||
'RENOVATE_REPOSITORIES=forust/homelab' \
|
||||
> renovate/.env
|
||||
docker compose -f renovate/renovate-compose.yaml config --quiet
|
||||
image="$(sed -n 's|.*image:[[:space:]]*\(renovate/renovate:[^[:space:]]*\).*|\1|p' \
|
||||
renovate/k8s/cronjob.yaml | head -1)"
|
||||
if [ -z "$image" ]; then
|
||||
echo "::error::no renovate/renovate image found in renovate/k8s/cronjob.yaml"
|
||||
exit 1
|
||||
fi
|
||||
echo "using $image"
|
||||
echo "image=$image" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Validate Kubernetes manifests
|
||||
- name: Validate Renovate repository config
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
docker run --rm \
|
||||
-v "$PWD:/work" \
|
||||
-w /work \
|
||||
ghcr.io/yannh/kubeconform:latest \
|
||||
-v "$PWD/renovate:/opt/renovate:ro" \
|
||||
-e RENOVATE_CONFIG_FILE=/opt/renovate/renovate.json \
|
||||
"${{ steps.image.outputs.image }}" \
|
||||
renovate-config-validator /opt/renovate/renovate.json
|
||||
|
||||
# The CronJob cannot read the repository, so renovate/k8s/configmap.yaml
|
||||
# carries an inlined copy of the config. Fail if it no longer matches.
|
||||
- name: Check the generated Renovate ConfigMap
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
./.gitea/workflows/sync-renovate-configmap.sh --check
|
||||
|
||||
- name: Validate Renovate Kubernetes manifests
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
tools_dir="$(bash .gitea/workflows/install-ci-tools.sh kubeconform)"
|
||||
export PATH="$tools_dir:$PATH"
|
||||
kubeconform \
|
||||
-strict \
|
||||
-ignore-missing-schemas \
|
||||
-summary \
|
||||
@@ -41,12 +63,11 @@ jobs:
|
||||
renovate/k8s/configmap.yaml \
|
||||
renovate/k8s/cronjob.yaml
|
||||
|
||||
- name: Validate Renovate repository config
|
||||
- name: Validate Renovate Compose file
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
docker run --rm \
|
||||
-v "$PWD:/work" \
|
||||
-w /work \
|
||||
renovate/renovate:44.103.0 \
|
||||
renovate-config-validator renovate.json
|
||||
source .gitea/workflows/compose-lint.sh
|
||||
mapfile -t safe_flags < <(compose_safe_flags)
|
||||
validate_compose_file renovate/renovate-compose.yaml \
|
||||
${safe_flags[@]+"${safe_flags[@]}"}
|
||||
@@ -28,18 +28,36 @@ concurrency:
|
||||
jobs:
|
||||
run-renovate:
|
||||
runs-on: [self-hosted, linux, arch, homelab]
|
||||
timeout-minutes: 60
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
|
||||
|
||||
# renovate/k8s/cronjob.yaml is the single source of truth for the image tag.
|
||||
# Reading it here means this workflow validates and runs the exact version
|
||||
# that is deployed, instead of a copy that silently goes stale.
|
||||
- name: Resolve the deployed Renovate image
|
||||
id: image
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
image="$(sed -n 's|.*image:[[:space:]]*\(renovate/renovate:[^[:space:]]*\).*|\1|p' \
|
||||
renovate/k8s/cronjob.yaml | head -1)"
|
||||
if [ -z "$image" ]; then
|
||||
echo "::error::no renovate/renovate image found in renovate/k8s/cronjob.yaml"
|
||||
exit 1
|
||||
fi
|
||||
echo "using $image"
|
||||
echo "image=$image" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Validate Renovate config
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
docker run --rm \
|
||||
-v "$PWD/renovate/config.js:/opt/renovate/config.js:ro" \
|
||||
-e RENOVATE_CONFIG_FILE=/opt/renovate/config.js \
|
||||
renovate/renovate:44.103.0 \
|
||||
-v "$PWD/renovate/renovate.json:/opt/renovate/renovate.json:ro" \
|
||||
-e RENOVATE_CONFIG_FILE=/opt/renovate/renovate.json \
|
||||
"${{ steps.image.outputs.image }}" \
|
||||
renovate-config-validator
|
||||
|
||||
- name: Run Renovate
|
||||
@@ -56,14 +74,14 @@ jobs:
|
||||
: "${RENOVATE_TOKEN:?missing RENOVATE_TOKEN secret — add a renovate-bot PAT in repo/org Actions secrets}"
|
||||
|
||||
docker run --rm \
|
||||
-v "$PWD/renovate/config.js:/opt/renovate/config.js:ro" \
|
||||
-v "$PWD/renovate/renovate.json:/opt/renovate/renovate.json:ro" \
|
||||
-e RENOVATE_PLATFORM=gitea \
|
||||
-e RENOVATE_ENDPOINT=https://gitea.forust.xyz/api/v1 \
|
||||
-e RENOVATE_TOKEN="$RENOVATE_TOKEN" \
|
||||
-e RENOVATE_GITHUB_COM_TOKEN="${RENOVATE_GITHUB_COM_TOKEN:-}" \
|
||||
-e RENOVATE_REPOSITORIES="${RENOVATE_REPOSITORIES:-forust/homelab}" \
|
||||
-e RENOVATE_DRY_RUN="${RENOVATE_DRY_RUN:-}" \
|
||||
-e RENOVATE_CONFIG_FILE=/opt/renovate/config.js \
|
||||
-e RENOVATE_CONFIG_FILE=/opt/renovate/renovate.json \
|
||||
-e RENOVATE_BASE_DIR=/tmp/renovate \
|
||||
-e LOG_LEVEL="${LOG_LEVEL:-info}" \
|
||||
renovate/renovate:44.103.0
|
||||
"${{ steps.image.outputs.image }}"
|
||||
Executable
+55
@@ -0,0 +1,55 @@
|
||||
#!/usr/bin/env bash
|
||||
# Regenerates renovate/k8s/configmap.yaml from renovate/renovate.json.
|
||||
#
|
||||
# renovate/renovate.json is the single source of truth: the CronJob, the Compose
|
||||
# file and the renovate-run workflow all mount that exact file. A ConfigMap cannot
|
||||
# read a file from the repository, so the same bytes are inlined here as a literal
|
||||
# block. This script keeps the copy honest:
|
||||
#
|
||||
# .gitea/workflows/sync-renovate-configmap.sh # rewrite in place
|
||||
# .gitea/workflows/sync-renovate-configmap.sh --check # fail if out of date
|
||||
#
|
||||
# renovate-ci runs the --check form on every PR and push, so a config change that
|
||||
# forgets to regenerate the ConfigMap cannot be merged.
|
||||
set -euo pipefail
|
||||
|
||||
here="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
repo="$(git -C "$here" rev-parse --show-toplevel)"
|
||||
|
||||
src="$repo/renovate/renovate.json"
|
||||
dst="$repo/renovate/k8s/configmap.yaml"
|
||||
[ -f "$src" ] || {
|
||||
echo "missing $src" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
render() {
|
||||
cat <<'HEADER'
|
||||
# GENERATED FILE - do not edit by hand.
|
||||
# Source: renovate/renovate.json
|
||||
# Regenerate: .gitea/workflows/sync-renovate-configmap.sh
|
||||
# Verify: .gitea/workflows/sync-renovate-configmap.sh --check
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: renovate-config
|
||||
namespace: renovate
|
||||
data:
|
||||
renovate.json: |
|
||||
HEADER
|
||||
sed 's/^/ /' "$src"
|
||||
}
|
||||
|
||||
if [ "${1:-}" = "--check" ]; then
|
||||
if ! diff -u "$dst" <(render) >/dev/null 2>&1; then
|
||||
echo "ERROR: $dst is out of sync with renovate/renovate.json"
|
||||
echo "Run: .gitea/workflows/sync-renovate-configmap.sh"
|
||||
diff -u "$dst" <(render) || true
|
||||
exit 1
|
||||
fi
|
||||
echo "renovate/k8s/configmap.yaml is in sync with renovate/renovate.json"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
render >"$dst"
|
||||
echo "wrote $dst"
|
||||
@@ -1,60 +0,0 @@
|
||||
{
|
||||
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||
"extends": ["config:recommended"],
|
||||
"enabledManagers": ["dockerfile", "docker-compose", "kubernetes", "helm-values", "custom.regex"],
|
||||
"helm-values": {
|
||||
"managerFilePatterns": ["/k8s/.+values\\.ya?ml$/"]
|
||||
},
|
||||
"kubernetes": {
|
||||
"managerFilePatterns": ["/k8s/.+\\.ya?ml$/"]
|
||||
},
|
||||
"customManagers": [
|
||||
{
|
||||
"customType": "regex",
|
||||
"description": "singlesource: playwright npm version pinned in npx command (k8s + compose)",
|
||||
"fileMatch": ["^edu_master/k8s/playwright\\.yaml$", "^edu_master/compose\\.yaml$"],
|
||||
"matchStrings": ["playwright@(?<currentValue>\\d+\\.\\d+\\.\\d+)"],
|
||||
"datasourceTemplate": "npm",
|
||||
"depNameTemplate": "playwright"
|
||||
},
|
||||
{
|
||||
"customType": "regex",
|
||||
"description": "singlesource: PLAYWRIGHT_VERSION file",
|
||||
"fileMatch": ["^edu_master/PLAYWRIGHT_VERSION$"],
|
||||
"matchStrings": ["^(?<currentValue>\\d+\\.\\d+\\.\\d+)$"],
|
||||
"datasourceTemplate": "pypi",
|
||||
"depNameTemplate": "playwright"
|
||||
}
|
||||
],
|
||||
"packageRules": [
|
||||
{
|
||||
"description": "singlesource playwright - use whichever version is found, keep docker+pypi+npm in sync",
|
||||
"matchPackageNames": ["playwright", "mcr.microsoft.com/playwright"],
|
||||
"groupName": "playwright singlesource",
|
||||
"groupSlug": "playwright"
|
||||
},
|
||||
{
|
||||
"description": "playwright must not automerge - version skew breaks WS handshake (checker.py:1523 vs playwright.yaml:20)",
|
||||
"matchPackageNames": ["playwright", "mcr.microsoft.com/playwright"],
|
||||
"automerge": false
|
||||
},
|
||||
{
|
||||
"description": "Keep private homelab images unchanged",
|
||||
"matchDatasources": ["docker"],
|
||||
"matchPackageNames": ["/gcr\\.forust\\.xyz\\/forust\\/.+/"],
|
||||
"enabled": false
|
||||
},
|
||||
{
|
||||
"description": "Require approval for major upgrades",
|
||||
"matchUpdateTypes": ["major"],
|
||||
"dependencyDashboardApproval": true,
|
||||
"automerge": false
|
||||
},
|
||||
{
|
||||
"description": "Group container patch updates",
|
||||
"matchDatasources": ["docker"],
|
||||
"matchUpdateTypes": ["patch"],
|
||||
"groupName": "container patch updates"
|
||||
}
|
||||
]
|
||||
}
|
||||
+32
-3
@@ -26,15 +26,17 @@ 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/config.js`:
|
||||
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 `renovate/renovate:44.103.0` on the self-hosted
|
||||
runner via Docker. Required Actions secrets (repo or org settings):
|
||||
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.
|
||||
@@ -64,6 +66,33 @@ 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
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
module.exports = {
|
||||
platform: 'gitea',
|
||||
endpoint: process.env.RENOVATE_ENDPOINT || 'https://gitea.forust.xyz/api/v1',
|
||||
enabledManagers: ['docker-compose', 'kubernetes', 'helm-values'],
|
||||
'helm-values': {
|
||||
managerFilePatterns: ['/k8s/.+values\\.ya?ml$/'],
|
||||
},
|
||||
kubernetes: {
|
||||
managerFilePatterns: ['/k8s/.+\\.ya?ml$/'],
|
||||
},
|
||||
repositories: (process.env.RENOVATE_REPOSITORIES || '')
|
||||
.split(',')
|
||||
.map((repository) => repository.trim())
|
||||
.filter(Boolean),
|
||||
onboarding: false,
|
||||
requireConfig: 'optional',
|
||||
autodiscover: false,
|
||||
dependencyDashboard: true,
|
||||
prCreation: 'immediate',
|
||||
labels: ['dependencies', 'automated'],
|
||||
extends: [
|
||||
'config:recommended',
|
||||
':dependencyDashboard',
|
||||
],
|
||||
packageRules: [
|
||||
{
|
||||
description: 'Do not update private homelab images',
|
||||
matchDatasources: ['docker'],
|
||||
matchPackageNames: ['/gcr\\.forust\\.xyz\\/forust\\/.+/'],
|
||||
enabled: false,
|
||||
},
|
||||
{
|
||||
description: 'Keep major upgrades manual',
|
||||
matchUpdateTypes: ['major'],
|
||||
dependencyDashboardApproval: true,
|
||||
automerge: false,
|
||||
},
|
||||
{
|
||||
description: 'Group patch updates',
|
||||
matchUpdateTypes: ['patch'],
|
||||
groupName: 'container patch updates',
|
||||
},
|
||||
],
|
||||
};
|
||||
+124
-36
@@ -1,51 +1,139 @@
|
||||
# GENERATED FILE - do not edit by hand.
|
||||
# Source: renovate/renovate.json
|
||||
# Regenerate: .gitea/workflows/sync-renovate-configmap.sh
|
||||
# Verify: .gitea/workflows/sync-renovate-configmap.sh --check
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: renovate-config
|
||||
namespace: renovate
|
||||
data:
|
||||
config.js: |
|
||||
module.exports = {
|
||||
platform: 'gitea',
|
||||
endpoint: process.env.RENOVATE_ENDPOINT || 'https://gitea.forust.xyz/api/v1',
|
||||
enabledManagers: ['docker-compose', 'kubernetes', 'helm-values'],
|
||||
'helm-values': {
|
||||
managerFilePatterns: ['/k8s/.+values\\.ya?ml$/'],
|
||||
renovate.json: |
|
||||
{
|
||||
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||
"extends": ["config:recommended", ":dependencyDashboard"],
|
||||
"enabledManagers": ["dockerfile", "docker-compose", "kubernetes", "helm-values", "custom.regex"],
|
||||
"onboarding": false,
|
||||
"requireConfig": "optional",
|
||||
"autodiscover": false,
|
||||
"dependencyDashboard": true,
|
||||
"prCreation": "immediate",
|
||||
"labels": ["dependencies", "automated"],
|
||||
"helm-values": {
|
||||
"managerFilePatterns": ["/k8s/.+values\\.ya?ml$/"]
|
||||
},
|
||||
kubernetes: {
|
||||
managerFilePatterns: ['/k8s/.+\\.ya?ml$/'],
|
||||
"kubernetes": {
|
||||
"managerFilePatterns": ["/k8s/.+\\.ya?ml$/"]
|
||||
},
|
||||
repositories: (process.env.RENOVATE_REPOSITORIES || '')
|
||||
.split(',')
|
||||
.map((repository) => repository.trim())
|
||||
.filter(Boolean),
|
||||
onboarding: false,
|
||||
requireConfig: 'optional',
|
||||
autodiscover: false,
|
||||
dependencyDashboard: true,
|
||||
prCreation: 'immediate',
|
||||
labels: ['dependencies', 'automated'],
|
||||
extends: [
|
||||
'config:recommended',
|
||||
':dependencyDashboard',
|
||||
"customManagers": [
|
||||
{
|
||||
"customType": "regex",
|
||||
"description": "singlesource: playwright npm version pinned in npx command (k8s + compose)",
|
||||
"managerFilePatterns": ["^edu_master/k8s/playwright\\.yaml$", "^edu_master/compose\\.yaml$"],
|
||||
"matchStrings": ["playwright@(?<currentValue>\\d+\\.\\d+\\.\\d+)"],
|
||||
"datasourceTemplate": "npm",
|
||||
"depNameTemplate": "playwright"
|
||||
},
|
||||
{
|
||||
"customType": "regex",
|
||||
"description": "singlesource: PLAYWRIGHT_VERSION file",
|
||||
"managerFilePatterns": ["^edu_master/PLAYWRIGHT_VERSION$"],
|
||||
"matchStrings": ["^(?<currentValue>\\d+\\.\\d+\\.\\d+)$"],
|
||||
"datasourceTemplate": "pypi",
|
||||
"depNameTemplate": "playwright"
|
||||
},
|
||||
{
|
||||
"customType": "regex",
|
||||
"description": "kube-prometheus-stack chart version pinned in the deploy workflow",
|
||||
"managerFilePatterns": ["^\\.gitea/workflows/deploy-lib\\.sh$"],
|
||||
"matchStrings": ["\\|prometheus-community/kube-prometheus-stack\\|prometheus\\|(?<currentValue>[0-9.]+)\\|"],
|
||||
"datasourceTemplate": "helm",
|
||||
"depNameTemplate": "kube-prometheus-stack",
|
||||
"registryUrlTemplate": "https://prometheus-community.github.io/helm-charts"
|
||||
},
|
||||
{
|
||||
"customType": "regex",
|
||||
"description": "grafana/loki chart version pinned in the deploy workflow",
|
||||
"managerFilePatterns": ["^\\.gitea/workflows/deploy-lib\\.sh$"],
|
||||
"matchStrings": ["\\|grafana/loki\\|prometheus\\|(?<currentValue>[0-9.]+)\\|"],
|
||||
"datasourceTemplate": "helm",
|
||||
"depNameTemplate": "loki",
|
||||
"registryUrlTemplate": "https://grafana.github.io/helm-charts"
|
||||
},
|
||||
{
|
||||
"customType": "regex",
|
||||
"description": "grafana/alloy chart version pinned in the deploy workflow",
|
||||
"managerFilePatterns": ["^\\.gitea/workflows/deploy-lib\\.sh$"],
|
||||
"matchStrings": ["\\|grafana/alloy\\|prometheus\\|(?<currentValue>[0-9.]+)\\|"],
|
||||
"datasourceTemplate": "helm",
|
||||
"depNameTemplate": "alloy",
|
||||
"registryUrlTemplate": "https://grafana.github.io/helm-charts"
|
||||
},
|
||||
{
|
||||
"customType": "regex",
|
||||
"description": "actionlint version used by the ci workflow",
|
||||
"managerFilePatterns": ["^\\.gitea/workflows/tool-versions\\.env$"],
|
||||
"matchStrings": ["(?:^|\\n)ACTIONLINT_VERSION=\"(?<currentValue>[0-9.]+)\""],
|
||||
"datasourceTemplate": "github-tags",
|
||||
"depNameTemplate": "rhysd/actionlint"
|
||||
},
|
||||
{
|
||||
"customType": "regex",
|
||||
"description": "shellcheck version used by the ci workflow",
|
||||
"managerFilePatterns": ["^\\.gitea/workflows/tool-versions\\.env$"],
|
||||
"matchStrings": ["(?:^|\\n)SHELLCHECK_VERSION=\"(?<currentValue>[0-9.]+)\""],
|
||||
"datasourceTemplate": "github-tags",
|
||||
"depNameTemplate": "koalaman/shellcheck"
|
||||
},
|
||||
{
|
||||
"customType": "regex",
|
||||
"description": "kubeconform version used by the ci workflow",
|
||||
"managerFilePatterns": ["^\\.gitea/workflows/tool-versions\\.env$"],
|
||||
"matchStrings": ["(?:^|\\n)KUBECONFORM_VERSION=\"(?<currentValue>[0-9.]+)\""],
|
||||
"datasourceTemplate": "github-tags",
|
||||
"depNameTemplate": "yannh/kubeconform"
|
||||
}
|
||||
],
|
||||
packageRules: [
|
||||
"packageRules": [
|
||||
{
|
||||
description: 'Do not update private homelab images',
|
||||
matchDatasources: ['docker'],
|
||||
matchPackageNames: ['/gcr\\.forust\\.xyz\\/forust\\/.+/'],
|
||||
enabled: false,
|
||||
"description": "Keep private homelab images unchanged",
|
||||
"matchDatasources": ["docker"],
|
||||
"matchPackageNames": ["/gcr\\.forust\\.xyz\\/forust\\/.+/"],
|
||||
"enabled": false
|
||||
},
|
||||
{
|
||||
description: 'Keep major upgrades manual',
|
||||
matchUpdateTypes: ['major'],
|
||||
dependencyDashboardApproval: true,
|
||||
automerge: false,
|
||||
"description": "singlesource playwright - use whichever version is found, keep docker+pypi+npm in sync",
|
||||
"matchPackageNames": ["playwright", "mcr.microsoft.com/playwright"],
|
||||
"groupName": "playwright singlesource",
|
||||
"groupSlug": "playwright"
|
||||
},
|
||||
{
|
||||
description: 'Group patch updates',
|
||||
matchUpdateTypes: ['patch'],
|
||||
groupName: 'container patch updates',
|
||||
"description": "playwright must not automerge - version skew breaks the WS handshake (checker.py:1523 vs playwright.yaml:20)",
|
||||
"matchPackageNames": ["playwright", "mcr.microsoft.com/playwright"],
|
||||
"automerge": false
|
||||
},
|
||||
],
|
||||
};
|
||||
{
|
||||
"description": "Renovate updates itself in lockstep across the CronJob and the Compose file",
|
||||
"matchPackageNames": ["renovate/renovate"],
|
||||
"groupName": "renovate self-update",
|
||||
"automerge": false
|
||||
},
|
||||
{
|
||||
"description": "Helm chart bumps change PVC fields and admission behaviour, keep them reviewable",
|
||||
"matchDatasources": ["helm"],
|
||||
"automerge": false
|
||||
},
|
||||
{
|
||||
"description": "Require approval for major upgrades",
|
||||
"matchUpdateTypes": ["major"],
|
||||
"dependencyDashboardApproval": true,
|
||||
"automerge": false
|
||||
},
|
||||
{
|
||||
"description": "Group container patch updates",
|
||||
"matchDatasources": ["docker"],
|
||||
"matchUpdateTypes": ["patch"],
|
||||
"groupName": "container patch updates"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -36,7 +36,7 @@ spec:
|
||||
name: renovate-secrets
|
||||
key: RENOVATE_REPOSITORIES
|
||||
- name: RENOVATE_CONFIG_FILE
|
||||
value: /opt/renovate/config.js
|
||||
value: /opt/renovate/renovate.json
|
||||
- name: RENOVATE_BASE_DIR
|
||||
value: /tmp/renovate
|
||||
- name: RENOVATE_GITHUB_COM_TOKEN
|
||||
@@ -49,8 +49,8 @@ spec:
|
||||
value: info
|
||||
volumeMounts:
|
||||
- name: config
|
||||
mountPath: /opt/renovate/config.js
|
||||
subPath: config.js
|
||||
mountPath: /opt/renovate/renovate.json
|
||||
subPath: renovate.json
|
||||
readOnly: true
|
||||
volumes:
|
||||
- name: config
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
services:
|
||||
renovate:
|
||||
image: renovate/renovate:44.103.0
|
||||
# Kept in step with renovate/k8s/cronjob.yaml by the "renovate self-update"
|
||||
# package rule in renovate/renovate.json.
|
||||
image: renovate/renovate:44.115.9
|
||||
container_name: renovate
|
||||
restart: "no"
|
||||
env_file:
|
||||
@@ -10,8 +12,8 @@ services:
|
||||
RENOVATE_ENDPOINT: ${RENOVATE_ENDPOINT:?set RENOVATE_ENDPOINT}
|
||||
RENOVATE_TOKEN: ${RENOVATE_TOKEN:?set RENOVATE_TOKEN}
|
||||
RENOVATE_REPOSITORIES: ${RENOVATE_REPOSITORIES:?set RENOVATE_REPOSITORIES}
|
||||
RENOVATE_CONFIG_FILE: /opt/renovate/config.js
|
||||
RENOVATE_CONFIG_FILE: /opt/renovate/renovate.json
|
||||
RENOVATE_BASE_DIR: /tmp/renovate
|
||||
LOG_LEVEL: ${LOG_LEVEL:-info}
|
||||
volumes:
|
||||
- ./config.js:/opt/renovate/config.js:ro
|
||||
- ./renovate.json:/opt/renovate/renovate.json:ro
|
||||
@@ -0,0 +1,128 @@
|
||||
{
|
||||
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||
"extends": ["config:recommended", ":dependencyDashboard"],
|
||||
"enabledManagers": ["dockerfile", "docker-compose", "kubernetes", "helm-values", "custom.regex"],
|
||||
"onboarding": false,
|
||||
"requireConfig": "optional",
|
||||
"autodiscover": false,
|
||||
"dependencyDashboard": true,
|
||||
"prCreation": "immediate",
|
||||
"labels": ["dependencies", "automated"],
|
||||
"helm-values": {
|
||||
"managerFilePatterns": ["/k8s/.+values\\.ya?ml$/"]
|
||||
},
|
||||
"kubernetes": {
|
||||
"managerFilePatterns": ["/k8s/.+\\.ya?ml$/"]
|
||||
},
|
||||
"customManagers": [
|
||||
{
|
||||
"customType": "regex",
|
||||
"description": "singlesource: playwright npm version pinned in npx command (k8s + compose)",
|
||||
"managerFilePatterns": ["^edu_master/k8s/playwright\\.yaml$", "^edu_master/compose\\.yaml$"],
|
||||
"matchStrings": ["playwright@(?<currentValue>\\d+\\.\\d+\\.\\d+)"],
|
||||
"datasourceTemplate": "npm",
|
||||
"depNameTemplate": "playwright"
|
||||
},
|
||||
{
|
||||
"customType": "regex",
|
||||
"description": "singlesource: PLAYWRIGHT_VERSION file",
|
||||
"managerFilePatterns": ["^edu_master/PLAYWRIGHT_VERSION$"],
|
||||
"matchStrings": ["^(?<currentValue>\\d+\\.\\d+\\.\\d+)$"],
|
||||
"datasourceTemplate": "pypi",
|
||||
"depNameTemplate": "playwright"
|
||||
},
|
||||
{
|
||||
"customType": "regex",
|
||||
"description": "kube-prometheus-stack chart version pinned in the deploy workflow",
|
||||
"managerFilePatterns": ["^\\.gitea/workflows/deploy-lib\\.sh$"],
|
||||
"matchStrings": ["\\|prometheus-community/kube-prometheus-stack\\|prometheus\\|(?<currentValue>[0-9.]+)\\|"],
|
||||
"datasourceTemplate": "helm",
|
||||
"depNameTemplate": "kube-prometheus-stack",
|
||||
"registryUrlTemplate": "https://prometheus-community.github.io/helm-charts"
|
||||
},
|
||||
{
|
||||
"customType": "regex",
|
||||
"description": "grafana/loki chart version pinned in the deploy workflow",
|
||||
"managerFilePatterns": ["^\\.gitea/workflows/deploy-lib\\.sh$"],
|
||||
"matchStrings": ["\\|grafana/loki\\|prometheus\\|(?<currentValue>[0-9.]+)\\|"],
|
||||
"datasourceTemplate": "helm",
|
||||
"depNameTemplate": "loki",
|
||||
"registryUrlTemplate": "https://grafana.github.io/helm-charts"
|
||||
},
|
||||
{
|
||||
"customType": "regex",
|
||||
"description": "grafana/alloy chart version pinned in the deploy workflow",
|
||||
"managerFilePatterns": ["^\\.gitea/workflows/deploy-lib\\.sh$"],
|
||||
"matchStrings": ["\\|grafana/alloy\\|prometheus\\|(?<currentValue>[0-9.]+)\\|"],
|
||||
"datasourceTemplate": "helm",
|
||||
"depNameTemplate": "alloy",
|
||||
"registryUrlTemplate": "https://grafana.github.io/helm-charts"
|
||||
},
|
||||
{
|
||||
"customType": "regex",
|
||||
"description": "actionlint version used by the ci workflow",
|
||||
"managerFilePatterns": ["^\\.gitea/workflows/tool-versions\\.env$"],
|
||||
"matchStrings": ["(?:^|\\n)ACTIONLINT_VERSION=\"(?<currentValue>[0-9.]+)\""],
|
||||
"datasourceTemplate": "github-tags",
|
||||
"depNameTemplate": "rhysd/actionlint"
|
||||
},
|
||||
{
|
||||
"customType": "regex",
|
||||
"description": "shellcheck version used by the ci workflow",
|
||||
"managerFilePatterns": ["^\\.gitea/workflows/tool-versions\\.env$"],
|
||||
"matchStrings": ["(?:^|\\n)SHELLCHECK_VERSION=\"(?<currentValue>[0-9.]+)\""],
|
||||
"datasourceTemplate": "github-tags",
|
||||
"depNameTemplate": "koalaman/shellcheck"
|
||||
},
|
||||
{
|
||||
"customType": "regex",
|
||||
"description": "kubeconform version used by the ci workflow",
|
||||
"managerFilePatterns": ["^\\.gitea/workflows/tool-versions\\.env$"],
|
||||
"matchStrings": ["(?:^|\\n)KUBECONFORM_VERSION=\"(?<currentValue>[0-9.]+)\""],
|
||||
"datasourceTemplate": "github-tags",
|
||||
"depNameTemplate": "yannh/kubeconform"
|
||||
}
|
||||
],
|
||||
"packageRules": [
|
||||
{
|
||||
"description": "Keep private homelab images unchanged",
|
||||
"matchDatasources": ["docker"],
|
||||
"matchPackageNames": ["/gcr\\.forust\\.xyz\\/forust\\/.+/"],
|
||||
"enabled": false
|
||||
},
|
||||
{
|
||||
"description": "singlesource playwright - use whichever version is found, keep docker+pypi+npm in sync",
|
||||
"matchPackageNames": ["playwright", "mcr.microsoft.com/playwright"],
|
||||
"groupName": "playwright singlesource",
|
||||
"groupSlug": "playwright"
|
||||
},
|
||||
{
|
||||
"description": "playwright must not automerge - version skew breaks the WS handshake (checker.py:1523 vs playwright.yaml:20)",
|
||||
"matchPackageNames": ["playwright", "mcr.microsoft.com/playwright"],
|
||||
"automerge": false
|
||||
},
|
||||
{
|
||||
"description": "Renovate updates itself in lockstep across the CronJob and the Compose file",
|
||||
"matchPackageNames": ["renovate/renovate"],
|
||||
"groupName": "renovate self-update",
|
||||
"automerge": false
|
||||
},
|
||||
{
|
||||
"description": "Helm chart bumps change PVC fields and admission behaviour, keep them reviewable",
|
||||
"matchDatasources": ["helm"],
|
||||
"automerge": false
|
||||
},
|
||||
{
|
||||
"description": "Require approval for major upgrades",
|
||||
"matchUpdateTypes": ["major"],
|
||||
"dependencyDashboardApproval": true,
|
||||
"automerge": false
|
||||
},
|
||||
{
|
||||
"description": "Group container patch updates",
|
||||
"matchDatasources": ["docker"],
|
||||
"matchUpdateTypes": ["patch"],
|
||||
"groupName": "container patch updates"
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in new issue
Block a user