// Шаблон конфига Renovate для РЕПЫ ПРИЛОЖЕНИЯ (не для infra/komodo). // // Кладётся в корень репы проекта под именем renovate.jsonc. Файл одинаков // для всех реп: ничего репо-специфичного здесь нет намеренно, отличия // (ветки, область) живут в projects/personal/renovate/renovate-config.js. // // Схема целиком — docs/image-updates.md, раздел 7.1. // // ЧТО ЗДЕСЬ ПРОИСХОДИТ, В ДВУХ СТРОЧКАХ: // образы из реестра -> выдержка трое суток -> автомёрдж -> вебхук проекта // -> pre_deploy делает git pull --ff-only -> прод; // зависимости кода -> один сгруппированный PR, автомёрджа НЕТ, ждёт человека. // // Про локально собираемые образы (`image: msos/backend` рядом с `build:`) // думать не надо: менеджер docker-compose их не извлекает вообще. Проверено // прогоном `--platform=local --dry-run=lookup` на минимальном примере — // в выдаче остаётся только postgres, `msos/backend` даже не ищется в реестре. { "$schema": "https://docs.renovatebot.com/renovate-schema.json", "extends": ["config:recommended", ":dependencyDashboard"], "timezone": "Europe/Warsaw", // ОБЛАСТЬ. Прогон вхолостую 10.09.2026 показал, что без этих двух ключей // Renovate в прикладной репе лезет сильно дальше, чем задумано. // // enabledManagers: без списка их подхватывается полтора десятка. На // cars-system это дало `html` (16 файлов вёрстки в _legacy), `pyenv` // (.python-version — это смена рантайма, а не зависимости), плюс `poetry` // и `pixi`, которые лезут в тот же backend/pyproject.toml, что и pep621. "enabledManagers": [ "docker-compose", "dockerfile", "npm", "bun", "pep621", "pip_requirements", "gomod", "github-actions" ], // ignorePaths: в репах приложений рядом с рабочим compose лежит ещё и // caddy/docker-compose.yml. Это ГРАНИЦА — `ghcr.io/caddybuilds/caddy-cloudflare`, // а граница из схемы исключена намеренно, ей нужен не лаг, а хелсчек с // автооткатом (docs/image-updates.md §6). В infra/komodo это делает // includePaths, здесь — вот эта строчка. Заодно выкидываем мёртвый // _legacy и compose для дев-воркtree, который никто не разворачивает. "ignorePaths": [ "**/caddy/**", "_legacy/**", "**/docker-compose.worktree.yml" ], // Дайджест: тег в compose остаётся для читаемости, разворачивается всегда // один и тот же образ. "pinDigests": true, "minimumReleaseAge": "3 days", "minimumReleaseAgeBehaviour": "timestamp-required", "internalChecksFilter": "strict", "labels": ["renovate"], "rebaseWhen": "behind-base-branch", "platformAutomerge": true, "automergeStrategy": "squash", // Потолки — как в infra/komodo и по той же арифметике: PR с меткой wait-3d // живёт трое суток, значит открытых копится «создано за день × 3». // Осторожно: сюда же попадают PR с зависимостями кода, а их никто не // мёржит автоматически — они занимают место в prConcurrentLimit и могут // вытеснить docker-обновления. Именно поэтому зависимости кода // сгруппированы в ОДИН PR, а их мажоры не создают PR вовсе. "prHourlyLimit": 8, "prConcurrentLimit": 25, "packageRules": [ { "description": "Docker: патчи, миноры и дайджесты — молча в деплой-ветку.", "matchDatasources": ["docker"], "matchUpdateTypes": ["patch", "minor", "digest", "pinDigest"], "automerge": true }, { "description": "Docker: первичный пиннинг дайджеста — ОТДЕЛЬНОЙ веткой. `groupName: null` здесь обязателен: у Renovate есть встроенная группа «Pin dependencies», и без этой строчки docker-пины уезжают в один PR вместе с npm-пинами. Группа берёт самый строгий automerge из своих участников, то есть докер молча переставал мёржиться сам — поймано прогоном вхолостую на placebot, где в pin-dependencies лежали python и caddy-cloudflare вперемешку с фронтовыми пакетами.", "matchDatasources": ["docker"], "matchUpdateTypes": ["pin", "pinDigest"], "groupName": null, "automerge": true }, { "description": "Docker: мажор руками. Аппрув в дашборде, PR не создаётся.", "matchDatasources": ["docker"], "matchUpdateTypes": ["major"], "automerge": false, "dependencyDashboardApproval": true }, { "description": "Базы: МАЖОР руками, отдельным предохранителем. postgres 17 -> 18 не стартует на старом data dir без pg_upgrade, и у этих стеков pre_deploy делает `docker compose up -d postgres && make migrate` — то есть автомёрдж мажора мигрировал бы уже пересозданную пустую базу. mongo и mariadb здесь по той же причине, timescaledb — расширение поверх postgres, у него ещё и своя процедура апгрейда.", "matchPackageNames": [ "postgres", "docker.io/library/postgres", "postgis/postgis", "redis", "docker.io/library/redis", "mongo", "docker.io/library/mongo", "mariadb", "docker.io/library/mariadb", "timescale/timescaledb" ], "matchUpdateTypes": ["major"], "automerge": false, "dependencyDashboardApproval": true }, { "description": "Реестры без даты релиза: minimumReleaseAge на них неисполним (реестр не отдаёт timestamp). PR создаётся сразу, выдержка живёт на мёрдже — метка wait-3d и merge-aged-prs.py. См. docs/image-updates.md §2.2.", "matchDatasources": ["docker"], "matchPackageNames": ["ghcr.io/**", "lscr.io/**", "quay.io/**", "public.ecr.aws/**", "docker.elastic.co/**"], "minimumReleaseAgeBehaviour": "timestamp-optional", "automerge": false, "addLabels": ["wait-3d"] }, { "description": "Теги без версии (latest, stable, s6, ...) — то же самое: возраста у них нет даже на Docker Hub.", "matchDatasources": ["docker"], "matchCurrentValue": "/^(latest|stable|main|edge|main-stable|latest-full|s6|dind)$/", "minimumReleaseAgeBehaviour": "timestamp-optional", "automerge": false, "addLabels": ["wait-3d"] }, { "description": "ЗАВИСИМОСТИ КОДА (npm, pip, go.mod, экшены и прочее не-docker): PR собираем, автомёрдж НЕ включаем — решение Бобра от 10.09.2026, первый заход без него, чтобы сначала посмотреть на объём. Сгруппированы в один PR намеренно: иначе они по одному займут весь prConcurrentLimit и вытеснят docker-обновления, а те как раз едут сами.", "matchDatasources": ["!docker"], "matchUpdateTypes": ["pin", "patch", "minor", "digest", "pinDigest"], "groupName": "зависимости кода", "automerge": false, "addLabels": ["deps-code"] }, { "description": "Зависимости кода, МАЖОР: PR не создаём, показываем списком в дашборде. Иначе первый же прогон на большой репе выкатит десяток PR с ломающими изменениями, которые никто не смёржит. Захотим PR — убрать эту строчку с dependencyDashboardApproval.", "matchDatasources": ["!docker"], "matchUpdateTypes": ["major"], "automerge": false, "dependencyDashboardApproval": true } ] }