From 192fdbfbf634a72dd9e3db1703654e5d22277dfd Mon Sep 17 00:00:00 2001 From: bot-backend Date: Thu, 27 Aug 2026 22:28:52 +0300 Subject: [PATCH] =?UTF-8?q?fix(ops/metrics):=20=D1=82=D0=B5=D0=BC=D0=B0=20?= =?UTF-8?q?=C2=AB=D0=BC=D0=B5=D1=82=D1=80=D0=B8=D0=BA=D0=B8=C2=BB=20=D0=B7?= =?UTF-8?q?=D0=B0=D0=B4=D0=B0=D1=91=D1=82=D1=81=D1=8F=20=D0=B4=D0=B5=D1=84?= =?UTF-8?q?=D0=BE=D0=BB=D1=82=D0=BE=D0=BC,=20=D0=B0=20=D0=BD=D0=B5=20?= =?UTF-8?q?=D1=80=D1=83=D1=87=D0=BD=D1=8B=D0=BC=20=D0=B7=D0=B0=D0=B2=D0=B5?= =?UTF-8?q?=D0=B4=D0=B5=D0=BD=D0=B8=D0=B5=D0=BC=20=D1=81=D0=B5=D0=BA=D1=80?= =?UTF-8?q?=D0=B5=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Разделение тем из #3163 зависело от шага «завести секрет руками». Шаг отказал сразу же: 27.08 два прогона деплоя подряд отработали зелёными, напечатали строку про откат — и тема «метрики» осталась пустой, а весь инфраструктурный поток продолжил идти в тему клиентских инцидентов. Номер темы форума секретом не является: в репозитории уже лежат домены, пути на хостах, имена контейнеров и внешние адреса. Ставим 245 значением по умолчанию прямо в деплое; переменная окружения по-прежнему перекрывает — переезд темы или другой чат решается ею, без правки кода. Откат на METRICS_TELEGRAM_TOPIC_ID убран намеренно и запрещён тестом. Он возвращал ровно то состояние, ради ухода от которого всё затевалось, и сообщал об этом строкой в логе прогона, которую никто не читает. Молчаливое «почти правильно» хуже явной поломки. Прогнано в обе стороны: с переменной — тема из окружения, без неё — 245. backend/tests/ops — 86 passed. --- .forgejo/workflows/deploy-metrics.yml | 38 ++++++++++++---------- backend/tests/ops/test_3078_alert_topic.py | 27 ++++++++------- 2 files changed, 36 insertions(+), 29 deletions(-) diff --git a/.forgejo/workflows/deploy-metrics.yml b/.forgejo/workflows/deploy-metrics.yml index e197618d..7b101edc 100644 --- a/.forgejo/workflows/deploy-metrics.yml +++ b/.forgejo/workflows/deploy-metrics.yml @@ -164,26 +164,28 @@ jobs: # бы вовсе — то есть алертинг исчез бы целиком, а не «ушёл не в # ту тему». # - # Откат обязателен: пока METRICS_TELEGRAM_INFRA_TOPIC_ID не - # прописана на хосте, берём METRICS_TELEGRAM_TOPIC_ID — тогда - # поведение остаётся ровно прежним, а не ломается молча. + # Значение по умолчанию стоит ЗДЕСЬ, а не в секрете. Номер темы + # форума секретом не является: в репозитории уже лежат домены, + # пути на хостах, имена контейнеров и внешние адреса. Зато шаг + # «завести секрет руками» — это отказ, который уже случился: + # 27.08 два прогона подряд молча откатились на тему клиентских + # инцидентов, и тема «метрики» осталась пустой при полностью + # зелёном деплое. + # + # Прежний откат на METRICS_TELEGRAM_TOPIC_ID убран намеренно: он + # давал ровно то состояние, ради ухода от которого всё и + # затевалось — весь инфраструктурный поток в теме клиентских + # инцидентов, — и сообщал об этом строкой в логе, которую никто + # не читает. Молчаливое «почти правильно» хуже явной поломки. + # + # Переменная окружения по-прежнему перекрывает значение: переезд + # темы или другой чат решается ею, без правки кода. + INFRA_TOPIC_ID="${METRICS_TELEGRAM_INFRA_TOPIC_ID:-245}" + METRICS_TELEGRAM_INFRA_TOPIC_LINE=" message_thread_id: ${INFRA_TOPIC_ID}" if [ -n "${METRICS_TELEGRAM_INFRA_TOPIC_ID:-}" ]; then - INFRA_TOPIC_ID="${METRICS_TELEGRAM_INFRA_TOPIC_ID}" - INFRA_TOPIC_IS_FALLBACK=0 + echo "Инфраструктура: тема ${INFRA_TOPIC_ID} из окружения." else - INFRA_TOPIC_ID="${METRICS_TELEGRAM_TOPIC_ID:-}" - INFRA_TOPIC_IS_FALLBACK=1 - fi - if [ -n "${INFRA_TOPIC_ID}" ]; then - METRICS_TELEGRAM_INFRA_TOPIC_LINE=" message_thread_id: ${INFRA_TOPIC_ID}" - if [ "${INFRA_TOPIC_IS_FALLBACK}" = "1" ]; then - echo "Инфраструктура: METRICS_TELEGRAM_INFRA_TOPIC_ID не задана — откат на METRICS_TELEGRAM_TOPIC_ID, топик ${INFRA_TOPIC_ID}." - else - echo "Инфраструктура: адресуются в топик ${INFRA_TOPIC_ID}." - fi - else - METRICS_TELEGRAM_INFRA_TOPIC_LINE="" - echo "Инфраструктура: топик не задан — уйдут в общую тему чата." + echo "Инфраструктура: тема ${INFRA_TOPIC_ID} по умолчанию (METRICS_TELEGRAM_INFRA_TOPIC_ID не задана)." fi if [ -n "${METRICS_TELEGRAM_ONCALL:-}" ]; then diff --git a/backend/tests/ops/test_3078_alert_topic.py b/backend/tests/ops/test_3078_alert_topic.py index 07b4597e..501ebfbb 100644 --- a/backend/tests/ops/test_3078_alert_topic.py +++ b/backend/tests/ops/test_3078_alert_topic.py @@ -133,22 +133,27 @@ def test_deploy_computes_whole_line_and_passes_it_to_envsubst() -> None: ) -def test_infra_topic_falls_back_to_client_topic_when_unset() -> None: - """Без METRICS_TELEGRAM_INFRA_TOPIC_ID — откат на METRICS_TELEGRAM_TOPIC_ID (#3163). +def test_infra_topic_has_working_default_and_never_falls_back_to_client_topic() -> None: + """Тема по умолчанию задана в самом деплое и НЕ откатывается на клиентскую (#3163). - Разделение тем не должно ломать деплой у тех, кто ещё не прописал новую - переменную на хосте: пока её нет, поведение обязано остаться ровно - прежним (топик из METRICS_TELEGRAM_TOPIC_ID), а не откатиться в общую тему - чата или сломать рендер конфига. + Первая половина: без значения по умолчанию разделение тем зависело бы от + ручного шага «завести секрет». Этот шаг уже отказал — 27.08 два прогона + подряд отработали зелёными, а тема «метрики» осталась пустой. + + Вторая половина важнее: откат на METRICS_TELEGRAM_TOPIC_ID запрещён явно. + Он возвращал ровно то состояние, ради ухода от которого всё затевалось — + весь инфраструктурный поток в теме клиентских инцидентов, — и сообщал об + этом строкой в логе прогона, которую никто не читает. """ text = WORKFLOW.read_text(encoding="utf-8") assert re.search( - r'if \[ -n "\$\{METRICS_TELEGRAM_INFRA_TOPIC_ID:-\}" \]; then' - r'[\s\S]*?INFRA_TOPIC_ID="\$\{METRICS_TELEGRAM_INFRA_TOPIC_ID\}"' - r'[\s\S]*?else' - r'[\s\S]*?INFRA_TOPIC_ID="\$\{METRICS_TELEGRAM_TOPIC_ID:-\}"', + r'INFRA_TOPIC_ID="\$\{METRICS_TELEGRAM_INFRA_TOPIC_ID:-\d+\}"', text, - ), "нет отката на METRICS_TELEGRAM_TOPIC_ID при незаданной METRICS_TELEGRAM_INFRA_TOPIC_ID" + ), "у инфраструктурной темы нет значения по умолчанию — разделение зависит от ручного шага" + assert not re.search( + r'INFRA_TOPIC_ID="\$\{METRICS_TELEGRAM_TOPIC_ID', + text, + ), "вернулся откат на тему клиентских инцидентов — это и есть исходный дефект" def test_config_is_validated_before_stack_comes_up() -> None: -- 2.45.3