Быстрый путь «правка только прокси» наконец включается: считаем изменённые файлы сами (#3448) #3465
Merged
bot-backend
merged 4 commits from 2026-09-12 11:43:39 +00:00
fix/3448-caddy-only-detection into main
4 commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
| 05959464ae |
ci.yml: запускать backend-tests на правках метрик (#3467/#3475)
All checks were successful
CI Trade-In / changes (pull_request) Successful in 14s
CI / changes (pull_request) Successful in 19s
CI Trade-In / backend-tests (pull_request) Has been skipped
CI Trade-In / browser-tests (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / frontend-tests (pull_request) Successful in 1m36s
CI / openapi-codegen-check (pull_request) Successful in 2m48s
CI / backend-tests (pull_request) Successful in 18m27s
Гейт backend/tests/ops/test_3467_prometheus_reload.py (едет в PR #3475) читает .forgejo/workflows/deploy-metrics.yml и docker-compose.metrics.yml. Пока этих путей нет в фильтре `backend`, правка, трогающая ТОЛЬКО deploy-metrics.yml — например дописывающая `|| true` к шагу перезагрузки Prometheus, — даёт backend=false: джоба backend-tests пропускается, гейт не исполняется, регрессия уезжает в main зелёной. Это ровно тот класс, который осуждает комментарий двумя абзацами выше в этом же файле: гейт, который не запускается на той самой правке, от которой стережёт, — украшение. Список правится одной веткой намеренно: параллельный PR #3475 его не трогает, иначе две ветки подрались бы за один фильтр. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
|||
| 2e928c715b |
Гейт #3448: закрыть зелёные мутации, добавить признак непустоты, запускать на ci-tradein.yml
All checks were successful
CI Trade-In / changes (pull_request) Successful in 13s
CI Trade-In / backend-tests (pull_request) Has been skipped
CI / changes (pull_request) Successful in 16s
CI Trade-In / browser-tests (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / frontend-tests (pull_request) Successful in 1m42s
CI / openapi-codegen-check (pull_request) Successful in 2m37s
CI / backend-tests (pull_request) Successful in 19m21s
Мутационный прогон нашёл пять зелёных мутаций — то есть мест, где логику можно сломать, а гейт этого не заметит. Закрыты фикстурами, каждая краснеет ровно на своей мутации: * CADDY_RE → `^(Caddyfile|caddy)`: тогда `caddy-extra/**` и `Caddyfile.bak` дают caddy_only=true — тихий пропуск полного деплоя, против которого весь PR; * снятие проверки «файлов больше нуля»: пустой дифф формально удовлетворяет «ни один файл не лежит вне caddy» и отключает сборку; * выпадение `data/sql/**` из backend: миграции едут в backend-образе; * подмена базы на `HEAD^..HEAD`: на ОДНОМ мерж-коммите даёт верный ответ и выглядит рабочей, а на push'е из нескольких коммитов теряет первый — фикстура «бэкенд-коммит + caddy-коммит» это ловит; * потеря `core.quotePath=false`: кириллический путь под backend/ выпадает из классификации. Плюс прод-сторож из deploy-caddy: его кусок (от PROD_HEAD до `git reset --hard`) извлекается из ssh-скрипта и ИСПОЛНЯЕТСЯ на временном репозитории, где прод-дерево отстаёт от origin/main — отдельно законный случай (отстал только конфиг прокси) и отказной (отстал бэкенд). Проверяется и порядок: сторож обязан стоять ДО `git reset`. Команда ищется регуляркой по началу строки, а не подстрокой: `git reset --hard` упоминается выше в комментариях, и поиск по тексту находил объяснение вместо кода. Признак непустоты у проверки исключающих `!`-шаблонов: раньше она бы прошла при нулевом охвате (переименуют действие, заведут .yaml) — теперь отдельно утверждается, что хотя бы один шаг paths-filter найден, как это сделано в ci.yml для shell-гейта. Маска расширена до *.y*ml, параметризация — по найденным шагам. ci.yml: в фильтр `backend` добавлен `.forgejo/workflows/ci-tradein.yml` — там тоже живёт paths-filter, и без этой строки правка с `!`-шаблоном не запустила бы backend-tests, то есть гейт не побежал бы ровно на той правке, от которой стережёт. Докстринг фикстуры с мержем переписан: он утверждал, что «дифф последнего коммита» на мерж-коммите даёт пустой список (это верно для `git show`, а не для `git diff HEAD^ HEAD`) — то есть обещал защиту, которой у этой фикстуры нет. Теперь там сказано, что подмену базы стережёт отдельная проверка. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
|||
| 9a8aaa2d2d |
deploy-caddy: сторож отставания прода, общий лок и квотирование путей (#3448)
Оживший быстрый путь снимает гард свежести :latest. Пока caddy_only был мёртв, любой push шёл полным деплоем, и гард #2950 прикрывал прод по умолчанию. Теперь при caddy_only=true джоба `deploy` пропускается целиком — вместе с гардом. Сценарий отказа. Push A правит бэкенд, билды ~6 мин, `deploy` в очереди. Через 2 мин push B правит только caddy/. На Forgejo 10.0.3 ещё не стартовавшая `deploy` предыдущего прогона отменяется ДАЖЕ при cancel-in-progress: false (наблюдение 21.08.2026 10:35:13, шапка scripts/check-latest-image-revision.sh; workflow-level concurrency там не исполняется, см. deploy.yml). Дифф A..B — один caddy-файл, быстрый путь включается, `compose pull` + `up -d` не делает никто: прод крутит старый образ, голова main зелёная, сигнала нет. Сторож в ssh-скрипте deploy-caddy: если прод отстаёт от origin/main не только по Caddyfile/caddy/**, быстрый путь запрещён, шаг падает и называет файлы. Стоит ДО `git reset --hard` намеренно — при отказе прод-HEAD остаётся честным для следующего прогона. У Trade-In для того же заведён отдельный маркер (/opt/gendesign/.tradein-deployed-sha, deploy-tradein.yml), у ПТИЦЫ маркера нет, и `git reset` делает прод-HEAD его эквивалентом. ЧЕГО СТОРОЖ НЕ ЛОВИТ: `deploy`, упавшую ПОСЛЕ `git reset --hard` (например на миграции). Тогда прод-HEAD уже равен новому коммиту, а контейнеры старые — это остаётся за настоящим маркером «что задеплоено». Тот же лок, что и у полного деплоя. deploy-caddy делает `git reset --hard` в /opt/gendesign, то есть правит прод-дерево — ровно то, что job `deploy` сериализует через flock /var/lock/gendesign-docker-deploy.lock. Пока путь был мёртв, сталкиваться было нечему; теперь это первая джоба, трогающая прод-дерево в обход сериализации. Квотирование путей. `git diff --name-only` и `git ls-files` при core.quotePath (умолчание true) отдают не-ASCII пути закавыченными с \NNN-экранированием — `^backend/` такую строку не матчит, и файл backend/<кириллица>.py дал бы backend=false. Старый paths-filter брал `--name-status -z`, где квотирования нет: это единственное место, где переход на свой diff менял поведение. В дереве такие пути уже живут (docs/Бизнес-план…). Добавлен `-c core.quotePath=false` в обе команды и в сторож выше. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
|||
| 091137a0c5 |
Быстрый путь caddy_only: считаем изменённые файлы сами, без исключающих шаблонов (#3448)
All checks were successful
CI Trade-In / changes (pull_request) Successful in 9s
CI / changes (pull_request) Successful in 13s
CI Trade-In / backend-tests (pull_request) Has been skipped
CI Trade-In / browser-tests (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Successful in 2m34s
CI / backend-tests (pull_request) Successful in 17m41s
Быстрый путь «правка ТОЛЬКО прокси» (#2916) не отработал ни разу: мерж |