From 254a52d89c056dfa0baebf19613c917b74ae8bd8 Mon Sep 17 00:00:00 2001 From: bot-backend Date: Thu, 13 Aug 2026 21:35:11 +0500 Subject: [PATCH] =?UTF-8?q?ci:=20=D1=81=D0=B4=D0=B5=D0=BB=D0=B0=D1=82?= =?UTF-8?q?=D1=8C=20=D0=B2=D0=B8=D0=B4=D0=B8=D0=BC=D1=8B=D0=BC=D0=B8=20?= =?UTF-8?q?=D0=B4=D0=B2=D0=B0=20=D0=B1=D0=B5=D0=B7=D0=BC=D0=BE=D0=BB=D0=B2?= =?UTF-8?q?=D0=BD=D1=8B=D1=85=20=D1=88=D0=B0=D0=B3=D0=B0=20=D0=BF=D0=BE?= =?UTF-8?q?=D1=81=D0=BB=D0=B5=20pytest?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit backend-tests трижды покраснел ПОСЛЕ зелёного pytest (4647 passed, покрытие 74.57% ≥ 65), и по логу невозможно понять, в каком из двух `if: always()` шагов это случилось: act_runner не печатает баннеры обычных `run:`-шагов, а оба шага в штатном режиме молчат — один пишет в $GITHUB_STEP_SUMMARY, второй глушит вывод в /dev/null. Зелёный и красный прогоны в этом месте неотличимы построчно. Добавлены маркеры начала/конца обоих шагов. Отдельно: `coverage report` уважает fail_under из pyproject и выходит с кодом 2, а `run:` идёт под `bash -eo pipefail` — то есть шаг-ОТЧЁТ умел ронять сборку. Воспроизведено локально (pytest exit=0, шаг exit=2). Теперь код возврата печатается, а гейт остаётся там, где ему место — в `pytest --cov-fail-under=65`. `|| cov_rc=$?` вместо отдельной строки `cov_rc=$?`: под `set -e` присваивание после упавшей команды не выполнилось бы, и код снова потерялся бы. Refs #2871 --- .forgejo/workflows/ci.yml | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/.forgejo/workflows/ci.yml b/.forgejo/workflows/ci.yml index 53e1d59b..a9cb7fa7 100644 --- a/.forgejo/workflows/ci.yml +++ b/.forgejo/workflows/ci.yml @@ -246,20 +246,34 @@ jobs: # если переменная пустая/файла нет, печатаем в обычный лог (fallback). if: always() run: | + echo "### шаг «Coverage summary» начался" [ -f coverage.xml ] || { echo "coverage.xml отсутствует — пропускаю summary"; exit 0; } - report="$(uv run coverage report --skip-covered --sort=cover | tail -40)" + # NB (#2871): `coverage report` уважает fail_under из pyproject и выходит с + # кодом 2, когда порог не набран, а `run:` идёт под `bash -eo pipefail` — + # то есть падение ЭТОГО шага гасит зелёный pytest и выглядит как «job упал + # неизвестно где». Разделяем вычисление и вывод, чтобы код возврата был виден. + # `|| cov_rc=$?`, а не отдельная строка: под `set -e` присваивание после + # упавшей команды просто не выполнится, и код возврата снова потеряется. + cov_rc=0 + uv run coverage report --skip-covered --sort=cover > /tmp/cov_report.txt || cov_rc=$? + echo "### coverage report вернул код $cov_rc" + report="$(tail -40 /tmp/cov_report.txt)" if [ -n "${GITHUB_STEP_SUMMARY:-}" ]; then { echo '```'; echo "$report"; echo '```'; } >> "$GITHUB_STEP_SUMMARY" else echo "$report" fi + echo "### шаг «Coverage summary» закончился успешно" - name: Снести тестовый Postgres # if: always() — контейнер уходит и когда сьют красный, и когда прогон # отменён concurrency-группой. Иначе на раннере копятся мёртвые контейнеры. if: always() working-directory: . - run: docker rm -f "$CI_PG" >/dev/null 2>&1 || true + run: | + echo "### шаг «Снести тестовый Postgres» начался (CI_PG=${CI_PG:-<пусто>})" + docker rm -f "$CI_PG" >/dev/null 2>&1 || true + echo "### шаг «Снести тестовый Postgres» закончился успешно" frontend-tests: runs-on: ubuntu-latest -- 2.45.3