Compare commits

...
Author SHA1 Message Date
renovate-bot 368935f432 chore(deps): update renovate/renovate docker tag to v44.140.0
ci / validate (push) Skipped
ci / lint-prettier (push) Skipped
ci / lint-ruff (push) Skipped
ci / lint-yaml (push) Skipped
ci / lint-dockerfiles (push) Skipped
renovate-ci / validate-renovate (push) Skipped
ci / lint-compose (pull_request) Successful in 11s
ci / lint-actionlint (pull_request) Successful in 6s
ci / lint-shellcheck (pull_request) Successful in 16s
ci / lint-prettier (pull_request) Successful in 19s
ci / lint-ruff (pull_request) Successful in 7s
ci / lint-yaml (pull_request) Successful in 10s
ci / lint-dockerfiles (pull_request) Successful in 4s
ci / validate (pull_request) Successful in 7s
ci / build (pull_request) Skipped
renovate-ci / validate-renovate (pull_request) Failing after 1m6s
2026-10-06 16:19:22 +00:00
forust 6057734a4f fix(renovate): sync generated configmap
renovate-ci / validate-renovate (push) Successful in 9s
ci / lint-compose (push) Successful in 9s
ci / lint-actionlint (push) Successful in 4s
ci / lint-shellcheck (push) Successful in 10s
ci / lint-prettier (push) Successful in 19s
ci / lint-ruff (push) Successful in 8s
ci / lint-yaml (push) Successful in 11s
ci / lint-dockerfiles (push) Successful in 5s
ci / validate (push) Successful in 7s
ci / build (push) Successful in 18s
2026-10-06 18:08:17 +02:00
forust 8eedf8b74b Merge pull request 'feat(monitoring): add VictoriaMetrics trial stack' (#95) from feat/victoria-metrics-migration into main
ci / lint-compose (push) Successful in 11s
ci / lint-actionlint (push) Successful in 2m36s
ci / lint-shellcheck (push) Successful in 15s
ci / lint-prettier (push) Successful in 19s
ci / lint-ruff (push) Successful in 7s
ci / lint-yaml (push) Successful in 10s
ci / lint-dockerfiles (push) Successful in 5s
ci / validate (push) Successful in 7s
renovate-ci / validate-renovate (push) Failing after 9s
ci / build (push) Successful in 19s
Reviewed-on: https://gitea.forust.xyz/forust/homelab/pulls/95
2026-10-06 16:05:46 +00:00
forust 8c0e36a5c0 feat(monitoring): replace scrape dump with vmagent
ci / lint-prettier (push) Skipped
ci / lint-ruff (push) Skipped
ci / lint-yaml (push) Skipped
ci / lint-dockerfiles (push) Skipped
ci / validate (push) Skipped
renovate-ci / validate-renovate (push) Skipped
ci / lint-compose (pull_request) Successful in 11s
ci / lint-actionlint (pull_request) Successful in 6s
ci / lint-shellcheck (pull_request) Successful in 16s
ci / lint-dockerfiles (pull_request) Successful in 6s
ci / lint-prettier (pull_request) Successful in 16s
ci / lint-ruff (pull_request) Successful in 7s
ci / lint-yaml (pull_request) Successful in 10s
ci / validate (pull_request) Successful in 7s
ci / build (pull_request) Skipped
renovate-ci / validate-renovate (pull_request) Failing after 1m40s
2026-10-06 18:03:59 +02:00
forust 78cd15f12c chore(monitoring): remove vmctl backfill job
renovate-ci / validate-renovate (pull_request) Skipped
ci / lint-compose (pull_request) Successful in 11s
ci / lint-yaml (pull_request) Successful in 11s
ci / lint-prettier (push) Skipped
ci / lint-ruff (push) Skipped
ci / lint-yaml (push) Skipped
ci / lint-dockerfiles (push) Skipped
ci / validate (push) Skipped
renovate-ci / validate-renovate (push) Skipped
ci / lint-actionlint (pull_request) Successful in 5s
ci / lint-shellcheck (pull_request) Successful in 16s
ci / lint-prettier (pull_request) Successful in 15s
ci / lint-ruff (pull_request) Successful in 6s
ci / lint-dockerfiles (pull_request) Successful in 7s
ci / validate (pull_request) Successful in 7s
ci / build (pull_request) Skipped
One-shot Prometheus history backfill is complete; drop the Job and clean up related comments.
2026-10-06 17:53:24 +02:00
forust 18c633c242 feat(monitoring): add VictoriaMetrics trial stack
ci / lint-prettier (push) Skipped
ci / lint-ruff (push) Skipped
ci / lint-yaml (push) Skipped
ci / lint-dockerfiles (push) Skipped
ci / validate (push) Skipped
renovate-ci / validate-renovate (push) Skipped
renovate-ci / validate-renovate (pull_request) Skipped
ci / lint-compose (pull_request) Successful in 12s
ci / lint-actionlint (pull_request) Successful in 6s
ci / lint-shellcheck (pull_request) Successful in 13s
ci / lint-prettier (pull_request) Successful in 21s
ci / lint-ruff (pull_request) Successful in 7s
ci / lint-yaml (pull_request) Successful in 12s
ci / lint-dockerfiles (pull_request) Successful in 7s
ci / validate (pull_request) Successful in 7s
ci / build (pull_request) Skipped
2026-10-06 17:45:44 +02:00
forust 4510394531 Merge pull request 'chore(deps): update renovate/renovate docker tag to v44.139.0' (#81) from renovate/renovate-self-update into main
ci / lint-compose (push) Successful in 11s
ci / lint-actionlint (push) Successful in 6s
ci / lint-shellcheck (push) Successful in 15s
ci / lint-prettier (push) Successful in 19s
ci / lint-ruff (push) Successful in 7s
ci / lint-yaml (push) Successful in 11s
ci / lint-dockerfiles (push) Successful in 6s
ci / validate (push) Successful in 9s
renovate-ci / validate-renovate (push) Successful in 13s
ci / build (push) Successful in 20s
Reviewed-on: https://gitea.forust.xyz/forust/homelab/pulls/81
2026-10-06 15:33:45 +00:00
renovate-bot 2545312db1 chore(deps): update renovate/renovate docker tag to v44.139.0 2026-10-06 15:33:45 +00:00
forust 8ce0b809c0 Merge pull request 'chore(deps): update all minor updates' (#77) from renovate/all-minor into main
renovate-ci / validate-renovate (push) Skipped
ci / lint-compose (push) Canceled after 0s
ci / lint-actionlint (push) Canceled after 0s
ci / lint-shellcheck (push) Canceled after 0s
ci / lint-prettier (push) Canceled after 0s
ci / lint-ruff (push) Canceled after 0s
ci / lint-yaml (push) Canceled after 0s
ci / lint-dockerfiles (push) Canceled after 0s
ci / validate (push) Canceled after 0s
ci / build (push) Canceled after 0s
Reviewed-on: https://gitea.forust.xyz/forust/homelab/pulls/77
2026-10-06 15:33:28 +00:00
renovate-bot 506c04e15c chore(deps): update all minor updates 2026-10-06 15:33:28 +00:00
forust bdcbb3d5af Merge pull request 'chore(deps): update all patch updates' (#82) from renovate/all-patch into main
renovate-ci / validate-renovate (push) Skipped
ci / lint-compose (push) Canceled after 0s
ci / lint-actionlint (push) Canceled after 0s
ci / lint-shellcheck (push) Canceled after 0s
ci / lint-prettier (push) Canceled after 0s
ci / lint-ruff (push) Canceled after 0s
ci / lint-yaml (push) Canceled after 0s
ci / lint-dockerfiles (push) Canceled after 0s
ci / validate (push) Canceled after 0s
ci / build (push) Canceled after 0s
Reviewed-on: https://gitea.forust.xyz/forust/homelab/pulls/82
2026-10-06 15:33:09 +00:00
renovate-bot faac6febb8 chore(deps): update all patch updates 2026-10-06 15:33:09 +00:00
forust 695da1308c Merge pull request 'fix(renovate): restore custom extraction and update groups' (#93) from fix/renovate-extraction-groups into main
ci / lint-compose (push) Successful in 10s
ci / lint-actionlint (push) Successful in 6s
ci / lint-shellcheck (push) Successful in 17s
ci / lint-prettier (push) Successful in 18s
ci / lint-ruff (push) Successful in 8s
ci / lint-yaml (push) Successful in 12s
ci / lint-dockerfiles (push) Successful in 8s
ci / validate (push) Successful in 8s
renovate-ci / validate-renovate (push) Successful in 11s
ci / build (push) Successful in 37s
Reviewed-on: https://gitea.forust.xyz/forust/homelab/pulls/93
2026-10-06 15:31:25 +00:00
forust 552b22cb66 fix(renovate): include self-update Compose filename 2026-10-06 15:31:25 +00:00
forust 3756e60c95 fix(renovate): restore custom extraction and update groups 2026-10-06 15:31:25 +00:00
forust d0d217ddf4 Merge pull request 'fix(deploy): skip verify and smoke when deployment is disabled' (#94) from fix/deploy-skip-when-disabled into main
renovate-ci / validate-renovate (push) Skipped
ci / lint-compose (push) Canceled after 0s
ci / lint-actionlint (push) Canceled after 0s
ci / lint-shellcheck (push) Canceled after 0s
ci / lint-prettier (push) Canceled after 0s
ci / lint-ruff (push) Canceled after 0s
ci / lint-yaml (push) Canceled after 0s
ci / lint-dockerfiles (push) Canceled after 0s
ci / validate (push) Canceled after 0s
ci / build (push) Canceled after 0s
Reviewed-on: https://gitea.forust.xyz/forust/homelab/pulls/94
2026-10-06 15:24:17 +00:00
forust 24f84bab2f fix(deploy): skip verification when deployment is disabled
ci / lint-yaml (push) Skipped
ci / lint-dockerfiles (push) Skipped
ci / validate (push) Skipped
renovate-ci / validate-renovate (push) Skipped
ci / lint-prettier (push) Skipped
ci / lint-ruff (push) Skipped
renovate-ci / validate-renovate (pull_request) Skipped
ci / lint-compose (pull_request) Canceled after 0s
ci / lint-actionlint (pull_request) Canceled after 0s
ci / lint-shellcheck (pull_request) Canceled after 0s
ci / lint-prettier (pull_request) Canceled after 0s
ci / lint-ruff (pull_request) Canceled after 0s
ci / lint-yaml (pull_request) Canceled after 0s
ci / lint-dockerfiles (pull_request) Canceled after 0s
ci / validate (pull_request) Canceled after 0s
ci / build (pull_request) Canceled after 0s
2026-10-06 15:24:06 +00:00
forust 0b8a3c16a7 Merge pull request 'fix(glance): mount CSS from the correct ConfigMap' (#87) from fix/glance-assets into main
renovate-ci / validate-renovate (push) Skipped
ci / lint-compose (push) Canceled after 0s
ci / lint-actionlint (push) Canceled after 0s
ci / lint-shellcheck (push) Canceled after 0s
ci / lint-prettier (push) Canceled after 0s
ci / lint-ruff (push) Canceled after 0s
ci / lint-yaml (push) Canceled after 0s
ci / lint-dockerfiles (push) Canceled after 0s
ci / validate (push) Canceled after 0s
ci / build (push) Canceled after 0s
Reviewed-on: https://gitea.forust.xyz/forust/homelab/pulls/87
2026-10-06 15:17:47 +00:00
forust e9a68aae77 fix(glance): mount CSS from the assets ConfigMap 2026-10-06 15:17:47 +00:00
forust 5359df5ed6 Merge pull request 'fix(postgres): include the required NetBox database password' (#88) from fix/postgres-env-example into main
renovate-ci / validate-renovate (push) Skipped
ci / lint-compose (push) Successful in 14s
ci / lint-actionlint (push) Successful in 8s
ci / lint-shellcheck (push) Successful in 17s
ci / lint-prettier (push) Successful in 24s
ci / lint-ruff (push) Successful in 9s
ci / lint-yaml (push) Successful in 11s
ci / lint-dockerfiles (push) Successful in 5s
ci / validate (push) Successful in 11s
ci / build (push) Canceled after 0s
Reviewed-on: https://gitea.forust.xyz/forust/homelab/pulls/88
2026-10-06 15:17:19 +00:00
forust 8aea0f0d13 fix(postgres): include required NetBox password in Compose env example 2026-10-06 15:17:19 +00:00
forust 65d4f2d482 Merge pull request 'fix(traefik): correct AdGuard and SearXNG Compose rules' (#90) from fix/compose-router-rules into main
renovate-ci / validate-renovate (push) Skipped
ci / lint-compose (push) Successful in 12s
ci / lint-actionlint (push) Successful in 6s
ci / lint-shellcheck (push) Successful in 13s
ci / lint-prettier (push) Successful in 16s
ci / lint-ruff (push) Successful in 8s
ci / lint-yaml (push) Successful in 11s
ci / lint-dockerfiles (push) Successful in 6s
ci / validate (push) Successful in 10s
ci / build (push) Successful in 23s
Reviewed-on: https://gitea.forust.xyz/forust/homelab/pulls/90
2026-10-06 15:10:49 +00:00
forust 2fe9b7632f fix(traefik): correct AdGuard and SearXNG Compose router expressions 2026-10-06 15:10:49 +00:00
forust e436d89eef Merge pull request 'fix(netbird): restore Compose setup and runtime renderer' (#86) from fix/netbird-compose-runtime into main
renovate-ci / validate-renovate (push) Skipped
ci / lint-compose (push) Successful in 11s
ci / lint-actionlint (push) Successful in 4s
ci / lint-shellcheck (push) Successful in 15s
ci / lint-prettier (push) Successful in 21s
ci / lint-ruff (push) Successful in 7s
ci / lint-yaml (push) Successful in 11s
ci / lint-dockerfiles (push) Successful in 6s
ci / validate (push) Successful in 7s
ci / build (push) Successful in 20s
Reviewed-on: https://gitea.forust.xyz/forust/homelab/pulls/86
2026-10-06 15:10:12 +00:00
forust 8729cb5062 fix(netbird): restore Compose setup and server entrypoint
ci / validate (push) Skipped
ci / lint-prettier (push) Skipped
ci / lint-ruff (push) Skipped
ci / lint-yaml (push) Skipped
ci / lint-dockerfiles (push) Skipped
renovate-ci / validate-renovate (push) Skipped
renovate-ci / validate-renovate (pull_request) Skipped
ci / lint-compose (pull_request) Successful in 12s
ci / lint-actionlint (pull_request) Successful in 8s
ci / lint-shellcheck (pull_request) Successful in 21s
ci / lint-prettier (pull_request) Successful in 17s
ci / lint-ruff (pull_request) Successful in 6s
ci / lint-yaml (pull_request) Successful in 9s
ci / lint-dockerfiles (pull_request) Successful in 5s
ci / validate (pull_request) Successful in 6s
ci / build (pull_request) Skipped
2026-10-06 15:08:46 +00:00
forust f1e4a1088d Merge pull request 'fix(ci): deduplicate PR checks and filter deploy triggers' (#92) from fix/ci-trigger-dedup into main
renovate-ci / validate-renovate (push) Successful in 9s
ci / lint-compose (push) Successful in 10s
ci / lint-actionlint (push) Successful in 6s
ci / lint-shellcheck (push) Successful in 12s
ci / lint-prettier (push) Successful in 19s
ci / lint-ruff (push) Successful in 8s
ci / lint-yaml (push) Successful in 12s
ci / lint-dockerfiles (push) Successful in 7s
ci / validate (push) Successful in 7s
ci / build (push) Successful in 19s
Reviewed-on: https://gitea.forust.xyz/forust/homelab/pulls/92
2026-10-06 15:06:47 +00:00
forust b357ef95d8 fix(deploy): only create automatic runs for main CI
ci / lint-ruff (push) Skipped
ci / lint-yaml (push) Skipped
ci / lint-dockerfiles (push) Skipped
ci / validate (push) Skipped
ci / lint-prettier (push) Skipped
renovate-ci / validate-renovate (push) Skipped
ci / lint-compose (pull_request) Successful in 13s
ci / lint-actionlint (pull_request) Successful in 6s
ci / lint-shellcheck (pull_request) Successful in 11s
ci / lint-prettier (pull_request) Successful in 18s
ci / lint-ruff (pull_request) Successful in 8s
ci / lint-yaml (pull_request) Successful in 13s
ci / lint-dockerfiles (pull_request) Successful in 5s
ci / validate (pull_request) Successful in 9s
ci / build (pull_request) Skipped
renovate-ci / validate-renovate (pull_request) Successful in 12s
2026-10-06 17:00:05 +02:00
forust 67422663b7 fix(ci): avoid duplicate branch and PR runs
ci / validate (push) Skipped
ci / lint-prettier (push) Skipped
ci / lint-ruff (push) Skipped
ci / lint-yaml (push) Skipped
ci / lint-dockerfiles (push) Skipped
renovate-ci / validate-renovate (push) Skipped
ci / lint-compose (pull_request) Canceled after 0s
ci / lint-actionlint (pull_request) Canceled after 0s
ci / lint-shellcheck (pull_request) Canceled after 0s
ci / lint-prettier (pull_request) Canceled after 0s
ci / lint-ruff (pull_request) Canceled after 0s
ci / lint-yaml (pull_request) Canceled after 0s
ci / lint-dockerfiles (pull_request) Canceled after 0s
ci / validate (pull_request) Canceled after 0s
ci / build (pull_request) Canceled after 0s
renovate-ci / validate-renovate (pull_request) Successful in 10s
2026-10-06 16:59:26 +02:00
forust 88705fec88 Merge pull request 'fix(deploy): reject unsafe per-file pruning' (#85) from fix/deploy-prune-guard into main
renovate-ci / validate-renovate (push) Successful in 9s
ci / lint-compose (push) Successful in 10s
ci / lint-actionlint (push) Successful in 4s
ci / lint-shellcheck (push) Successful in 11s
ci / lint-prettier (push) Successful in 15s
ci / lint-ruff (push) Successful in 5s
ci / lint-yaml (push) Successful in 10s
ci / lint-dockerfiles (push) Successful in 5s
ci / validate (push) Successful in 8s
ci / build (push) Successful in 23s
Reviewed-on: https://gitea.forust.xyz/forust/homelab/pulls/85
2026-10-06 14:57:22 +00:00
forust c098807aa4 fix(deploy): reject destructive per-file pruning before apply
renovate-ci / validate-renovate (push) Skipped
ci / lint-compose (push) Successful in 14s
ci / lint-actionlint (push) Successful in 8s
ci / lint-shellcheck (push) Successful in 13s
ci / lint-prettier (push) Successful in 19s
ci / lint-ruff (push) Successful in 8s
ci / lint-yaml (push) Successful in 12s
ci / lint-dockerfiles (push) Successful in 8s
ci / validate (push) Successful in 10s
ci / build (push) Skipped
ci / lint-compose (pull_request) Successful in 12s
ci / lint-actionlint (pull_request) Successful in 5s
ci / lint-shellcheck (pull_request) Successful in 11s
ci / lint-prettier (pull_request) Successful in 16s
ci / lint-ruff (pull_request) Successful in 8s
ci / lint-yaml (pull_request) Successful in 11s
ci / lint-dockerfiles (pull_request) Successful in 7s
ci / validate (pull_request) Successful in 7s
ci / build (pull_request) Skipped
renovate-ci / validate-renovate (pull_request) Successful in 10s
2026-10-06 14:57:11 +00:00
forust e1eee2d3c7 Merge pull request 'feat(reloader): enable deploy and integrate configuration reloads' (#91) from fix/reloader-integration into main
ci / lint-compose (push) Canceled after 0s
ci / lint-actionlint (push) Canceled after 0s
ci / lint-shellcheck (push) Canceled after 0s
ci / lint-prettier (push) Canceled after 0s
ci / lint-ruff (push) Canceled after 0s
ci / lint-yaml (push) Canceled after 0s
ci / lint-dockerfiles (push) Canceled after 0s
ci / validate (push) Canceled after 0s
ci / build (push) Canceled after 0s
renovate-ci / validate-renovate (push) Successful in 9s
Reviewed-on: https://gitea.forust.xyz/forust/homelab/pulls/91
2026-10-06 14:55:16 +00:00
36 changed files with 712 additions and 79 deletions

No files matched your search

+7 -1
View File
@@ -3,7 +3,7 @@ name: ci
on: on:
push: push:
branches: branches:
- "**" - main
pull_request: pull_request:
workflow_dispatch: workflow_dispatch:
@@ -142,6 +142,7 @@ jobs:
export PATH="$tools_dir:$PATH" export PATH="$tools_dir:$PATH"
ruff check . ruff check .
ruff format --check . ruff format --check .
python3 -m unittest discover -s tests -v
lint-yaml: lint-yaml:
runs-on: [self-hosted, linux, arch, homelab] runs-on: [self-hosted, linux, arch, homelab]
@@ -293,6 +294,11 @@ jobs:
echo "server-side dry-run: ${#manifests[@]} manifests, ${#kustomize_apps[@]} kustomize apps" echo "server-side dry-run: ${#manifests[@]} manifests, ${#kustomize_apps[@]} kustomize apps"
failed=0 failed=0
for m in ${manifests[@]+"${manifests[@]}"}; do for m in ${manifests[@]+"${manifests[@]}"}; do
if [[ "$m" == "prometheus-stack/k8s/vmagent.yaml" ]] \
&& ! kubectl get crd vmagents.operator.victoriametrics.com >/dev/null 2>&1; then
echo "skip server-side dry-run until the VictoriaMetrics Operator CRD is installed: $m"
continue
fi
if ! out="$(kubectl apply --dry-run=server -f "$m" 2>&1)"; then if ! out="$(kubectl apply --dry-run=server -f "$m" 2>&1)"; then
failed=1 failed=1
echo "::error file=${m}::$(printf '%s' "$out" | head -1)" echo "::error file=${m}::$(printf '%s' "$out" | head -1)"
+16 -5
View File
@@ -31,6 +31,16 @@ warn() {
echo "WARNING: $*" >&2 echo "WARNING: $*" >&2
} }
# Prune needs the complete desired set in one invocation. Per-file pruning
# treats resources from the other files as absent and can delete them.
check_prune_mode() {
if [ "$APPLY_PRUNE" = "true" ]; then
echo "ERROR: APPLY_PRUNE=true is unsupported by the per-file deploy loop." >&2
echo "Disable it; remove obsolete resources explicitly after review." >&2
return 1
fi
}
collect_k8s() { collect_k8s() {
git -C "$REPO" ls-files -- "$1" \ git -C "$REPO" ls-files -- "$1" \
| grep -E '\.ya?ml$' \ | grep -E '\.ya?ml$' \
@@ -536,6 +546,7 @@ rollback_workloads() {
# have to be declared as custom.regex managers in renovate/renovate.json. # have to be declared as custom.regex managers in renovate/renovate.json.
HELM_RELEASES=( HELM_RELEASES=(
"prometheus-stack|prometheus-community/kube-prometheus-stack|prometheus|86.2.3|prometheus-stack/k8s/grafana-values.yaml|prometheus-stack/k8s/active" "prometheus-stack|prometheus-community/kube-prometheus-stack|prometheus|86.2.3|prometheus-stack/k8s/grafana-values.yaml|prometheus-stack/k8s/active"
"victoria-operator|victoriametrics/victoria-metrics-operator|prometheus|0.68.1|prometheus-stack/k8s/victoria-operator-values.yaml|prometheus-stack/k8s/active"
"loki|grafana/loki|prometheus|7.3.0|loki/k8s/loki-values.yaml|loki/k8s/active" "loki|grafana/loki|prometheus|7.3.0|loki/k8s/loki-values.yaml|loki/k8s/active"
"alloy|grafana/alloy|prometheus|1.12.1|loki/k8s/alloy-values.yaml|loki/k8s/active" "alloy|grafana/alloy|prometheus|1.12.1|loki/k8s/alloy-values.yaml|loki/k8s/active"
"reloader|stakater/reloader|reloader|2.2.17|reloader/k8s/reloader-values.yaml|reloader/k8s/active" "reloader|stakater/reloader|reloader|2.2.17|reloader/k8s/reloader-values.yaml|reloader/k8s/active"
@@ -547,6 +558,7 @@ helm_repo_for() {
prometheus-community/*) echo "prometheus-community https://prometheus-community.github.io/helm-charts" ;; prometheus-community/*) echo "prometheus-community https://prometheus-community.github.io/helm-charts" ;;
grafana/*) echo "grafana https://grafana.github.io/helm-charts" ;; grafana/*) echo "grafana https://grafana.github.io/helm-charts" ;;
stakater/*) echo "stakater https://stakater.github.io/stakater-charts" ;; stakater/*) echo "stakater https://stakater.github.io/stakater-charts" ;;
victoriametrics/*) echo "victoriametrics https://victoriametrics.github.io/helm-charts" ;;
esac esac
} }
@@ -720,6 +732,7 @@ check_referenced_secrets() {
} }
stage_validate() { stage_validate() {
check_prune_mode || return 1
cd "$REPO" cd "$REPO"
select_manifests select_manifests
local m k cf local m k cf
@@ -753,18 +766,16 @@ stage_validate() {
} }
stage_apply_k8s() { stage_apply_k8s() {
check_prune_mode || return 1
cd "$REPO" cd "$REPO"
select_manifests >/dev/null select_manifests >/dev/null
local ns_files=() other_files=() m k prune_opts=() local ns_files=() other_files=() m k
for m in ${K8S_MANIFESTS[@]+"${K8S_MANIFESTS[@]}"}; do for m in ${K8S_MANIFESTS[@]+"${K8S_MANIFESTS[@]}"}; do
case "$m" in case "$m" in
*/namespace.y?ml) ns_files+=("$m") ;; */namespace.y?ml) ns_files+=("$m") ;;
*) other_files+=("$m") ;; *) other_files+=("$m") ;;
esac esac
done done
if [ "$APPLY_PRUNE" = "true" ]; then
prune_opts=(--prune -l app.kubernetes.io/managed-by=homelab-deploy)
fi
# Record what is about to change, and publish it for the verify job, before # Record what is about to change, and publish it for the verify job, before
# the first apply. Both are fatal on failure: see snapshot_dir. # the first apply. Both are fatal on failure: see snapshot_dir.
@@ -789,7 +800,7 @@ stage_apply_k8s() {
if [ "${#other_files[@]}" -gt 0 ]; then if [ "${#other_files[@]}" -gt 0 ]; then
log "Applying resources (${#other_files[@]} files, our images pinned to digests)" log "Applying resources (${#other_files[@]} files, our images pinned to digests)"
for m in "${other_files[@]}"; do for m in "${other_files[@]}"; do
if ! render_pinned <"$m" | kubectl apply "${prune_opts[@]}" -f -; then if ! render_pinned <"$m" | kubectl apply -f -; then
echo "ERROR: apply failed for ${m#"$REPO"/}" >&2 echo "ERROR: apply failed for ${m#"$REPO"/}" >&2
exit 1 exit 1
fi fi
+8 -3
View File
@@ -5,6 +5,7 @@ on:
# workflow_dispatch so a red lint/validate run can never reach the cluster. # workflow_dispatch so a red lint/validate run can never reach the cluster.
workflow_run: workflow_run:
workflows: [ci] workflows: [ci]
branches: [main]
types: [completed] types: [completed]
workflow_dispatch: workflow_dispatch:
@@ -137,9 +138,10 @@ jobs:
# lets it start after a failed dependency; the needs on apply-compose are a # lets it start after a failed dependency; the needs on apply-compose are a
# barrier, so verification begins only once both applies are done. # barrier, so verification begins only once both applies are done.
verify-k8s: verify-k8s:
needs: [apply-k8s, apply-compose] needs: [preflight, apply-k8s, apply-compose]
if: >- if: >-
always() && always() &&
needs.preflight.result == 'success' &&
needs.apply-k8s.result != 'skipped' && needs.apply-k8s.result != 'skipped' &&
needs.apply-compose.result != 'skipped' needs.apply-compose.result != 'skipped'
runs-on: [self-hosted, linux, arch, homelab, prod] runs-on: [self-hosted, linux, arch, homelab, prod]
@@ -182,8 +184,11 @@ jobs:
# suppressing them on a rollback would hide the one run where the answer # suppressing them on a rollback would hide the one run where the answer
# matters most. # matters most.
smoke: smoke:
needs: [verify-k8s] needs: [preflight, verify-k8s]
if: always() && needs.verify-k8s.result != 'skipped' if: >-
always() &&
needs.preflight.result == 'success' &&
needs.verify-k8s.result != 'skipped'
runs-on: [self-hosted, linux, arch, homelab, prod] runs-on: [self-hosted, linux, arch, homelab, prod]
timeout-minutes: 10 timeout-minutes: 10
steps: steps:
+14
View File
@@ -2,9 +2,23 @@ name: renovate-ci
on: on:
pull_request: pull_request:
paths:
- "renovate/**"
- ".gitea/workflows/renovate-ci.yaml"
- ".gitea/workflows/sync-renovate-configmap.sh"
- ".gitea/workflows/compose-lint.sh"
- ".gitea/workflows/install-ci-tools.sh"
- ".gitea/workflows/tool-versions.env"
push: push:
branches: branches:
- main - main
paths:
- "renovate/**"
- ".gitea/workflows/renovate-ci.yaml"
- ".gitea/workflows/sync-renovate-configmap.sh"
- ".gitea/workflows/compose-lint.sh"
- ".gitea/workflows/install-ci-tools.sh"
- ".gitea/workflows/tool-versions.env"
workflow_dispatch: workflow_dispatch:
permissions: permissions:
+1 -1
View File
@@ -31,7 +31,7 @@ services:
- "traefik.http.routers.adguard-dev.entrypoints=websecure" - "traefik.http.routers.adguard-dev.entrypoints=websecure"
- "traefik.http.routers.adguard-dev.tls=true" - "traefik.http.routers.adguard-dev.tls=true"
# DoH Router # DoH Router
- "traefik.http.routers.dns-over-https.rule=(Host(`dns.forust.xyz` || Host(`adguard.forust.xyz`)) && PathPrefix(`/dns-query`))" - "traefik.http.routers.dns-over-https.rule=(Host(`dns.forust.xyz`) || Host(`adguard.forust.xyz`)) && PathPrefix(`/dns-query`)"
- "traefik.http.routers.dns-over-https.entrypoints=websecure" - "traefik.http.routers.dns-over-https.entrypoints=websecure"
- "traefik.http.routers.dns-over-https.tls.certresolver=letsencrypt" - "traefik.http.routers.dns-over-https.tls.certresolver=letsencrypt"
+1 -1
View File
@@ -20,7 +20,7 @@ spec:
spec: spec:
containers: containers:
- name: cloudflared - name: cloudflared
image: cloudflare/cloudflared:2026.9.3 image: cloudflare/cloudflared:2026.10.0
imagePullPolicy: IfNotPresent imagePullPolicy: IfNotPresent
args: args:
- tunnel - tunnel
+1 -1
View File
@@ -1,4 +1,4 @@
FROM python:3.11-slim FROM python:3.14-slim
WORKDIR /app WORKDIR /app
+1 -1
View File
@@ -1,4 +1,4 @@
FROM python:3.11-slim FROM python:3.14-slim
WORKDIR /app WORKDIR /app
+1 -1
View File
@@ -71,7 +71,7 @@ spec:
name: glance-config name: glance-config
- name: glance-assets - name: glance-assets
configMap: configMap:
name: glance-config name: glance-assets
- name: docker-socket - name: docker-socket
hostPath: hostPath:
path: /var/run/docker.sock path: /var/run/docker.sock
+1 -1
View File
@@ -1,7 +1,7 @@
services: services:
homarr: homarr:
container_name: homarr container_name: homarr
image: ghcr.io/homarr-labs/homarr:v2.1.2 image: ghcr.io/homarr-labs/homarr:v2.2.0
restart: unless-stopped restart: unless-stopped
volumes: volumes:
- ./appdata:/appdata - ./appdata:/appdata
+1 -1
View File
@@ -32,7 +32,7 @@ spec:
serviceAccountName: homarr serviceAccountName: homarr
containers: containers:
- name: homarr - name: homarr
image: ghcr.io/homarr-labs/homarr:v2.1.2 image: ghcr.io/homarr-labs/homarr:v2.2.0
envFrom: envFrom:
- configMapRef: - configMapRef:
name: homarr-config name: homarr-config
+1 -1
View File
@@ -1,6 +1,6 @@
services: services:
n8n: n8n:
image: docker.n8n.io/n8nio/n8n:2.42.3 image: docker.n8n.io/n8nio/n8n:2.43.0
container_name: n8n container_name: n8n
restart: unless-stopped restart: unless-stopped
environment: environment:
+1 -1
View File
@@ -31,7 +31,7 @@ spec:
spec: spec:
containers: containers:
- name: n8n - name: n8n
image: docker.n8n.io/n8nio/n8n:2.42.3 image: docker.n8n.io/n8nio/n8n:2.43.0
envFrom: envFrom:
- configMapRef: - configMapRef:
name: n8n-config name: n8n-config
+109
View File
@@ -0,0 +1,109 @@
#!/bin/sh
set -eu
umask 077
TEMPLATE_PATH=/opt/netbird/config.template.yaml
RENDERED_PATH=/run/netbird/config.yaml
RELAY_SECRET_PATH=/run/secrets/relay_auth_secret
ENCRYPTION_KEY_PATH=/run/secrets/datastore_encryption_key
is_valid_proxy_subnet() {
candidate="$1"
case "$candidate" in
0.0.0.0/0)
return 1
;;
*/*)
address="${candidate%%/*}"
prefix="${candidate#*/}"
;;
*)
return 1
;;
esac
case "$prefix" in
0|[1-9]|[1-2][0-9]|3[0-2]) ;;
*)
return 1
;;
esac
old_ifs="$IFS"
IFS=.
# shellcheck disable=SC2086
set -- $address
IFS="$old_ifs"
[ "$#" -eq 4 ] || return 1
for octet do
case "$octet" in
0|[1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]) ;;
*)
return 1
;;
esac
done
}
read_secret() {
secret_path="$1"
if [ ! -r "$secret_path" ]; then
echo "Required secret is not readable: $secret_path" >&2
exit 1
fi
secret_value="$(cat "$secret_path")"
if [ -z "$secret_value" ]; then
echo "Required secret is empty: $secret_path" >&2
exit 1
fi
printf '%s' "$secret_value"
}
if [ -z "${NETBIRD_DOMAIN:-}" ]; then
echo "NETBIRD_DOMAIN must be set" >&2
exit 1
fi
case "$NETBIRD_DOMAIN" in
*[!A-Za-z0-9.-]*)
echo "NETBIRD_DOMAIN contains unsupported characters" >&2
exit 1
;;
esac
if [ -z "${NETBIRD_PROXY_SUBNET:-}" ] || [ "$NETBIRD_PROXY_SUBNET" = "auto" ]; then
echo "NETBIRD_PROXY_SUBNET must be an explicit IPv4 CIDR; run netbird/setup.sh first" >&2
exit 1
fi
if ! is_valid_proxy_subnet "$NETBIRD_PROXY_SUBNET"; then
echo "NETBIRD_PROXY_SUBNET must be a non-default IPv4 CIDR, for example 172.20.0.0/16" >&2
exit 1
fi
if [ "$#" -ne 2 ] || [ "$1" != "--config" ] || [ "$2" != "$RENDERED_PATH" ]; then
echo "Expected: --config $RENDERED_PATH" >&2
exit 1
fi
relay_secret="$(read_secret "$RELAY_SECRET_PATH")"
encryption_key="$(read_secret "$ENCRYPTION_KEY_PATH")"
mkdir -p "$(dirname "$RENDERED_PATH")"
sed \
-e "s|__NETBIRD_DOMAIN__|${NETBIRD_DOMAIN}|g" \
-e "s|__NETBIRD_AUTH_SECRET__|${relay_secret}|g" \
-e "s|__NETBIRD_ENCRYPTION_KEY__|${encryption_key}|g" \
-e "s|__NETBIRD_PROXY_SUBNET__|${NETBIRD_PROXY_SUBNET}|g" \
"$TEMPLATE_PATH" >"$RENDERED_PATH"
if grep -q '__NETBIRD_' "$RENDERED_PATH"; then
echo "Rendered NetBird configuration still contains unresolved placeholders" >&2
exit 1
fi
exec /go/bin/netbird-server "$@"
+38
View File
@@ -0,0 +1,38 @@
#!/usr/bin/env bash
# Prepare local Compose configuration without replacing existing credentials.
set -euo pipefail
cd "$(dirname "${BASH_SOURCE[0]}")"
umask 077
if [ ! -f .env ]; then
cp .env.example .env
fi
if grep -q '^NETBIRD_PROXY_SUBNET=auto$' .env; then
subnet="$(docker network inspect proxy --format '{{range .IPAM.Config}}{{println .Subnet}}{{end}}' | awk '/^[0-9]+\./ { print; exit }')"
if [ -z "$subnet" ]; then
echo "No IPv4 subnet found on the Docker proxy network. Set NETBIRD_PROXY_SUBNET in .env." >&2
exit 1
fi
# The detected value must be safe to substitute into the env file.
if [[ ! "$subnet" =~ ^[0-9.]+/[0-9]+$ ]]; then
echo "Unexpected Docker network subnet: $subnet" >&2
exit 1
fi
sed -i "s|^NETBIRD_PROXY_SUBNET=auto$|NETBIRD_PROXY_SUBNET=$subnet|" .env
fi
mkdir -p secrets
chmod 700 secrets
for name in relay-auth-secret datastore-encryption-key; do
path="secrets/$name"
if [ -e "$path" ]; then
if [ ! -s "$path" ]; then
echo "Existing secret is empty: $path. Restore it before continuing." >&2
exit 1
fi
else
openssl rand -base64 32 >"$path"
fi
chmod 600 "$path"
done
printf '%s\n' 'Local files are ready. Review .env, then run docker compose config --quiet.'
+1 -1
View File
@@ -1,6 +1,6 @@
services: services:
netronome: netronome:
image: ghcr.io/autobrr/netronome:v0.15.0 image: ghcr.io/autobrr/netronome:v0.16.0
restart: unless-stopped restart: unless-stopped
container_name: netronome container_name: netronome
ports: ports:
+1 -1
View File
@@ -34,7 +34,7 @@ spec:
spec: spec:
containers: containers:
- name: netronome - name: netronome
image: ghcr.io/autobrr/netronome:v0.15.0 image: ghcr.io/autobrr/netronome:v0.16.0
ports: ports:
- name: netronome-port - name: netronome-port
protocol: TCP protocol: TCP
+1
View File
@@ -1,6 +1,7 @@
POSTGRES_ADMIN_PASSWORD= POSTGRES_ADMIN_PASSWORD=
AUTHENTIK_DB_PASSWORD= AUTHENTIK_DB_PASSWORD=
GITEA_DB_PASSWORD= GITEA_DB_PASSWORD=
NETBOX_DB_PASSWORD=
NETRONOME_DB_PASSWORD= NETRONOME_DB_PASSWORD=
PENPOT_DB_PASSWORD= PENPOT_DB_PASSWORD=
STATUSPAGE_DB_PASSWORD= STATUSPAGE_DB_PASSWORD=
+17
View File
@@ -0,0 +1,17 @@
# VictoriaMetrics
The `victoria-operator` Helm release converts Prometheus Operator
`ServiceMonitor` resources into owned `VMServiceScrape` resources. The
`VMAgent` selects converted scrapes labeled `release: prometheus-stack` in all
namespaces and writes them to the existing single-node VictoriaMetrics
instance. Changes to selected `ServiceMonitor` resources are reconciled
automatically; there is no copied Prometheus scrape-config blob to regenerate.
The agent drops targets for the Prometheus server service to avoid duplicating
its self-scrape. `scraper: victoria` identifies the samples ingested by this
VMAgent.
The VictoriaMetrics Operator chart and its CRDs are installed before the
Kubernetes manifests by the normal deploy workflow. On a cluster where the
operator CRDs are not installed yet, CI skips the server-side dry-run of the
`VMAgent` resource; the deploy installs the chart before applying that resource.
+7
View File
@@ -38,6 +38,8 @@ grafana:
# One block covers both the dashboards and datasources sidecars (p95 91M / 80M). # One block covers both the dashboards and datasources sidecars (p95 91M / 80M).
sidecar: sidecar:
datasources:
defaultDatasourceEnabled: false
resources: resources:
requests: requests:
memory: "96Mi" memory: "96Mi"
@@ -50,6 +52,11 @@ grafana:
type: loki type: loki
url: http://loki-gateway.prometheus.svc.cluster.local url: http://loki-gateway.prometheus.svc.cluster.local
access: proxy access: proxy
- name: VictoriaMetrics
type: prometheus
url: http://victoria-metrics.prometheus.svc.cluster.local:8428
access: proxy
isDefault: true
prometheus: prometheus:
prometheusSpec: prometheusSpec:
+102
View File
@@ -31,3 +31,105 @@ spec:
port: 80 port: 80
tls: tls:
secretName: internal-wildcard-tls secretName: internal-wildcard-tls
---
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: prometheus-local
namespace: prometheus
spec:
entryPoints:
- websecure
routes:
- match: Host(`prom.workstation.internal`) || Host(`prom.gigaforust.internal`)
kind: Rule
services:
- name: prometheus-stack-kube-prom-prometheus
port: 9090
tls:
secretName: internal-wildcard-tls
---
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: alertmanager-local
namespace: prometheus
spec:
entryPoints:
- websecure
routes:
- match: Host(`am.workstation.internal`) || Host(`am.gigaforust.internal`)
kind: Rule
services:
- name: prometheus-stack-kube-prom-alertmanager
port: 9093
tls:
secretName: internal-wildcard-tls
---
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: loki-local
namespace: prometheus
spec:
entryPoints:
- websecure
routes:
- match: Host(`loki.workstation.internal`) || Host(`loki.gigaforust.internal`)
kind: Rule
services:
- name: loki-gateway
port: 80
tls:
secretName: internal-wildcard-tls
---
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: alloy-local
namespace: prometheus
spec:
entryPoints:
- websecure
routes:
- match: Host(`alloy.workstation.internal`) || Host(`alloy.gigaforust.internal`)
kind: Rule
services:
- name: alloy
port: 12345
tls:
secretName: internal-wildcard-tls
---
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: victoria-local
namespace: prometheus
spec:
entryPoints:
- websecure
routes:
- match: Host(`victoria.workstation.internal`) || Host(`victoria.gigaforust.internal`)
kind: Rule
services:
- name: victoria-metrics
port: 8428
tls:
secretName: internal-wildcard-tls
---
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: vmalert-local
namespace: prometheus
spec:
entryPoints:
- websecure
routes:
- match: Host(`vmalert.workstation.internal`) || Host(`vmalert.gigaforust.internal`)
kind: Rule
services:
- name: vmalert
port: 8880
tls:
secretName: internal-wildcard-tls
@@ -0,0 +1,12 @@
nameOverride: victoria-operator
operator:
enable_converter_ownership: true
resources:
requests:
cpu: 50m
memory: 96Mi
limits:
cpu: 200m
memory: 256Mi
+79
View File
@@ -0,0 +1,79 @@
apiVersion: v1
kind: Service
metadata:
name: victoria-metrics
namespace: prometheus
spec:
selector:
app: victoria-metrics
ports:
- port: 8428
targetPort: 8428
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: victoria-pvc
namespace: prometheus
spec:
resources:
requests:
storage: 10Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: victoria-deployment
namespace: prometheus
spec:
replicas: 1
selector:
matchLabels:
app: victoria-metrics
strategy:
type: Recreate
template:
metadata:
labels:
app: victoria-metrics
spec:
containers:
- name: victoria
image: victoriametrics/victoria-metrics:v1.153.0-scratch
args:
- -storageDataPath=/vmdata
- -retentionPeriod=30d
- -httpListenAddr=:8428
ports:
- containerPort: 8428
readinessProbe:
httpGet:
path: /health
port: 8428
initialDelaySeconds: 15
periodSeconds: 10
failureThreshold: 6
livenessProbe:
httpGet:
path: /health
port: 8428
initialDelaySeconds: 60
periodSeconds: 30
failureThreshold: 3
volumeMounts:
- name: vmdata
mountPath: /vmdata
resources:
requests:
cpu: "100m"
memory: "256Mi"
limits:
cpu: "1000m"
memory: "1Gi"
volumes:
- name: vmdata
persistentVolumeClaim:
claimName: victoria-pvc
+29
View File
@@ -0,0 +1,29 @@
apiVersion: operator.victoriametrics.com/v1beta1
kind: VMAgent
metadata:
name: vmagent
namespace: prometheus
spec:
image:
tag: v1.153.0
scrapeInterval: 30s
externalLabels:
scraper: victoria
serviceScrapeNamespaceSelector: {}
serviceScrapeSelector:
matchLabels:
release: prometheus-stack
globalScrapeRelabelConfigs:
- action: drop
source_labels:
- __meta_kubernetes_service_name
regex: prometheus-stack-kube-prom-prometheus
remoteWrite:
- url: http://victoria-metrics.prometheus.svc.cluster.local:8428/api/v1/write
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
cpu: "1000m"
memory: 1Gi
+70
View File
@@ -0,0 +1,70 @@
apiVersion: v1
kind: Service
metadata:
name: vmalert
namespace: prometheus
spec:
selector:
app: vmalert
ports:
- port: 8880
targetPort: 8880
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: vmalert-deployment
namespace: prometheus
spec:
replicas: 1
selector:
matchLabels:
app: vmalert
strategy:
type: Recreate
template:
metadata:
labels:
app: vmalert
spec:
containers:
- name: vmalert
image: victoriametrics/vmalert:v1.153.0
args:
- -datasource.url=http://victoria-metrics.prometheus.svc.cluster.local:8428
- -remoteWrite.url=http://victoria-metrics.prometheus.svc.cluster.local:8428
- -notifier.url=http://prometheus-stack-kube-prom-alertmanager.prometheus.svc.cluster.local:9093
- -rule=/etc/vm/rules/*.yaml
- -evaluationInterval=60s
- -httpListenAddr=:8880
ports:
- containerPort: 8880
readinessProbe:
httpGet:
path: /metrics
port: 8880
initialDelaySeconds: 15
periodSeconds: 10
failureThreshold: 6
livenessProbe:
httpGet:
path: /metrics
port: 8880
initialDelaySeconds: 60
periodSeconds: 30
failureThreshold: 3
volumeMounts:
- name: rules
mountPath: /etc/vm/rules
readOnly: true
resources:
requests:
cpu: "50m"
memory: "64Mi"
limits:
cpu: "200m"
memory: "256Mi"
volumes:
- name: rules
configMap:
name: prometheus-prometheus-stack-kube-prom-prometheus-rulefiles-0
+48 -25
View File
@@ -19,6 +19,9 @@ data:
"dependencyDashboard": true, "dependencyDashboard": true,
"prCreation": "immediate", "prCreation": "immediate",
"labels": ["dependencies", "automated"], "labels": ["dependencies", "automated"],
"docker-compose": {
"managerFilePatterns": ["renovate/renovate-compose.yaml"]
},
"helm-values": { "helm-values": {
"managerFilePatterns": ["/k8s/.+values\\.ya?ml$/"] "managerFilePatterns": ["/k8s/.+values\\.ya?ml$/"]
}, },
@@ -29,7 +32,7 @@ data:
{ {
"customType": "regex", "customType": "regex",
"description": "singlesource: playwright npm version pinned in npx command (k8s + compose)", "description": "singlesource: playwright npm version pinned in npx command (k8s + compose)",
"managerFilePatterns": ["^edu_master/k8s/playwright\\.yaml$", "^edu_master/compose\\.yaml$"], "managerFilePatterns": ["edu_master/k8s/playwright.yaml", "edu_master/compose.yaml"],
"matchStrings": ["playwright@(?<currentValue>\\d+\\.\\d+\\.\\d+)"], "matchStrings": ["playwright@(?<currentValue>\\d+\\.\\d+\\.\\d+)"],
"datasourceTemplate": "npm", "datasourceTemplate": "npm",
"depNameTemplate": "playwright" "depNameTemplate": "playwright"
@@ -37,24 +40,42 @@ data:
{ {
"customType": "regex", "customType": "regex",
"description": "singlesource: PLAYWRIGHT_VERSION file", "description": "singlesource: PLAYWRIGHT_VERSION file",
"managerFilePatterns": ["^edu_master/PLAYWRIGHT_VERSION$"], "managerFilePatterns": ["edu_master/PLAYWRIGHT_VERSION"],
"matchStrings": ["^(?<currentValue>\\d+\\.\\d+\\.\\d+)$"], "matchStrings": ["^(?<currentValue>\\d+\\.\\d+\\.\\d+)(?:\\r?\\n)?$"],
"datasourceTemplate": "pypi", "datasourceTemplate": "pypi",
"depNameTemplate": "playwright" "depNameTemplate": "playwright"
}, },
{
"customType": "regex",
"description": "singlesource: playwright Python client version pinned in Dockerfile ARG",
"managerFilePatterns": ["edu_master/webinar-checker/Dockerfile"],
"matchStrings": ["(?:^|\\n)ARG PLAYWRIGHT_VERSION=(?<currentValue>\\d+\\.\\d+\\.\\d+)(?:\\r?\\n|$)"],
"datasourceTemplate": "pypi",
"depNameTemplate": "playwright",
"versioningTemplate": "pep440"
},
{ {
"customType": "regex", "customType": "regex",
"description": "kube-prometheus-stack chart version pinned in the deploy workflow", "description": "kube-prometheus-stack chart version pinned in the deploy workflow",
"managerFilePatterns": ["^\\.gitea/workflows/deploy-lib\\.sh$"], "managerFilePatterns": [".gitea/workflows/deploy-lib.sh"],
"matchStrings": ["\\|prometheus-community/kube-prometheus-stack\\|prometheus\\|(?<currentValue>[0-9.]+)\\|"], "matchStrings": ["\\|prometheus-community/kube-prometheus-stack\\|prometheus\\|(?<currentValue>[0-9.]+)\\|"],
"datasourceTemplate": "helm", "datasourceTemplate": "helm",
"depNameTemplate": "kube-prometheus-stack", "depNameTemplate": "kube-prometheus-stack",
"registryUrlTemplate": "https://prometheus-community.github.io/helm-charts" "registryUrlTemplate": "https://prometheus-community.github.io/helm-charts"
}, },
{
"customType": "regex",
"description": "VictoriaMetrics Operator chart version pinned in the deploy workflow",
"managerFilePatterns": [".gitea/workflows/deploy-lib.sh"],
"matchStrings": ["\\|victoriametrics/victoria-metrics-operator\\|prometheus\\|(?<currentValue>[0-9.]+)\\|"],
"datasourceTemplate": "helm",
"depNameTemplate": "victoria-metrics-operator",
"registryUrlTemplate": "https://victoriametrics.github.io/helm-charts"
},
{ {
"customType": "regex", "customType": "regex",
"description": "grafana/loki chart version pinned in the deploy workflow", "description": "grafana/loki chart version pinned in the deploy workflow",
"managerFilePatterns": ["^\\.gitea/workflows/deploy-lib\\.sh$"], "managerFilePatterns": [".gitea/workflows/deploy-lib.sh"],
"matchStrings": ["\\|grafana/loki\\|prometheus\\|(?<currentValue>[0-9.]+)\\|"], "matchStrings": ["\\|grafana/loki\\|prometheus\\|(?<currentValue>[0-9.]+)\\|"],
"datasourceTemplate": "helm", "datasourceTemplate": "helm",
"depNameTemplate": "loki", "depNameTemplate": "loki",
@@ -63,7 +84,7 @@ data:
{ {
"customType": "regex", "customType": "regex",
"description": "grafana/alloy chart version pinned in the deploy workflow", "description": "grafana/alloy chart version pinned in the deploy workflow",
"managerFilePatterns": ["^\\.gitea/workflows/deploy-lib\\.sh$"], "managerFilePatterns": [".gitea/workflows/deploy-lib.sh"],
"matchStrings": ["\\|grafana/alloy\\|prometheus\\|(?<currentValue>[0-9.]+)\\|"], "matchStrings": ["\\|grafana/alloy\\|prometheus\\|(?<currentValue>[0-9.]+)\\|"],
"datasourceTemplate": "helm", "datasourceTemplate": "helm",
"depNameTemplate": "alloy", "depNameTemplate": "alloy",
@@ -72,7 +93,7 @@ data:
{ {
"customType": "regex", "customType": "regex",
"description": "actionlint version used by the ci workflow", "description": "actionlint version used by the ci workflow",
"managerFilePatterns": ["^\\.gitea/workflows/tool-versions\\.env$"], "managerFilePatterns": [".gitea/workflows/tool-versions.env"],
"matchStrings": ["(?:^|\\n)ACTIONLINT_VERSION=\"(?<currentValue>[0-9.]+)\""], "matchStrings": ["(?:^|\\n)ACTIONLINT_VERSION=\"(?<currentValue>[0-9.]+)\""],
"datasourceTemplate": "github-tags", "datasourceTemplate": "github-tags",
"depNameTemplate": "rhysd/actionlint" "depNameTemplate": "rhysd/actionlint"
@@ -80,7 +101,7 @@ data:
{ {
"customType": "regex", "customType": "regex",
"description": "shellcheck version used by the ci workflow", "description": "shellcheck version used by the ci workflow",
"managerFilePatterns": ["^\\.gitea/workflows/tool-versions\\.env$"], "managerFilePatterns": [".gitea/workflows/tool-versions.env"],
"matchStrings": ["(?:^|\\n)SHELLCHECK_VERSION=\"(?<currentValue>[0-9.]+)\""], "matchStrings": ["(?:^|\\n)SHELLCHECK_VERSION=\"(?<currentValue>[0-9.]+)\""],
"datasourceTemplate": "github-tags", "datasourceTemplate": "github-tags",
"depNameTemplate": "koalaman/shellcheck" "depNameTemplate": "koalaman/shellcheck"
@@ -88,7 +109,7 @@ data:
{ {
"customType": "regex", "customType": "regex",
"description": "kubeconform version used by the ci workflow", "description": "kubeconform version used by the ci workflow",
"managerFilePatterns": ["^\\.gitea/workflows/tool-versions\\.env$"], "managerFilePatterns": [".gitea/workflows/tool-versions.env"],
"matchStrings": ["(?:^|\\n)KUBECONFORM_VERSION=\"(?<currentValue>[0-9.]+)\""], "matchStrings": ["(?:^|\\n)KUBECONFORM_VERSION=\"(?<currentValue>[0-9.]+)\""],
"datasourceTemplate": "github-tags", "datasourceTemplate": "github-tags",
"depNameTemplate": "yannh/kubeconform" "depNameTemplate": "yannh/kubeconform"
@@ -96,7 +117,7 @@ data:
{ {
"customType": "regex", "customType": "regex",
"description": "uv version used to build the pytest venv", "description": "uv version used to build the pytest venv",
"managerFilePatterns": ["^\\.gitea/workflows/tool-versions\\.env$"], "managerFilePatterns": [".gitea/workflows/tool-versions.env"],
"matchStrings": ["(?:^|\\n)UV_VERSION=\"(?<currentValue>[0-9.]+)\""], "matchStrings": ["(?:^|\\n)UV_VERSION=\"(?<currentValue>[0-9.]+)\""],
"datasourceTemplate": "github-tags", "datasourceTemplate": "github-tags",
"depNameTemplate": "astral-sh/uv" "depNameTemplate": "astral-sh/uv"
@@ -104,7 +125,7 @@ data:
{ {
"customType": "regex", "customType": "regex",
"description": "prettier version used by the ci workflow", "description": "prettier version used by the ci workflow",
"managerFilePatterns": ["^\\.gitea/workflows/tool-versions\\.env$"], "managerFilePatterns": [".gitea/workflows/tool-versions.env"],
"matchStrings": ["(?:^|\\n)PRETTIER_VERSION=\"(?<currentValue>[0-9.]+)\""], "matchStrings": ["(?:^|\\n)PRETTIER_VERSION=\"(?<currentValue>[0-9.]+)\""],
"datasourceTemplate": "npm", "datasourceTemplate": "npm",
"depNameTemplate": "prettier" "depNameTemplate": "prettier"
@@ -112,7 +133,7 @@ data:
{ {
"customType": "regex", "customType": "regex",
"description": "ruff version used by the ci workflow", "description": "ruff version used by the ci workflow",
"managerFilePatterns": ["^\\.gitea/workflows/tool-versions\\.env$"], "managerFilePatterns": [".gitea/workflows/tool-versions.env"],
"matchStrings": ["(?:^|\\n)RUFF_VERSION=\"(?<currentValue>[0-9.]+)\""], "matchStrings": ["(?:^|\\n)RUFF_VERSION=\"(?<currentValue>[0-9.]+)\""],
"datasourceTemplate": "pypi", "datasourceTemplate": "pypi",
"depNameTemplate": "ruff" "depNameTemplate": "ruff"
@@ -120,7 +141,7 @@ data:
{ {
"customType": "regex", "customType": "regex",
"description": "pip-audit version used by the ci workflow", "description": "pip-audit version used by the ci workflow",
"managerFilePatterns": ["^\\.gitea/workflows/tool-versions\\.env$"], "managerFilePatterns": [".gitea/workflows/tool-versions.env"],
"matchStrings": ["(?:^|\\n)PIP_AUDIT_VERSION=\"(?<currentValue>[0-9.]+)\""], "matchStrings": ["(?:^|\\n)PIP_AUDIT_VERSION=\"(?<currentValue>[0-9.]+)\""],
"datasourceTemplate": "pypi", "datasourceTemplate": "pypi",
"depNameTemplate": "pip-audit" "depNameTemplate": "pip-audit"
@@ -128,7 +149,7 @@ data:
{ {
"customType": "regex", "customType": "regex",
"description": "yamllint version used by the ci workflow", "description": "yamllint version used by the ci workflow",
"managerFilePatterns": ["^\\.gitea/workflows/tool-versions\\.env$"], "managerFilePatterns": [".gitea/workflows/tool-versions.env"],
"matchStrings": ["(?:^|\\n)YAMLLINT_VERSION=\"(?<currentValue>[0-9.]+)\""], "matchStrings": ["(?:^|\\n)YAMLLINT_VERSION=\"(?<currentValue>[0-9.]+)\""],
"datasourceTemplate": "pypi", "datasourceTemplate": "pypi",
"depNameTemplate": "yamllint" "depNameTemplate": "yamllint"
@@ -136,7 +157,7 @@ data:
{ {
"customType": "regex", "customType": "regex",
"description": "hadolint version used by the ci workflow", "description": "hadolint version used by the ci workflow",
"managerFilePatterns": ["^\\.gitea/workflows/tool-versions\\.env$"], "managerFilePatterns": [".gitea/workflows/tool-versions.env"],
"matchStrings": ["(?:^|\\n)HADOLINT_VERSION=\"(?<currentValue>[0-9.]+)\""], "matchStrings": ["(?:^|\\n)HADOLINT_VERSION=\"(?<currentValue>[0-9.]+)\""],
"datasourceTemplate": "github-tags", "datasourceTemplate": "github-tags",
"depNameTemplate": "hadolint/hadolint" "depNameTemplate": "hadolint/hadolint"
@@ -144,7 +165,7 @@ data:
{ {
"customType": "regex", "customType": "regex",
"description": "node version the ci workflow runs npm with", "description": "node version the ci workflow runs npm with",
"managerFilePatterns": ["^\\.gitea/workflows/tool-versions\\.env$"], "managerFilePatterns": [".gitea/workflows/tool-versions.env"],
"matchStrings": ["(?:^|\\n)NODE_VERSION=\"(?<currentValue>[0-9.]+)\""], "matchStrings": ["(?:^|\\n)NODE_VERSION=\"(?<currentValue>[0-9.]+)\""],
"datasourceTemplate": "node", "datasourceTemplate": "node",
"depNameTemplate": "node" "depNameTemplate": "node"
@@ -152,7 +173,7 @@ data:
{ {
"customType": "regex", "customType": "regex",
"description": "stakater/reloader chart version pinned in the deploy workflow", "description": "stakater/reloader chart version pinned in the deploy workflow",
"managerFilePatterns": ["^\\.gitea/workflows/deploy-lib\\.sh$"], "managerFilePatterns": [".gitea/workflows/deploy-lib.sh"],
"matchStrings": ["\\|stakater/reloader\\|reloader\\|(?<currentValue>[0-9.]+)\\|"], "matchStrings": ["\\|stakater/reloader\\|reloader\\|(?<currentValue>[0-9.]+)\\|"],
"datasourceTemplate": "helm", "datasourceTemplate": "helm",
"depNameTemplate": "reloader", "depNameTemplate": "reloader",
@@ -161,7 +182,7 @@ data:
], ],
"packageRules": [ "packageRules": [
{ {
"description": "Automerge digest and patch updates - safe by definition, review adds nothing, keeps the renovate queue and the deploy line short. Specific no-automerge rules below still override this for playwright, helm and majors.", "description": "Automerge ordinary digest and patch updates after successful checks; specific manual-review rules below override this.",
"matchUpdateTypes": ["digest", "patch"], "matchUpdateTypes": ["digest", "patch"],
"automerge": true "automerge": true
}, },
@@ -172,6 +193,12 @@ data:
"groupSlug": "all-minor", "groupSlug": "all-minor",
"automerge": false "automerge": false
}, },
{
"description": "Group ordinary patch updates; the specific groups and manual-review rules below take precedence",
"matchUpdateTypes": ["patch"],
"groupName": "all patch updates",
"groupSlug": "all-patch"
},
{ {
"description": "Keep private homelab images unchanged", "description": "Keep private homelab images unchanged",
"matchDatasources": ["docker"], "matchDatasources": ["docker"],
@@ -196,7 +223,7 @@ data:
"automerge": false "automerge": false
}, },
{ {
"description": "CI runs npm on the node the panel image is built from - the NODE_VERSION pin in tool-versions.env and node:22-alpine in the Dockerfile are the same dependency and move as one", "description": "Keep CI Node runtime updates in a separate, manually reviewed group",
"matchPackageNames": ["node"], "matchPackageNames": ["node"],
"groupName": "node runtime", "groupName": "node runtime",
"groupSlug": "node", "groupSlug": "node",
@@ -205,6 +232,8 @@ data:
{ {
"description": "Helm chart bumps change PVC fields and admission behaviour, keep them reviewable", "description": "Helm chart bumps change PVC fields and admission behaviour, keep them reviewable",
"matchDatasources": ["helm"], "matchDatasources": ["helm"],
"groupName": "Helm chart {{depName}}",
"groupSlug": "helm-{{depName}}",
"automerge": false "automerge": false
}, },
{ {
@@ -213,12 +242,6 @@ data:
"dependencyDashboardApproval": true, "dependencyDashboardApproval": true,
"automerge": false "automerge": false
}, },
{
"description": "Group patch updates from all sources - automerge still applies via the digest/patch rule above (helm/playwright stay manual via their own rules)",
"matchUpdateTypes": ["patch"],
"groupName": "all patch updates",
"groupSlug": "all-patch"
},
{ {
"description": "Python Y-bumps break compat (3.11->3.12->3.13->3.14) - keep the base image out of the shared minor/patch groups, review every bump separately. Placed last so its groupName wins.", "description": "Python Y-bumps break compat (3.11->3.12->3.13->3.14) - keep the base image out of the shared minor/patch groups, review every bump separately. Placed last so its groupName wins.",
"matchDatasources": ["docker"], "matchDatasources": ["docker"],
+1 -1
View File
@@ -19,7 +19,7 @@ spec:
restartPolicy: Never restartPolicy: Never
containers: containers:
- name: renovate - name: renovate
image: renovate/renovate:44.136.0 image: renovate/renovate:44.140.0
env: env:
- name: RENOVATE_PLATFORM - name: RENOVATE_PLATFORM
value: gitea value: gitea
+1 -1
View File
@@ -2,7 +2,7 @@ services:
renovate: renovate:
# Kept in step with renovate/k8s/cronjob.yaml by the "renovate self-update" # Kept in step with renovate/k8s/cronjob.yaml by the "renovate self-update"
# package rule in renovate/renovate.json. # package rule in renovate/renovate.json.
image: renovate/renovate:44.115.9 image: renovate/renovate:44.136.0
container_name: renovate container_name: renovate
restart: "no" restart: "no"
env_file: env_file:
+48 -25
View File
@@ -8,6 +8,9 @@
"dependencyDashboard": true, "dependencyDashboard": true,
"prCreation": "immediate", "prCreation": "immediate",
"labels": ["dependencies", "automated"], "labels": ["dependencies", "automated"],
"docker-compose": {
"managerFilePatterns": ["renovate/renovate-compose.yaml"]
},
"helm-values": { "helm-values": {
"managerFilePatterns": ["/k8s/.+values\\.ya?ml$/"] "managerFilePatterns": ["/k8s/.+values\\.ya?ml$/"]
}, },
@@ -18,7 +21,7 @@
{ {
"customType": "regex", "customType": "regex",
"description": "singlesource: playwright npm version pinned in npx command (k8s + compose)", "description": "singlesource: playwright npm version pinned in npx command (k8s + compose)",
"managerFilePatterns": ["^edu_master/k8s/playwright\\.yaml$", "^edu_master/compose\\.yaml$"], "managerFilePatterns": ["edu_master/k8s/playwright.yaml", "edu_master/compose.yaml"],
"matchStrings": ["playwright@(?<currentValue>\\d+\\.\\d+\\.\\d+)"], "matchStrings": ["playwright@(?<currentValue>\\d+\\.\\d+\\.\\d+)"],
"datasourceTemplate": "npm", "datasourceTemplate": "npm",
"depNameTemplate": "playwright" "depNameTemplate": "playwright"
@@ -26,24 +29,42 @@
{ {
"customType": "regex", "customType": "regex",
"description": "singlesource: PLAYWRIGHT_VERSION file", "description": "singlesource: PLAYWRIGHT_VERSION file",
"managerFilePatterns": ["^edu_master/PLAYWRIGHT_VERSION$"], "managerFilePatterns": ["edu_master/PLAYWRIGHT_VERSION"],
"matchStrings": ["^(?<currentValue>\\d+\\.\\d+\\.\\d+)$"], "matchStrings": ["^(?<currentValue>\\d+\\.\\d+\\.\\d+)(?:\\r?\\n)?$"],
"datasourceTemplate": "pypi", "datasourceTemplate": "pypi",
"depNameTemplate": "playwright" "depNameTemplate": "playwright"
}, },
{
"customType": "regex",
"description": "singlesource: playwright Python client version pinned in Dockerfile ARG",
"managerFilePatterns": ["edu_master/webinar-checker/Dockerfile"],
"matchStrings": ["(?:^|\\n)ARG PLAYWRIGHT_VERSION=(?<currentValue>\\d+\\.\\d+\\.\\d+)(?:\\r?\\n|$)"],
"datasourceTemplate": "pypi",
"depNameTemplate": "playwright",
"versioningTemplate": "pep440"
},
{ {
"customType": "regex", "customType": "regex",
"description": "kube-prometheus-stack chart version pinned in the deploy workflow", "description": "kube-prometheus-stack chart version pinned in the deploy workflow",
"managerFilePatterns": ["^\\.gitea/workflows/deploy-lib\\.sh$"], "managerFilePatterns": [".gitea/workflows/deploy-lib.sh"],
"matchStrings": ["\\|prometheus-community/kube-prometheus-stack\\|prometheus\\|(?<currentValue>[0-9.]+)\\|"], "matchStrings": ["\\|prometheus-community/kube-prometheus-stack\\|prometheus\\|(?<currentValue>[0-9.]+)\\|"],
"datasourceTemplate": "helm", "datasourceTemplate": "helm",
"depNameTemplate": "kube-prometheus-stack", "depNameTemplate": "kube-prometheus-stack",
"registryUrlTemplate": "https://prometheus-community.github.io/helm-charts" "registryUrlTemplate": "https://prometheus-community.github.io/helm-charts"
}, },
{
"customType": "regex",
"description": "VictoriaMetrics Operator chart version pinned in the deploy workflow",
"managerFilePatterns": [".gitea/workflows/deploy-lib.sh"],
"matchStrings": ["\\|victoriametrics/victoria-metrics-operator\\|prometheus\\|(?<currentValue>[0-9.]+)\\|"],
"datasourceTemplate": "helm",
"depNameTemplate": "victoria-metrics-operator",
"registryUrlTemplate": "https://victoriametrics.github.io/helm-charts"
},
{ {
"customType": "regex", "customType": "regex",
"description": "grafana/loki chart version pinned in the deploy workflow", "description": "grafana/loki chart version pinned in the deploy workflow",
"managerFilePatterns": ["^\\.gitea/workflows/deploy-lib\\.sh$"], "managerFilePatterns": [".gitea/workflows/deploy-lib.sh"],
"matchStrings": ["\\|grafana/loki\\|prometheus\\|(?<currentValue>[0-9.]+)\\|"], "matchStrings": ["\\|grafana/loki\\|prometheus\\|(?<currentValue>[0-9.]+)\\|"],
"datasourceTemplate": "helm", "datasourceTemplate": "helm",
"depNameTemplate": "loki", "depNameTemplate": "loki",
@@ -52,7 +73,7 @@
{ {
"customType": "regex", "customType": "regex",
"description": "grafana/alloy chart version pinned in the deploy workflow", "description": "grafana/alloy chart version pinned in the deploy workflow",
"managerFilePatterns": ["^\\.gitea/workflows/deploy-lib\\.sh$"], "managerFilePatterns": [".gitea/workflows/deploy-lib.sh"],
"matchStrings": ["\\|grafana/alloy\\|prometheus\\|(?<currentValue>[0-9.]+)\\|"], "matchStrings": ["\\|grafana/alloy\\|prometheus\\|(?<currentValue>[0-9.]+)\\|"],
"datasourceTemplate": "helm", "datasourceTemplate": "helm",
"depNameTemplate": "alloy", "depNameTemplate": "alloy",
@@ -61,7 +82,7 @@
{ {
"customType": "regex", "customType": "regex",
"description": "actionlint version used by the ci workflow", "description": "actionlint version used by the ci workflow",
"managerFilePatterns": ["^\\.gitea/workflows/tool-versions\\.env$"], "managerFilePatterns": [".gitea/workflows/tool-versions.env"],
"matchStrings": ["(?:^|\\n)ACTIONLINT_VERSION=\"(?<currentValue>[0-9.]+)\""], "matchStrings": ["(?:^|\\n)ACTIONLINT_VERSION=\"(?<currentValue>[0-9.]+)\""],
"datasourceTemplate": "github-tags", "datasourceTemplate": "github-tags",
"depNameTemplate": "rhysd/actionlint" "depNameTemplate": "rhysd/actionlint"
@@ -69,7 +90,7 @@
{ {
"customType": "regex", "customType": "regex",
"description": "shellcheck version used by the ci workflow", "description": "shellcheck version used by the ci workflow",
"managerFilePatterns": ["^\\.gitea/workflows/tool-versions\\.env$"], "managerFilePatterns": [".gitea/workflows/tool-versions.env"],
"matchStrings": ["(?:^|\\n)SHELLCHECK_VERSION=\"(?<currentValue>[0-9.]+)\""], "matchStrings": ["(?:^|\\n)SHELLCHECK_VERSION=\"(?<currentValue>[0-9.]+)\""],
"datasourceTemplate": "github-tags", "datasourceTemplate": "github-tags",
"depNameTemplate": "koalaman/shellcheck" "depNameTemplate": "koalaman/shellcheck"
@@ -77,7 +98,7 @@
{ {
"customType": "regex", "customType": "regex",
"description": "kubeconform version used by the ci workflow", "description": "kubeconform version used by the ci workflow",
"managerFilePatterns": ["^\\.gitea/workflows/tool-versions\\.env$"], "managerFilePatterns": [".gitea/workflows/tool-versions.env"],
"matchStrings": ["(?:^|\\n)KUBECONFORM_VERSION=\"(?<currentValue>[0-9.]+)\""], "matchStrings": ["(?:^|\\n)KUBECONFORM_VERSION=\"(?<currentValue>[0-9.]+)\""],
"datasourceTemplate": "github-tags", "datasourceTemplate": "github-tags",
"depNameTemplate": "yannh/kubeconform" "depNameTemplate": "yannh/kubeconform"
@@ -85,7 +106,7 @@
{ {
"customType": "regex", "customType": "regex",
"description": "uv version used to build the pytest venv", "description": "uv version used to build the pytest venv",
"managerFilePatterns": ["^\\.gitea/workflows/tool-versions\\.env$"], "managerFilePatterns": [".gitea/workflows/tool-versions.env"],
"matchStrings": ["(?:^|\\n)UV_VERSION=\"(?<currentValue>[0-9.]+)\""], "matchStrings": ["(?:^|\\n)UV_VERSION=\"(?<currentValue>[0-9.]+)\""],
"datasourceTemplate": "github-tags", "datasourceTemplate": "github-tags",
"depNameTemplate": "astral-sh/uv" "depNameTemplate": "astral-sh/uv"
@@ -93,7 +114,7 @@
{ {
"customType": "regex", "customType": "regex",
"description": "prettier version used by the ci workflow", "description": "prettier version used by the ci workflow",
"managerFilePatterns": ["^\\.gitea/workflows/tool-versions\\.env$"], "managerFilePatterns": [".gitea/workflows/tool-versions.env"],
"matchStrings": ["(?:^|\\n)PRETTIER_VERSION=\"(?<currentValue>[0-9.]+)\""], "matchStrings": ["(?:^|\\n)PRETTIER_VERSION=\"(?<currentValue>[0-9.]+)\""],
"datasourceTemplate": "npm", "datasourceTemplate": "npm",
"depNameTemplate": "prettier" "depNameTemplate": "prettier"
@@ -101,7 +122,7 @@
{ {
"customType": "regex", "customType": "regex",
"description": "ruff version used by the ci workflow", "description": "ruff version used by the ci workflow",
"managerFilePatterns": ["^\\.gitea/workflows/tool-versions\\.env$"], "managerFilePatterns": [".gitea/workflows/tool-versions.env"],
"matchStrings": ["(?:^|\\n)RUFF_VERSION=\"(?<currentValue>[0-9.]+)\""], "matchStrings": ["(?:^|\\n)RUFF_VERSION=\"(?<currentValue>[0-9.]+)\""],
"datasourceTemplate": "pypi", "datasourceTemplate": "pypi",
"depNameTemplate": "ruff" "depNameTemplate": "ruff"
@@ -109,7 +130,7 @@
{ {
"customType": "regex", "customType": "regex",
"description": "pip-audit version used by the ci workflow", "description": "pip-audit version used by the ci workflow",
"managerFilePatterns": ["^\\.gitea/workflows/tool-versions\\.env$"], "managerFilePatterns": [".gitea/workflows/tool-versions.env"],
"matchStrings": ["(?:^|\\n)PIP_AUDIT_VERSION=\"(?<currentValue>[0-9.]+)\""], "matchStrings": ["(?:^|\\n)PIP_AUDIT_VERSION=\"(?<currentValue>[0-9.]+)\""],
"datasourceTemplate": "pypi", "datasourceTemplate": "pypi",
"depNameTemplate": "pip-audit" "depNameTemplate": "pip-audit"
@@ -117,7 +138,7 @@
{ {
"customType": "regex", "customType": "regex",
"description": "yamllint version used by the ci workflow", "description": "yamllint version used by the ci workflow",
"managerFilePatterns": ["^\\.gitea/workflows/tool-versions\\.env$"], "managerFilePatterns": [".gitea/workflows/tool-versions.env"],
"matchStrings": ["(?:^|\\n)YAMLLINT_VERSION=\"(?<currentValue>[0-9.]+)\""], "matchStrings": ["(?:^|\\n)YAMLLINT_VERSION=\"(?<currentValue>[0-9.]+)\""],
"datasourceTemplate": "pypi", "datasourceTemplate": "pypi",
"depNameTemplate": "yamllint" "depNameTemplate": "yamllint"
@@ -125,7 +146,7 @@
{ {
"customType": "regex", "customType": "regex",
"description": "hadolint version used by the ci workflow", "description": "hadolint version used by the ci workflow",
"managerFilePatterns": ["^\\.gitea/workflows/tool-versions\\.env$"], "managerFilePatterns": [".gitea/workflows/tool-versions.env"],
"matchStrings": ["(?:^|\\n)HADOLINT_VERSION=\"(?<currentValue>[0-9.]+)\""], "matchStrings": ["(?:^|\\n)HADOLINT_VERSION=\"(?<currentValue>[0-9.]+)\""],
"datasourceTemplate": "github-tags", "datasourceTemplate": "github-tags",
"depNameTemplate": "hadolint/hadolint" "depNameTemplate": "hadolint/hadolint"
@@ -133,7 +154,7 @@
{ {
"customType": "regex", "customType": "regex",
"description": "node version the ci workflow runs npm with", "description": "node version the ci workflow runs npm with",
"managerFilePatterns": ["^\\.gitea/workflows/tool-versions\\.env$"], "managerFilePatterns": [".gitea/workflows/tool-versions.env"],
"matchStrings": ["(?:^|\\n)NODE_VERSION=\"(?<currentValue>[0-9.]+)\""], "matchStrings": ["(?:^|\\n)NODE_VERSION=\"(?<currentValue>[0-9.]+)\""],
"datasourceTemplate": "node", "datasourceTemplate": "node",
"depNameTemplate": "node" "depNameTemplate": "node"
@@ -141,7 +162,7 @@
{ {
"customType": "regex", "customType": "regex",
"description": "stakater/reloader chart version pinned in the deploy workflow", "description": "stakater/reloader chart version pinned in the deploy workflow",
"managerFilePatterns": ["^\\.gitea/workflows/deploy-lib\\.sh$"], "managerFilePatterns": [".gitea/workflows/deploy-lib.sh"],
"matchStrings": ["\\|stakater/reloader\\|reloader\\|(?<currentValue>[0-9.]+)\\|"], "matchStrings": ["\\|stakater/reloader\\|reloader\\|(?<currentValue>[0-9.]+)\\|"],
"datasourceTemplate": "helm", "datasourceTemplate": "helm",
"depNameTemplate": "reloader", "depNameTemplate": "reloader",
@@ -150,7 +171,7 @@
], ],
"packageRules": [ "packageRules": [
{ {
"description": "Automerge digest and patch updates - safe by definition, review adds nothing, keeps the renovate queue and the deploy line short. Specific no-automerge rules below still override this for playwright, helm and majors.", "description": "Automerge ordinary digest and patch updates after successful checks; specific manual-review rules below override this.",
"matchUpdateTypes": ["digest", "patch"], "matchUpdateTypes": ["digest", "patch"],
"automerge": true "automerge": true
}, },
@@ -161,6 +182,12 @@
"groupSlug": "all-minor", "groupSlug": "all-minor",
"automerge": false "automerge": false
}, },
{
"description": "Group ordinary patch updates; the specific groups and manual-review rules below take precedence",
"matchUpdateTypes": ["patch"],
"groupName": "all patch updates",
"groupSlug": "all-patch"
},
{ {
"description": "Keep private homelab images unchanged", "description": "Keep private homelab images unchanged",
"matchDatasources": ["docker"], "matchDatasources": ["docker"],
@@ -185,7 +212,7 @@
"automerge": false "automerge": false
}, },
{ {
"description": "CI runs npm on the node the panel image is built from - the NODE_VERSION pin in tool-versions.env and node:22-alpine in the Dockerfile are the same dependency and move as one", "description": "Keep CI Node runtime updates in a separate, manually reviewed group",
"matchPackageNames": ["node"], "matchPackageNames": ["node"],
"groupName": "node runtime", "groupName": "node runtime",
"groupSlug": "node", "groupSlug": "node",
@@ -194,6 +221,8 @@
{ {
"description": "Helm chart bumps change PVC fields and admission behaviour, keep them reviewable", "description": "Helm chart bumps change PVC fields and admission behaviour, keep them reviewable",
"matchDatasources": ["helm"], "matchDatasources": ["helm"],
"groupName": "Helm chart {{depName}}",
"groupSlug": "helm-{{depName}}",
"automerge": false "automerge": false
}, },
{ {
@@ -202,12 +231,6 @@
"dependencyDashboardApproval": true, "dependencyDashboardApproval": true,
"automerge": false "automerge": false
}, },
{
"description": "Group patch updates from all sources - automerge still applies via the digest/patch rule above (helm/playwright stay manual via their own rules)",
"matchUpdateTypes": ["patch"],
"groupName": "all patch updates",
"groupSlug": "all-patch"
},
{ {
"description": "Python Y-bumps break compat (3.11->3.12->3.13->3.14) - keep the base image out of the shared minor/patch groups, review every bump separately. Placed last so its groupName wins.", "description": "Python Y-bumps break compat (3.11->3.12->3.13->3.14) - keep the base image out of the shared minor/patch groups, review every bump separately. Placed last so its groupName wins.",
"matchDatasources": ["docker"], "matchDatasources": ["docker"],
+2 -2
View File
@@ -12,11 +12,11 @@ services:
- "traefik.enable=true" - "traefik.enable=true"
- "traefik.http.services.searxng.loadbalancer.server.port=8080" - "traefik.http.services.searxng.loadbalancer.server.port=8080"
# Prod Router # Prod Router
- "traefik.http.routers.searxng.rule=Host(`s.forust.xyz` || `search.forust.xyz`)" - "traefik.http.routers.searxng.rule=Host(`s.forust.xyz`) || Host(`search.forust.xyz`)"
- "traefik.http.routers.searxng.entrypoints=websecure" - "traefik.http.routers.searxng.entrypoints=websecure"
- "traefik.http.routers.searxng.tls.certresolver=letsencrypt" - "traefik.http.routers.searxng.tls.certresolver=letsencrypt"
# Local Router # Local Router
- "traefik.http.routers.searxng-local.rule=Host(`s.workstation.internal` || `searxng.workstation.internal`)" - "traefik.http.routers.searxng-local.rule=Host(`s.workstation.internal`) || Host(`searxng.workstation.internal`)"
- "traefik.http.routers.searxng-local.entrypoints=websecure" - "traefik.http.routers.searxng-local.entrypoints=websecure"
- "traefik.http.routers.searxng-local.tls=true" - "traefik.http.routers.searxng-local.tls=true"
# Dev Router # Dev Router
+1 -1
View File
@@ -1,6 +1,6 @@
services: services:
termix: termix:
image: ghcr.io/lukegus/termix:2.9.1 image: ghcr.io/lukegus/termix:2.9.2
container_name: termix container_name: termix
restart: unless-stopped restart: unless-stopped
# ports: # ports:
+1 -1
View File
@@ -31,7 +31,7 @@ spec:
spec: spec:
containers: containers:
- name: termix - name: termix
image: ghcr.io/lukegus/termix:2.9.1 image: ghcr.io/lukegus/termix:2.9.2
envFrom: envFrom:
- configMapRef: - configMapRef:
name: termix-config name: termix-config
+87
View File
@@ -0,0 +1,87 @@
"""Exercise local setup and config rendering without a Docker daemon."""
import os
import shutil
import subprocess
import tempfile
import unittest
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
class NetbirdRuntimeTests(unittest.TestCase):
def setUp(self):
self.temp = tempfile.TemporaryDirectory()
self.addCleanup(self.temp.cleanup)
self.root = Path(self.temp.name)
self.stack = self.root / 'netbird'
self.stack.mkdir()
for name in ('setup.sh', '.env.example', 'config.template.yaml'):
shutil.copy(ROOT / 'netbird' / name, self.stack / name)
binary = self.root / 'bin'
binary.mkdir()
docker = binary / 'docker'
docker.write_text('#!/bin/sh\nprintf "%s\\n" 172.20.0.0/16\n')
docker.chmod(0o755)
self.env = dict(os.environ, PATH=f'{binary}:{os.environ["PATH"]}')
def setup(self):
return subprocess.run( # noqa: S603 - executes the repository script copied into this test's temp dir
['/bin/bash', str(self.stack / 'setup.sh')], env=self.env, capture_output=True, check=False
)
def test_setup_preserves_existing_secrets_and_env(self):
self.assertEqual(self.setup().returncode, 0)
paths = [self.stack / '.env', *sorted((self.stack / 'secrets').iterdir())]
before = [p.read_bytes() for p in paths]
self.assertIn(b'NETBIRD_PROXY_SUBNET=172.20.0.0/16', before[0])
self.assertEqual(self.setup().returncode, 0)
self.assertEqual(before, [p.read_bytes() for p in paths])
for p in paths[1:]:
self.assertEqual(p.stat().st_mode & 0o777, 0o600)
def test_setup_rejects_empty_existing_secret(self):
(self.stack / 'secrets').mkdir()
secret = self.stack / 'secrets/datastore-encryption-key'
secret.touch()
self.assertNotEqual(self.setup().returncode, 0)
self.assertEqual(secret.read_bytes(), b'')
def render(self, subnet):
self.assertEqual(self.setup().returncode, 0)
rendered = self.root / 'run/config.yaml'
script = (ROOT / 'netbird/entrypoint.sh').read_text()
replacements = {
'/opt/netbird/config.template.yaml': str(self.stack / 'config.template.yaml'),
'/run/netbird/config.yaml': str(rendered),
'/run/secrets/relay_auth_secret': str(self.stack / 'secrets/relay-auth-secret'),
'/run/secrets/datastore_encryption_key': str(self.stack / 'secrets/datastore-encryption-key'),
'/go/bin/netbird-server': '/bin/true',
}
for original, local in replacements.items():
script = script.replace(original, local)
result = subprocess.run( # noqa: S603 - repository renderer, with test-local paths
['/bin/sh', '-c', script, 'entrypoint', '--config', str(rendered)],
env=dict(self.env, NETBIRD_DOMAIN='nb.example.com', NETBIRD_PROXY_SUBNET=subnet),
capture_output=True,
check=False,
)
return result, rendered
def test_renderer_replaces_placeholders_and_restricts_file_permissions(self):
result, rendered = self.render('172.20.0.0/16')
self.assertEqual(result.returncode, 0, result.stderr)
self.assertNotIn('__NETBIRD_', rendered.read_text())
self.assertIn('nb.example.com', rendered.read_text())
self.assertEqual(rendered.stat().st_mode & 0o777, 0o600)
def test_renderer_rejects_auto_and_default_route(self):
for subnet in ('auto', '0.0.0.0/0', '999.1.1.1/24'):
with self.subTest(subnet=subnet):
result, _ = self.render(subnet)
self.assertNotEqual(result.returncode, 0)
if __name__ == '__main__':
unittest.main()
+1 -1
View File
@@ -1,7 +1,7 @@
services: services:
server: server:
container_name: vaultwarden-server container_name: vaultwarden-server
image: vaultwarden/server:1.37.3 image: vaultwarden/server:1.37.4
restart: unless-stopped restart: unless-stopped
ports: ports:
- 9993:80 - 9993:80
+1 -1
View File
@@ -31,7 +31,7 @@ spec:
spec: spec:
containers: containers:
- name: vaultwarden - name: vaultwarden
image: vaultwarden/server:1.37.3 image: vaultwarden/server:1.37.4
ports: ports:
- containerPort: 80 - containerPort: 80
envFrom: envFrom:
+1 -1
View File
@@ -38,7 +38,7 @@ spec:
spec: spec:
containers: containers:
- name: xui - name: xui
image: ghcr.io/mhsanaei/3x-ui:v3.8.5 image: ghcr.io/mhsanaei/3x-ui:v3.9.0
envFrom: envFrom:
- configMapRef: - configMapRef:
name: xui-config name: xui-config